multi-harness 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebSearch",
5
+ "WebFetch(domain:github.com)",
6
+ "WebFetch(domain:docs.claude.com)",
7
+ "WebFetch(domain:docs.github.com)",
8
+ "WebFetch(domain:code.visualstudio.com)",
9
+ "WebFetch(domain:opencode.ai)",
10
+ "WebFetch(domain:antigravity.google)",
11
+ "WebFetch(domain:docs.google.com)",
12
+ "WebFetch(domain:docs.anthropic.com)",
13
+ "WebFetch(domain:developer.cursor.so)",
14
+ "WebFetch(domain:cursor.com)",
15
+ "WebFetch(domain:www.jetbrains.com)",
16
+ "WebFetch(domain:codeium.com)",
17
+ "WebFetch(domain:windsurf.com)",
18
+ "WebFetch(domain:docs.openai.com)",
19
+ "WebFetch(domain:github.blog)",
20
+ "WebFetch(domain:ai.google.dev)",
21
+ "WebFetch(domain:developers.google.com)",
22
+ "WebFetch(domain:copilot.github.com)",
23
+ "WebFetch(domain:developer.chrome.com)",
24
+ "WebFetch(domain:developers.openai.com)",
25
+ "Bash(.venv/bin/mh --help)",
26
+ "Bash(.venv/bin/mh init *)",
27
+ "Bash(.venv/bin/mh add *)",
28
+ "Bash(.venv/bin/mh remove *)",
29
+ "Bash(.venv/bin/mh status *)"
30
+ ]
31
+ }
32
+ }
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+
4
+ .pytest_cache/
5
+ .venv/
6
+ .idea/
7
+ .env
8
+ dist/
9
+ *.egg-info/
@@ -0,0 +1,179 @@
1
+ # multi-harness — project reference
2
+
3
+ ## What this is
4
+
5
+ `mh` is a Python CLI that lets a single project share skills, subagents, and project
6
+ instructions across multiple coding agents without duplication. It creates a canonical
7
+ `.harness/` directory and materializes per-agent symlinks so every agent sees its
8
+ expected paths.
9
+
10
+ Console script: `mh` (installed via `pip install -e .`)
11
+ Package: `multi_harness` — `src/` layout, `pyproject.toml` + hatchling.
12
+
13
+ ---
14
+
15
+ ## Architecture
16
+
17
+ ```
18
+ src/multi_harness/
19
+ ├── cli.py Typer app (group mode via @app.callback()).
20
+ │ Entry point: mh init, future: mh add/remove/status/sync
21
+ ├── harness.py Core logic: detect_configured_agents(), init().
22
+ │ Owns the HARNESS_DIR / AGENTS_MD path constants.
23
+ ├── symlinks.py ensure_symlink(link, target) — relative, idempotent, never
24
+ │ overwrites real files. Returns "created"/"ok"/"replaced".
25
+ └── agents/
26
+ ├── spec.py AgentSpec dataclass (frozen). Fields: name, display_name,
27
+ │ instructions_path (None if native AGENTS.md reader),
28
+ │ skills_path, subagents_path, detection_paths.
29
+ ├── __init__.py AGENT_REGISTRY: dict[str, AgentSpec] — add a new file here
30
+ │ to support a new agent.
31
+ ├── claude.py Claude Code
32
+ ├── codex.py OpenAI Codex CLI
33
+ ├── opencode.py OpenCode
34
+ ├── copilot.py GitHub Copilot
35
+ └── antigravity.py Google Antigravity
36
+ ```
37
+
38
+ Tests live in `tests/test_init.py`. Run with `.venv/bin/pytest`.
39
+
40
+ ---
41
+
42
+ ## Canonical layout produced by `mh init`
43
+
44
+ ```
45
+ AGENTS.md canonical project instructions (real file)
46
+ .harness/
47
+ skills/ real dir — shared skills
48
+ agents/ real dir — shared subagents
49
+ CLAUDE.md -> AGENTS.md
50
+ .claude/
51
+ skills -> ../.harness/skills
52
+ agents -> ../.harness/agents
53
+ settings.json (untouched — agent-specific)
54
+ .codex/
55
+ skills -> ../.harness/skills
56
+ agents -> ../.harness/agents
57
+ .opencode/
58
+ skills -> ../.harness/skills
59
+ agent -> ../.harness/agents (NB: singular)
60
+ .github/
61
+ copilot-instructions.md -> ../AGENTS.md
62
+ skills -> ../.harness/skills
63
+ agents -> ../.harness/agents
64
+ .agents/
65
+ skills -> ../.harness/skills
66
+ .subagents -> .harness/agents (Antigravity — root-level)
67
+ ```
68
+
69
+ All symlinks are **relative** so the tree is portable across machines and paths.
70
+
71
+ ---
72
+
73
+ ## Per-agent path reference (as of 2026)
74
+
75
+ | Agent | instructions_path | skills_path | subagents_path | detection_paths |
76
+ |-------|-------------------|-------------|----------------|-----------------|
77
+ | claude | `CLAUDE.md` | `.claude/skills` | `.claude/agents` | `CLAUDE.md`, `.claude` |
78
+ | codex | *native AGENTS.md* | `.codex/skills` | `.codex/agents` | `.codex` |
79
+ | opencode | *native AGENTS.md* | `.opencode/skills` | `.opencode/agent` ⚠️ | `.opencode` |
80
+ | copilot | `.github/copilot-instructions.md` | `.github/skills` | `.github/agents` | `.github/copilot-instructions.md` |
81
+ | antigravity | *native AGENTS.md* | `.agents/skills` | `.subagents` ⚠️ | `.agents`, `.subagents` |
82
+
83
+ ⚠️ opencode uses singular `agent/` (not `agents/`).
84
+ ⚠️ Antigravity's subagent path `.subagents/` is root-level, inferred from docs as of Jun 2026 — may need revision.
85
+
86
+ **Adding a new agent:** create `src/multi_harness/agents/<name>.py` with a `SPEC`
87
+ `AgentSpec` instance, then add it to `AGENT_REGISTRY` in `agents/__init__.py`.
88
+
89
+ ---
90
+
91
+ ## Key design decisions
92
+
93
+ **Detection skips symlinks.** `detect_configured_agents()` only fires when
94
+ `.harness/` does NOT yet exist. On `--force` re-init, detection is skipped entirely
95
+ — we never mistake our own symlinks for a natively-configured agent.
96
+
97
+ **`AGENTS.md` is not a detection signal.** Three agents (codex, opencode, antigravity)
98
+ natively read `AGENTS.md`, so its presence is ambiguous. Detection looks only at
99
+ agent-specific dirs/files (`.codex/`, `.opencode/`, `.github/copilot-instructions.md`,
100
+ `.agents/`, `.subagents/`, `CLAUDE.md`, `.claude/`).
101
+
102
+ **`instructions_path=None` means the agent is an AGENTS.md native.** No instruction
103
+ symlink is created for codex/opencode/antigravity — they already find the canonical
104
+ file. Only `CLAUDE.md` and `.github/copilot-instructions.md` need symlinks.
105
+
106
+ **`ensure_symlink` never deletes user data.** If the link target already exists as a
107
+ real file or directory, it raises `HarnessError` and the whole `init()` call aborts.
108
+ Migration happens before symlink creation, so migrated dirs are real dirs in `.harness/`
109
+ by the time symlinks are created.
110
+
111
+ **Migration is one-shot.** When exactly one agent is detected, its files are moved into
112
+ `.harness/` and symlinks replace them. There is no "dry-run" or partial migration.
113
+
114
+ ---
115
+
116
+ ## Upcoming commands (planned)
117
+
118
+ All four commands will depend on a `.harness/config.toml` that records which agents are
119
+ registered for the project. `mh init` will write this file; subsequent commands read it.
120
+
121
+ ### `mh add <agent> [--agents ...]`
122
+ Register one or more new agents to an existing harness: validate that `.harness/` exists,
123
+ create the symlinks for the new agent(s), update config.toml.
124
+
125
+ ### `mh remove <agent> [--agents ...]`
126
+ Remove an agent's symlinks (unlink instructions, skills, subagents paths) without deleting
127
+ any `.harness/` content. Update config.toml.
128
+
129
+ ### `mh status`
130
+ Read config.toml to know which agents are registered, then inspect each symlink:
131
+ - `ok` — symlink exists and points to the right place
132
+ - `missing` — symlink is absent (agent was added manually after init?)
133
+ - `broken` — symlink target doesn't resolve
134
+ - `detached` — real file/dir where a symlink should be
135
+ Report per-agent, per-link.
136
+
137
+ ### `mh sync [--agents ...]`
138
+ Re-create any missing or broken symlinks for registered agents (like `--force` but
139
+ restricted to links that actually need repair). Reads config.toml, calls `ensure_symlink`
140
+ for each link, skips those that are already `"ok"`.
141
+
142
+ ---
143
+
144
+ ## config.toml schema (planned)
145
+
146
+ File: `.harness/config.toml`
147
+
148
+ ```toml
149
+ [harness]
150
+ version = 1
151
+ agents = ["claude", "codex", "opencode", "copilot", "antigravity"]
152
+ ```
153
+
154
+ The `agents` list is the source of truth for which agents are registered. Commands that
155
+ need it (`status`, `sync`, `add`, `remove`) read it; `init` writes it.
156
+
157
+ ---
158
+
159
+ ## Open questions / future considerations
160
+
161
+ - **Antigravity subagent path:** documented as `.subagents/` (root-level). Confirm when
162
+ official Antigravity docs clarify the subagents directory convention.
163
+ - **config.toml location:** `.harness/config.toml` keeps all harness state in one place;
164
+ an alternative is `multi-harness.toml` at the repo root (more visible).
165
+ - **Skill/agent file format validation:** should `mh` inspect SKILL.md frontmatter (name,
166
+ description fields) for correctness? Deferred for now.
167
+ - **Per-agent instruction overlays** (`.harness/instructions/<agent>.md`) are explicitly
168
+ out of scope for now — one shared AGENTS.md is the intent.
169
+
170
+ ---
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
176
+ .venv/bin/pytest # 13 tests, all scenarios
177
+ .venv/bin/mh --help
178
+ .venv/bin/mh init --help
179
+ ```
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: multi-harness
3
+ Version: 0.1.0
4
+ Summary: Manage projects that target multiple coding agents from a single shared harness.
5
+ Author-email: jslarraz <jslarraz@gmail.com>
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: typer>=0.12
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=8; extra == 'dev'
11
+ Description-Content-Type: text/markdown
12
+
13
+ # multi-harness 🔗
14
+
15
+ > One project. Many coding agents. Zero duplication.
16
+
17
+ `mh` is a CLI that keeps your skills, subagents, and project instructions in a single
18
+ canonical `.harness/` directory and materialises per-agent symlinks so every agent sees
19
+ the paths it expects — no copy-paste, no drift.
20
+
21
+ **Supported agents:** Claude Code · OpenAI Codex CLI · OpenCode · GitHub Copilot · Google Antigravity
22
+
23
+ ---
24
+
25
+ ## ✨ Why multi-harness?
26
+
27
+ Each coding agent looks for instructions, skills, and subagents in different places:
28
+ `CLAUDE.md`, `.github/copilot-instructions.md`, `AGENTS.md`, `.claude/skills/`, `.codex/skills/` …
29
+
30
+ Without `mh` you either duplicate these files across every agent-specific location or
31
+ keep them in sync by hand. `mh` solves this by:
32
+
33
+ 1. Creating one real `.harness/` directory with the canonical files.
34
+ 2. Writing relative symlinks everywhere each agent expects to look.
35
+ 3. Detecting an existing single-agent project and **migrating** it automatically.
36
+
37
+ ---
38
+
39
+ ## 📦 Installation
40
+
41
+ ```bash
42
+ pip install multi-harness
43
+ ```
44
+
45
+ Verify the install:
46
+
47
+ ```bash
48
+ mh --help
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 🚀 Quick start
54
+
55
+ ```bash
56
+ cd my-project
57
+ mh init
58
+ ```
59
+
60
+ That's it. `mh` detects which agents are already configured, migrates their files into
61
+ `.harness/`, and creates symlinks for all five supported agents.
62
+
63
+ ---
64
+
65
+ ## 📖 Commands
66
+
67
+ ### `mh init` — bootstrap or migrate a project
68
+
69
+ ```bash
70
+ mh init # all five agents, current directory
71
+ mh init --agents claude,codex # register only two agents
72
+ mh init --template ./AGENTS_TEMPLATE.md # seed AGENTS.md from a template file
73
+ mh init --force # re-create symlinks idempotently (safe)
74
+ mh init /path/to/project # target a different directory
75
+ ```
76
+
77
+ On first run `mh init`:
78
+ - Creates `AGENTS.md` (or uses your `--template`) as the shared project instructions file.
79
+ - Creates `.harness/skills/` and `.harness/agents/` as the shared canonical directories.
80
+ - Writes relative symlinks for every registered agent (see layout below).
81
+ - Records the registered agents in `.harness/config.toml`.
82
+
83
+ If exactly **one** agent is already configured, `mh init` migrates its files into
84
+ `.harness/` before creating symlinks — your existing work is preserved, not overwritten.
85
+
86
+ ---
87
+
88
+ ### `mh add` — register new agents
89
+
90
+ ```bash
91
+ mh add copilot # add a single agent
92
+ mh add opencode antigravity # add multiple agents at once
93
+ ```
94
+
95
+ Creates the symlinks for the new agent(s) and updates `.harness/config.toml`. Requires
96
+ `mh init` to have been run first.
97
+
98
+ ---
99
+
100
+ ### `mh remove` — unregister agents
101
+
102
+ ```bash
103
+ mh remove codex # remove one agent
104
+ mh remove opencode copilot # remove several at once
105
+ ```
106
+
107
+ Removes the agent's symlinks (instructions, skills, subagents) without touching any file
108
+ inside `.harness/`. Your shared content is never deleted.
109
+
110
+ ---
111
+
112
+ ### `mh status` — inspect symlink health
113
+
114
+ ```bash
115
+ mh status # check current directory
116
+ mh status /path/to/project # check another directory
117
+ ```
118
+
119
+ Reports the state of every symlink for every registered agent:
120
+
121
+ | Status | Meaning |
122
+ |--------|---------|
123
+ | ✅ `ok` | Symlink exists and resolves correctly |
124
+ | ❌ `missing` | Symlink is absent |
125
+ | 💔 `broken` | Symlink exists but target doesn't resolve |
126
+ | ⚠️ `detached` | A real file/dir sits where a symlink should be |
127
+
128
+ ---
129
+
130
+ ## 🗂️ Layout produced by `mh init`
131
+
132
+ ```
133
+ my-project/
134
+ ├── AGENTS.md ← canonical shared instructions (real file)
135
+ ├── CLAUDE.md → AGENTS.md
136
+ ├── .harness/
137
+ │ ├── config.toml ← registered agents list
138
+ │ ├── skills/ ← shared skills (real dir)
139
+ │ └── agents/ ← shared subagents (real dir)
140
+ ├── .claude/
141
+ │ ├── skills → ../.harness/skills
142
+ │ └── agents → ../.harness/agents
143
+ ├── .codex/
144
+ │ ├── skills → ../.harness/skills
145
+ │ └── agents → ../.harness/agents
146
+ ├── .opencode/
147
+ │ ├── skills → ../.harness/skills
148
+ │ └── agent → ../.harness/agents
149
+ ├── .github/
150
+ │ ├── copilot-instructions.md → ../AGENTS.md
151
+ │ ├── skills → ../.harness/skills
152
+ │ └── agents → ../.harness/agents
153
+ ├── .agents/
154
+ │ └── skills → ../.harness/skills
155
+ └── .subagents → .harness/agents
156
+ ```
157
+
158
+ All symlinks are **relative**, so the tree is fully portable across machines and paths.
159
+
160
+ ---
161
+
162
+ ## 🔄 Typical workflow
163
+
164
+ ```bash
165
+ # 1. Bootstrap a new project
166
+ mh init --agents claude,codex
167
+
168
+ # 2. Add an agent later
169
+ mh add copilot
170
+
171
+ # 3. Check everything is wired up correctly
172
+ mh status
173
+
174
+ # 4. Remove an agent you no longer use
175
+ mh remove antigravity
176
+ ```
177
+
178
+ Write your instructions once in `AGENTS.md`, drop skills into `.harness/skills/`, and
179
+ place shared subagents in `.harness/agents/` — every registered agent picks them up
180
+ automatically.
181
+
182
+ ---
183
+
184
+ ## 🛡️ Safety guarantees
185
+
186
+ - **Symlinks never overwrite real files.** If a real file or directory already exists
187
+ where a symlink should go, `mh` aborts with an error rather than deleting your data.
188
+ - **`--force` is safe.** It re-creates symlinks but still refuses to touch real files.
189
+ - **Migration is non-destructive.** Files are moved into `.harness/`; nothing is deleted.
@@ -0,0 +1,177 @@
1
+ # multi-harness 🔗
2
+
3
+ > One project. Many coding agents. Zero duplication.
4
+
5
+ `mh` is a CLI that keeps your skills, subagents, and project instructions in a single
6
+ canonical `.harness/` directory and materialises per-agent symlinks so every agent sees
7
+ the paths it expects — no copy-paste, no drift.
8
+
9
+ **Supported agents:** Claude Code · OpenAI Codex CLI · OpenCode · GitHub Copilot · Google Antigravity
10
+
11
+ ---
12
+
13
+ ## ✨ Why multi-harness?
14
+
15
+ Each coding agent looks for instructions, skills, and subagents in different places:
16
+ `CLAUDE.md`, `.github/copilot-instructions.md`, `AGENTS.md`, `.claude/skills/`, `.codex/skills/` …
17
+
18
+ Without `mh` you either duplicate these files across every agent-specific location or
19
+ keep them in sync by hand. `mh` solves this by:
20
+
21
+ 1. Creating one real `.harness/` directory with the canonical files.
22
+ 2. Writing relative symlinks everywhere each agent expects to look.
23
+ 3. Detecting an existing single-agent project and **migrating** it automatically.
24
+
25
+ ---
26
+
27
+ ## 📦 Installation
28
+
29
+ ```bash
30
+ pip install multi-harness
31
+ ```
32
+
33
+ Verify the install:
34
+
35
+ ```bash
36
+ mh --help
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 🚀 Quick start
42
+
43
+ ```bash
44
+ cd my-project
45
+ mh init
46
+ ```
47
+
48
+ That's it. `mh` detects which agents are already configured, migrates their files into
49
+ `.harness/`, and creates symlinks for all five supported agents.
50
+
51
+ ---
52
+
53
+ ## 📖 Commands
54
+
55
+ ### `mh init` — bootstrap or migrate a project
56
+
57
+ ```bash
58
+ mh init # all five agents, current directory
59
+ mh init --agents claude,codex # register only two agents
60
+ mh init --template ./AGENTS_TEMPLATE.md # seed AGENTS.md from a template file
61
+ mh init --force # re-create symlinks idempotently (safe)
62
+ mh init /path/to/project # target a different directory
63
+ ```
64
+
65
+ On first run `mh init`:
66
+ - Creates `AGENTS.md` (or uses your `--template`) as the shared project instructions file.
67
+ - Creates `.harness/skills/` and `.harness/agents/` as the shared canonical directories.
68
+ - Writes relative symlinks for every registered agent (see layout below).
69
+ - Records the registered agents in `.harness/config.toml`.
70
+
71
+ If exactly **one** agent is already configured, `mh init` migrates its files into
72
+ `.harness/` before creating symlinks — your existing work is preserved, not overwritten.
73
+
74
+ ---
75
+
76
+ ### `mh add` — register new agents
77
+
78
+ ```bash
79
+ mh add copilot # add a single agent
80
+ mh add opencode antigravity # add multiple agents at once
81
+ ```
82
+
83
+ Creates the symlinks for the new agent(s) and updates `.harness/config.toml`. Requires
84
+ `mh init` to have been run first.
85
+
86
+ ---
87
+
88
+ ### `mh remove` — unregister agents
89
+
90
+ ```bash
91
+ mh remove codex # remove one agent
92
+ mh remove opencode copilot # remove several at once
93
+ ```
94
+
95
+ Removes the agent's symlinks (instructions, skills, subagents) without touching any file
96
+ inside `.harness/`. Your shared content is never deleted.
97
+
98
+ ---
99
+
100
+ ### `mh status` — inspect symlink health
101
+
102
+ ```bash
103
+ mh status # check current directory
104
+ mh status /path/to/project # check another directory
105
+ ```
106
+
107
+ Reports the state of every symlink for every registered agent:
108
+
109
+ | Status | Meaning |
110
+ |--------|---------|
111
+ | ✅ `ok` | Symlink exists and resolves correctly |
112
+ | ❌ `missing` | Symlink is absent |
113
+ | 💔 `broken` | Symlink exists but target doesn't resolve |
114
+ | ⚠️ `detached` | A real file/dir sits where a symlink should be |
115
+
116
+ ---
117
+
118
+ ## 🗂️ Layout produced by `mh init`
119
+
120
+ ```
121
+ my-project/
122
+ ├── AGENTS.md ← canonical shared instructions (real file)
123
+ ├── CLAUDE.md → AGENTS.md
124
+ ├── .harness/
125
+ │ ├── config.toml ← registered agents list
126
+ │ ├── skills/ ← shared skills (real dir)
127
+ │ └── agents/ ← shared subagents (real dir)
128
+ ├── .claude/
129
+ │ ├── skills → ../.harness/skills
130
+ │ └── agents → ../.harness/agents
131
+ ├── .codex/
132
+ │ ├── skills → ../.harness/skills
133
+ │ └── agents → ../.harness/agents
134
+ ├── .opencode/
135
+ │ ├── skills → ../.harness/skills
136
+ │ └── agent → ../.harness/agents
137
+ ├── .github/
138
+ │ ├── copilot-instructions.md → ../AGENTS.md
139
+ │ ├── skills → ../.harness/skills
140
+ │ └── agents → ../.harness/agents
141
+ ├── .agents/
142
+ │ └── skills → ../.harness/skills
143
+ └── .subagents → .harness/agents
144
+ ```
145
+
146
+ All symlinks are **relative**, so the tree is fully portable across machines and paths.
147
+
148
+ ---
149
+
150
+ ## 🔄 Typical workflow
151
+
152
+ ```bash
153
+ # 1. Bootstrap a new project
154
+ mh init --agents claude,codex
155
+
156
+ # 2. Add an agent later
157
+ mh add copilot
158
+
159
+ # 3. Check everything is wired up correctly
160
+ mh status
161
+
162
+ # 4. Remove an agent you no longer use
163
+ mh remove antigravity
164
+ ```
165
+
166
+ Write your instructions once in `AGENTS.md`, drop skills into `.harness/skills/`, and
167
+ place shared subagents in `.harness/agents/` — every registered agent picks them up
168
+ automatically.
169
+
170
+ ---
171
+
172
+ ## 🛡️ Safety guarantees
173
+
174
+ - **Symlinks never overwrite real files.** If a real file or directory already exists
175
+ where a symlink should go, `mh` aborts with an error rather than deleting your data.
176
+ - **`--force` is safe.** It re-creates symlinks but still refuses to touch real files.
177
+ - **Migration is non-destructive.** Files are moved into `.harness/`; nothing is deleted.
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "multi-harness"
7
+ version = "0.1.0"
8
+ description = "Manage projects that target multiple coding agents from a single shared harness."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "jslarraz", email = "jslarraz@gmail.com" }]
13
+ dependencies = [
14
+ "typer>=0.12",
15
+ ]
16
+
17
+ [project.optional-dependencies]
18
+ dev = [
19
+ "pytest>=8",
20
+ ]
21
+
22
+ [project.scripts]
23
+ mh = "multi_harness.cli:app"
24
+
25
+ [tool.hatch.build.targets.wheel]
26
+ packages = ["src/multi_harness"]
27
+
28
+ [tool.pytest.ini_options]
29
+ testpaths = ["tests"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,13 @@
1
+ from .antigravity import SPEC as _ANTIGRAVITY
2
+ from .claude import SPEC as _CLAUDE
3
+ from .codex import SPEC as _CODEX
4
+ from .copilot import SPEC as _COPILOT
5
+ from .opencode import SPEC as _OPENCODE
6
+ from .spec import AgentSpec
7
+
8
+ AGENT_REGISTRY: dict[str, AgentSpec] = {
9
+ spec.name: spec
10
+ for spec in (_CLAUDE, _CODEX, _OPENCODE, _COPILOT, _ANTIGRAVITY)
11
+ }
12
+
13
+ __all__ = ["AGENT_REGISTRY", "AgentSpec"]
@@ -0,0 +1,12 @@
1
+ from pathlib import Path
2
+
3
+ from .spec import AgentSpec
4
+
5
+ SPEC = AgentSpec(
6
+ name="antigravity",
7
+ display_name="Google Antigravity",
8
+ instructions_path=None,
9
+ skills_path=Path(".agents/skills"),
10
+ subagents_path=Path(".subagents"),
11
+ detection_paths=(Path(".agents"), Path(".subagents")),
12
+ )
@@ -0,0 +1,12 @@
1
+ from pathlib import Path
2
+
3
+ from .spec import AgentSpec
4
+
5
+ SPEC = AgentSpec(
6
+ name="claude",
7
+ display_name="Claude Code",
8
+ instructions_path=Path("CLAUDE.md"),
9
+ skills_path=Path(".claude/skills"),
10
+ subagents_path=Path(".claude/agents"),
11
+ detection_paths=(Path("CLAUDE.md"), Path(".claude")),
12
+ )
@@ -0,0 +1,12 @@
1
+ from pathlib import Path
2
+
3
+ from .spec import AgentSpec
4
+
5
+ SPEC = AgentSpec(
6
+ name="codex",
7
+ display_name="OpenAI Codex",
8
+ instructions_path=None,
9
+ skills_path=Path(".codex/skills"),
10
+ subagents_path=Path(".codex/agents"),
11
+ detection_paths=(Path(".codex"),),
12
+ )
@@ -0,0 +1,12 @@
1
+ from pathlib import Path
2
+
3
+ from .spec import AgentSpec
4
+
5
+ SPEC = AgentSpec(
6
+ name="copilot",
7
+ display_name="GitHub Copilot",
8
+ instructions_path=Path(".github/copilot-instructions.md"),
9
+ skills_path=Path(".github/skills"),
10
+ subagents_path=Path(".github/agents"),
11
+ detection_paths=(Path(".github/copilot-instructions.md"),),
12
+ )