
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@agent-pattern-labs/iso-harness
Advanced tools
One config for every coding agent — Cursor, Claude Code, Codex, OpenCode, Pi.
One config for every coding agent — Cursor, Claude Code, Codex, OpenCode, Pi.
Keep your instructions, subagents, commands, and MCP servers in a single
iso/ directory. iso-harness build transpiles that source to the
file layout each harness actually reads.
iso/ → CLAUDE.md (Claude Code)
├── instructions.md .claude/agents/*.md
├── instructions.agents.md* .claude/commands/*.md
├── instructions.claude.md* .mcp.json
├── instructions.cursor.md* → AGENTS.md (Codex + OpenCode + Pi)
├── instructions.opencode.md* .codex/config.toml
├── mcp.json .opencode/agents/*.md
│ .opencode/skills/*.md
│ .opencode/instructions.md* (OpenCode-only addendum)
│ .opencode/opencode-model-fallback.json (optional; from `opencodeModelFallback` in iso/config.json)
│ opencode.json
│ → .cursor/rules/*.mdc (Cursor)
│ .cursor/mcp.json
│ → .pi/skills/*/SKILL.md (Pi)
│ .pi/prompts/*.md
├── agents/ .mcp.json
│ └── researcher.md
└── commands/
└── review.md
Files marked with * are optional.
npm install
node bin/iso-harness.mjs build --source examples/minimal/iso --out /tmp/iso-demo
Or once installed as a CLI:
iso-harness build # reads ./iso, writes to ./
iso-harness build --target claude,cursor # only two targets
iso-harness build --source path/to/iso --out path/to/project
iso-harness build --dry-run # print planned writes, no disk changes
iso-harness build --watch # rebuild on every change under iso/
--dry-run validates and renders the full output plan, but prints what
would be written instead of touching disk.--watch keeps a filesystem watcher on the source directory and reruns the
build after changes. Combine it with --target when you only care about one
harness while iterating.iso/
├── instructions.md # root prompt → CLAUDE.md / AGENTS.md / .cursor/rules/main.mdc
├── instructions.agents.md # optional addendum for shared AGENTS.md targets
├── instructions.claude.md # optional Claude-only root addendum
├── instructions.cursor.md # optional Cursor-only root addendum
├── instructions.opencode.md # optional OpenCode-only addendum, loaded via opencode.json.instructions
├── config.json # optional — targets.* merges + opencodeModelFallback file emit
├── mcp.json # shared MCP server definitions
├── agents/ # subagents
│ └── <slug>.md # YAML frontmatter + body
└── commands/ # slash commands / skills
└── <slug>.md # YAML frontmatter + body
mcp.jsonA harness-neutral schema. Each server has command, optional args, optional
env. The emitter translates to the shape each harness expects (e.g.
OpenCode wants type: "local" and command as an array).
{
"servers": {
"example": {
"command": "npx",
"args": ["-y", "@example/mcp"],
"env": { "EXAMPLE_MODE": "demo" }
}
}
}
By design, mcp.json has no per-harness override mechanism. The
same MCP server should behave the same way no matter which harness
launches it — if it doesn't, that's an MCP/config issue to fix at the
server level, not something the shared config should paper over.
---
name: researcher
description: Researches technical topics.
model: sonnet
tools: [Read, Grep, WebFetch]
targets:
cursor: skip # don't emit for Cursor
codex: skip
opencode: # per-target overrides pass through verbatim
temperature: 0.2
fallback_models: [foo, bar]
---
Agent prompt body goes here.
---
name: review
description: Review the current git diff.
args: "[scope]" # argument hint
targets:
cursor: skip
---
Slash-command body goes here.
| Harness | Instructions | Agents | Commands | MCP |
|---|---|---|---|---|
| Claude Code | CLAUDE.md | .claude/agents/*.md | .claude/commands/*.md | .mcp.json |
| Cursor | .cursor/rules/main.mdc | .cursor/rules/agent-*.mdc | (no native form) | .cursor/mcp.json |
| Codex | AGENTS.md | (no native form) | (no native form) | .codex/config.toml |
| OpenCode | AGENTS.md | .opencode/agents/*.md | .opencode/skills/*.md | opencode.json |
| Pi | AGENTS.md | .pi/skills/*/SKILL.md | .pi/prompts/*.md | (extension/package only) |
Successful builds record owned outputs in .iso-harness/manifest.json.
Subsequent builds remove unchanged outputs that are no longer present in the
source and reconcile owned MCP/config sections while preserving unrelated user
settings. Modified stale files are preserved with a warning, and an existing
unowned generated-file path is refused instead of overwritten.
The abstraction is only as good as its lowest common denominator. Four explicit hatches keep harness-specific features possible:
targets: (agents & commands).
Harness-specific fields under targets.<name> are mapped or passed
through where that target supports them. Use this for OpenCode
temperature / fallback_models, Claude Code allowed-tools, Pi
skill metadata, etc.targets.<name>: skip omits the item from a specific target —
useful when a subagent only makes sense in harnesses that support
subagents.iso/config.json with targets.<name>: { … } for top-level
harness config (not per-item). Keys under targets.opencode are
merged into the generated opencode.json — use this for OpenCode's
top-level instructions: [...] array, for example. Keys under
targets.pi are merged into .pi/settings.json.iso/config.json top-level opencodeModelFallback — JSON object
written verbatim to .opencode/opencode-model-fallback.json for the
@agent-pattern-labs/opencode-model-fallback
plugin (retryable_error_patterns, global fallback_models, etc.).
OpenCode-only; other harnesses ignore it.instructions.md is still the shared base prompt. Optional sibling files let
you add harness-specific root guidance without forking the whole source:
instructions.agents.md appends only to the shared AGENTS.md output used by Codex, OpenCode, and Pi.instructions.claude.md appends only to CLAUDE.md.instructions.cursor.md appends only to .cursor/rules/main.mdc.instructions.opencode.md is emitted to .opencode/instructions.md and automatically added to opencode.json.instructions.This is especially useful when OpenCode needs extra orchestration guidance
that should not leak into the shared AGENTS.md file that Codex and Pi also read.
// iso/config.json
{
"targets": {
"opencode": {
"instructions": ["templates/states.yml"]
},
"pi": {
"prompts": ["prompts"],
"enableSkillCommands": true
}
},
"opencodeModelFallback": {
"cooldown_seconds": 60,
"retryable_error_patterns": ["(?i)venice.*insufficient"],
"fallback_models": ["openrouter/openai/gpt-oss-120b:free"]
}
}
Per-agent OpenCode fallback_models still belong in agent frontmatter
under targets.opencode. Use opencodeModelFallback only for the
global plugin file OpenCode loads from .opencode/.
@agent-pattern-labs/iso-routeWhen @agent-pattern-labs/iso-route
writes its resolved role map to <out>/.claude/iso-route.resolved.json
(normally by running iso-route build into the same output directory
before iso-harness build), iso-harness picks it up automatically and
stamps model: onto each Claude subagent frontmatter.
Resolution order per subagent, highest to lowest:
targets.claude.model from the agent's frontmatter.model: from the agent's frontmatter.roles[agent.role ?? agent.slug].model from the resolved map.model: field.So an author can (a) hard-pin a model in the source file, (b) let iso-route drive it from policy, or (c) leave it to Claude Code's session default — without editing the agent body.
Non-Anthropic roles in the resolved map are skipped (Claude Code subagents can only run Anthropic models) and logged on stderr. Missing roles are silent — not every agent needs a role entry.
For Pi, iso-route owns .pi/settings.json model defaults. If
iso/config.json also contains targets.pi, iso-harness merges those
project settings into the existing file instead of replacing model
settings.
The contract is file-based on purpose: iso-harness and iso-route publish and version independently, so an on-disk JSON file is more robust than a TypeScript import across the two.
Releases are cut via a GitHub Release, which triggers
.github/workflows/release.yml to publish @agent-pattern-labs/iso-harness to npm
with provenance.
Prerequisites (one-time):
NPM_TOKEN — an npm automation token with publish
rights on the @agent-pattern-labs scope. Set at
https://github.com/Agent-Pattern-Labs/iso-harness/settings/secrets/actions.@agent-pattern-labs must exist and the token must have access.Cutting a release:
# 1. Bump version, commit, push. CI (Quality checks) must pass on the
# pushed commit — the release workflow refuses to publish otherwise.
npm version patch # or minor/major — bumps package.json + tags
git push && git push --tags
# 2. Create the GitHub Release off the tag. This fires release.yml.
gh release create "v$(node -p 'require(\"./package.json\").version')" \
--generate-notes
The release workflow will:
package.json version matches the tag via
scripts/release/check-source.mjs.npm publish --provenance --access public.If the publish step fails (e.g. token, 2FA, name conflict), fix the cause, delete the GitHub release + tag, and re-cut — do not amend.
v0.1 — instructions, agents, commands, MCP. Hooks, permissions, and per-harness-only features are out of scope for v1.
FAQs
One config for every coding agent — Cursor, Claude Code, Codex, OpenCode, Pi.
The npm package @agent-pattern-labs/iso-harness receives a total of 0 weekly downloads. As such, @agent-pattern-labs/iso-harness popularity was classified as not popular.
We found that @agent-pattern-labs/iso-harness demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.