Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .context/decisions/016-multi-agent-harness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# ADR-016: Multi-Agent Harness via Adapter Registry

**Status:** Accepted
**Date:** 2026-06-02
**Version:** 1.0
**Deciders:** Nicholas (Gocase)

## Context

dotcontext was built Claude-Code-first (ADR-004): a project-root `CLAUDE.md` plus `.claude/`
commands, agents, and skills. ADR-004 explicitly accepted "tightly coupled to Claude Code
(won't work with other AI tools)" as a tradeoff.

The toolkit's value — the curated project instructions, decisions, and skills — is agent-agnostic.
Coding agents have converged on a near-common convention: the **AGENTS.md** open standard
(Linux-Foundation-stewarded, plain Markdown, nearest-file-wins). GitHub's spec-kit ships per-agent
integrations; we want the same reach without abandoning the Claude-first ergonomics.

Research (2026) on where each agent reads its project instruction/memory file:

| Agent | Instructions file | Reads `AGENTS.md` natively? |
|-------|-------------------|-----------------------------|
| Claude Code | `CLAUDE.md` | No (but supports `@import`) |
| OpenAI Codex | `AGENTS.md` | Yes (originator) |
| opencode | `AGENTS.md` (also reads `CLAUDE.md`) | Yes |
| GitHub Copilot | `AGENTS.md` / `.github/copilot-instructions.md` | Yes (since Aug 2025) |
| Cursor (IDE + `cursor-agent` CLI) | `AGENTS.md` / `.cursor/rules/*.mdc` | Yes |
| Gemini CLI | `GEMINI.md` | No (but supports `@import`; configurable) |

## Decision

### 1. Extensible adapter registry

A registry (`src/setup/agents.sh`) declares each supported agent as a small record: `id`,
display name, detection command (`command -v`), instructions filename, and emit mode. Adding an
agent is one entry — nothing else in the toolkit hard-codes an agent. Initial set:
`claude, codex, opencode, gemini, copilot, cursor` (the Cursor entry covers both the IDE and the
`cursor-agent` CLI).

### 2. `AGENTS.md` is the single canonical source of project instructions

The real instruction content lives in **`AGENTS.md` at the repo root**. This natively covers
**codex, opencode, copilot, and cursor** with zero extra files. The two agents that don't read
`AGENTS.md` get thin **import stubs** pointing at it (both support `@import`):

- `CLAUDE.md` → `@AGENTS.md` (for Claude Code)
- `GEMINI.md` → `@AGENTS.md` (for Gemini CLI)

Single source, no duplication, no drift; each editor edits `AGENTS.md`.

### 3. Interactive agent detection (no new CLI flags)

`dotcontext init` detects which agent CLIs are installed and emits the matching instruction files;
in interactive mode it confirms the selection. `--yes` sets up all detected agents (falling back
to Claude when none are detected). This honors the minimal-CLI constraint (ADR-007) — no
`--agent` flag, the flow lives inside `init`.

### 4. Safe migration for existing projects

`dotcontext update` migrates legacy single-file projects: when a content-bearing `CLAUDE.md`
exists and `AGENTS.md` does not, it offers to make `AGENTS.md` canonical (move the content) and
leave `CLAUDE.md` as an `@AGENTS.md` stub. This is content-preserving and behavior-preserving for
Claude (it still reads the same content via the import).

### 5. Scope of this decision (phase 2a)

This ADR covers the **instructions file** only. Skills and hooks portability is addressed in
**ADR-017**; porting slash commands to each agent's native format is deferred to a later phase.

> **Correction (2026-06-03):** an earlier draft of this ADR claimed "Codex/Gemini/etc. have no
> structured-question API," used to justify a degraded `{{ASK}}` fallback. That premise is **false**.
> Current research (see ADR-017) confirms **all six agents ship a model-callable structured-question
> tool** (Claude `AskUserQuestion`, Codex `request_user_input`, opencode `question`, Gemini
> `ask_user`, Copilot `ask_user`, Cursor `cursor/ask_question`) **and** lifecycle hooks. So command
> portability (ADR-018) renders `{{ASK}}` to each agent's **native** question tool — it
> does not degrade to free text. The `--version --json` handshake (ADR-015) flips `multiagent: true`
> and lists supported `agents` as adapters land.

## Consequences

### Positive
- The toolkit works across Claude, Codex, opencode, Copilot, Cursor, and Gemini from one source.
- Adding a new agent is a single registry entry.
- Existing Claude-only projects keep working and migrate safely.

### Negative
- A root `AGENTS.md` plus possible `CLAUDE.md`/`GEMINI.md` stubs is slightly more surface than a
lone `CLAUDE.md`.
- Import resolution depends on each agent honoring `@import`; agents that don't are covered by
reading `AGENTS.md` directly, but a future agent that does neither would need a real copy.
- Command/skill portability is **not** solved here (phase 2b).

## Alternatives Considered

1. **Keep `CLAUDE.md` canonical, point `AGENTS.md` at it via `@import`** — rejected: Codex/Copilot/
Cursor don't resolve `@import`, so they'd see a literal pointer instead of content.
2. **Symlinks (`AGENTS.md` → `CLAUDE.md`)** — rejected: fragile on Windows/WSL (ADR cross-platform rule) and in git.
3. **Full content copies per agent** — rejected: guarantees drift across files.
4. **Per-agent zip artifacts (old spec-kit model)** — rejected: doesn't fit the single-bash-executable + curl distribution (ADR-001/002).

## History

| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-06-02 | Initial decision (phase 2a: instructions file across agents) |

## Related
- ADR-004: Claude Code integration (this extends it beyond Claude)
- ADR-005: Mandatory AskUserQuestion (will get a v2.0 for command portability in phase 2b)
- ADR-007: CLI simplification (interactive detection, no new flags)
- ADR-015: Capability discovery & update awareness (the handshake this populates)
102 changes: 102 additions & 0 deletions .context/decisions/017-skills-and-hooks-portability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# ADR-017: Harness Selection, Skills & Hooks Portability

**Status:** Accepted
**Date:** 2026-06-03
**Version:** 1.0
**Deciders:** Nicholas (Gocase)

## Context

ADR-016 made the project-instructions file (`AGENTS.md`) multi-agent. Two follow-ups remained:
**skills** and **hooks**. Research (June 2026) overturned an earlier assumption: **all six target
agents now implement the open Agent Skills (`SKILL.md`) standard, ship lifecycle hooks, and expose a
model-callable structured-question tool** (so the `AskUserQuestion` premise in ADR-016's first draft
was wrong — corrected there).

Skills directory coverage:

| Reads `.agents/skills/` | Reads `.claude/skills/` |
|-------------------------|--------------------------|
| Codex, opencode, Gemini, Copilot, Cursor | Claude, opencode, Copilot, Cursor |

No single directory covers all six: **Claude only reads `.claude/skills/`**, and **Codex/Gemini do
not read `.claude/skills/`**.

A separate problem surfaced: the old `init` emitted **all** of `.claude/` (commands, agents,
statusline, settings) plus `CLAUDE.md` unconditionally — junk for a user who only runs Codex or
Gemini.

## Decision

### 1. Harness selection — only emit what the chosen agents use

`dotcontext init` resolves a set of harnesses and emits files **only** for them:
- **Interactive** (default): confirm each detected agent (default = detected set).
- **`--agents claude,codex`** flag: non-interactive/scripted selection (a deliberate, scoped
exception to the minimal-CLI rule of ADR-007, for spec-kit `--integration` parity).
- **`--yes`**: all detected agents (fallback to `claude` if none).

Emission gating:
- `AGENTS.md` (canonical instructions) + `.context/` skeleton + MCP → **always** (harness-agnostic).
- `CLAUDE.md` stub + **all of `.claude/`** (commands, agents, statusline, `.claudeignore`) → **only if
Claude is selected**.
- `GEMINI.md` stub → only if Gemini selected.
- A Codex-only project therefore gets just `AGENTS.md` + `.agents/skills/` + a Codex hook — no `.claude/`.

### 2. Skills — `.agents/skills/` canonical, mirrored to `.claude/skills/`

The shared `SKILL.md` files are emitted to the physical directory matching the selection:
- Claude selected → physical `.claude/skills/`; if an `AGENTS.md`-reading agent is also selected,
`.agents/skills/` is a symlink to it (copy fallback for filesystems without symlinks).
- Claude not selected → physical `.agents/skills/`.

dotcontext owns these files, so a single physical copy + symlink avoids drift (no `@import` exists for
skills, unlike instructions).

### 3. Hooks — a notification hook per selected harness

Each selected harness gets a "task finished / needs attention" notification wired in its native config:
- Claude → `.claude/settings.json` (existing: notify + tool-failure-guard).
- Codex → `.codex/hooks.json`; Gemini → `.gemini/settings.json`; Copilot → `.github/hooks/dotcontext-notify.json`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Capitalize “GitHub” consistently in hook path examples.

Use “GitHub Copilot” capitalization in this sentence for consistency with the rest of the docs.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~60-~60: The official name of this software platform is spelled with a capital “H”.
Context: ...ni → .gemini/settings.json; Copilot → .github/hooks/dotcontext-notify.json; Cursor...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.context/decisions/017-skills-and-hooks-portability.md at line 60, Update
the example sentence that lists hook paths so “Copilot” is written as “GitHub
Copilot” and “GitHub” is capitalized consistently; specifically edit the line
that reads "Codex → `.codex/hooks.json`; Gemini → `.gemini/settings.json`;
Copilot → `.github/hooks/dotcontext-notify.json`;" to use "GitHub Copilot →
`.github/hooks/dotcontext-notify.json`" (ensure the word “GitHub” is capitalized
exactly as elsewhere in the docs).

Cursor → `.cursor/hooks.json`; opencode → `.opencode/plugins/dotcontext-notify.js` (opencode has no
declarative hooks — only JS/TS plugins).
- All point at a shared, **arg-driven** `notify.sh` (it takes title/message/sound as args and ignores
stdin, so the same script works regardless of each agent's hook JSON contract). Create-only — never
clobbers an existing agent config.

**Scope limits (intentional):** only the **notification** hook ports. The richer
`tool-failure-guard` stays **Claude-only** (it depends on Claude's `PostToolUseFailure` semantics, which
don't map uniformly). Non-Claude hook configs are validated as well-formed (JSON/TOML/JS) but are
**best-effort** — they are not end-to-end tested against each agent runtime.

## Consequences

### Positive
- No junk: a project only carries files for the harnesses it actually uses.
- Skills and notification hooks work across all six agents from shared sources.
- Confirms command portability (ADR-018) is viable — every agent has a native
structured-question tool.

### Negative
- Per-agent hook configs are best-effort (not runtime-tested per agent); event-name/semantics differ
(e.g. Gemini uses `AfterAgent`, not `Stop`).
- `tool-failure-guard` remains Claude-only.
- A `--agents` flag widens the CLI surface (scoped exception, justified above).

## Alternatives Considered

1. **Emit everything for all agents always** — rejected: dumps junk (the problem this fixes).
2. **One skills dir for all** — impossible: Claude and Codex/Gemini read disjoint directories.
3. **Duplicate skill copies per ecosystem** — rejected: drift; symlink keeps one source.
4. **Port `tool-failure-guard` everywhere** — rejected for now: no uniform failure-event semantics.

## History

| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-06-03 | Initial decision (harness selection, skills, notification hooks) |

## Related
- ADR-016: Multi-agent harness (instructions file) — this builds on it
- ADR-005: Mandatory AskUserQuestion — ADR-018 renders `{{ASK}}` to each agent's native question tool to satisfy it cross-agent
- ADR-007: CLI simplification — `--agents` is a scoped exception
79 changes: 79 additions & 0 deletions .context/decisions/018-command-portability-and-invocation-modes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# ADR-018: Command Portability & Invocation Modes (phase 2b plan)

**Status:** Proposed
**Date:** 2026-06-03
**Deciders:** Nicholas (Gocase)

## Context

ADR-016/017 made instructions, skills, and hooks multi-agent. The remaining piece (phase 2b) is
porting the 12 slash commands. Two facts shape the design:

1. **Commands and skills have converged** (Claude Code): a `/x` command is effectively a skill with
`disable-model-invocation: true`. Skills (`SKILL.md`) port cleanly to all six agents (ADR-017);
classic per-repo commands do not (Codex prompts are global, Cursor has no file-based slash command).
2. **Every agent ships a structured-question tool** (ADR-016 correction): Claude `AskUserQuestion`,
Codex `request_user_input`, opencode `question`, Gemini `ask_user`, Copilot `ask_user`, Cursor
`cursor/ask_question`. So requirement-gathering (ADR-005) is satisfiable on every agent.

The tempting shortcut — "make everything a skill" — is **unsafe**: skills are model-auto-invocable,
and `disable-model-invocation` (explicit-only) is honored only by Claude and Cursor. Auto-firing a
side-effecting command (`/commit`, `/create-pr`) on the other agents would be a foot-gun.

## Decision

### 1. Each artifact declares an invocation mode

- **`skill`** — auto-discoverable (model invokes by `description`) **and** explicitly invocable. For
read-mostly knowledge/analysis with no dangerous side effects.
- **`command`** — explicit-only. For deliberate, side-effecting, or outward-facing actions.

Classification (skills for knowledge, commands for action):

| Mode `skill` | Mode `command` (explicit-only) |
|---|---|
| `bug-reproduction`, `batch-operations`, `git-platform` (existing guides) | `setup-context`, `generate-prp`, `execute-prp`, `commit`, `create-pr`, `pr-comment`, `add-decision`, `add-skill`, `add-command` |
| **`code-review`**, **`deep-context`** (read-mostly analysis — promoted from command) | `fix-bug` (makes changes; leans on the `bug-reproduction` skill) |

Rationale for the promotions: `code-review` and `deep-context` are read-mostly, and "review my changes"
/ "help me understand X" are natural auto-triggers — discovery adds value with no side-effect risk, and
the explicit `/name` still works.

### 2. Emit per agent by mode

- `skill` mode → `SKILL.md` (already ports to all six — ADR-017).
- `command` mode → each agent's **explicit** primitive: Claude command, opencode command, Copilot
prompt file, Gemini custom command (TOML), Cursor skill + `disable-model-invocation`, Codex prompt
(global `~/.codex/prompts/`, namespaced). Where an agent only offers auto-skills, use its explicit
flag if honored, otherwise fall back to documenting the workflow in `AGENTS.md`.

### 3. Portable `{{ASK}}` directive

Command/skill bodies express requirement-gathering with a portable `{{ASK: question | optA | optB }}`
directive. At emit time it renders to each agent's **native** structured-question tool — it does **not**
degrade to free text. This satisfies ADR-005's clarity-assessed questioning on every agent.

## Consequences

- **Positive:** preserves the safe boundary (knowledge = skill, action = command); no side-effecting
auto-invocation; `{{ASK}}` keeps the ADR-005 contract everywhere.
- **Negative:** the emitter must implement per-agent command formats + the `{{ASK}}` renderer; Codex
commands remain global; Cursor commands ride on the skill+flag path.

## Alternatives Considered

1. **All artifacts as auto-skills** — rejected: unsafe (auto-firing side effects; `disable-model-invocation`
not universal).
2. **All as classic commands** — rejected: don't port (Codex global, Cursor none).
3. **Free-text fallback for `{{ASK}}`** — rejected: unnecessary, every agent has a native question tool.

## History

| Version | Date | Changes |
|---------|------|---------|
| 1.0 (proposed) | 2026-06-03 | Initial plan for phase 2b |

## Related
- ADR-005: Mandatory AskUserQuestion (clarity assessment) — `{{ASK}}` is how it's satisfied cross-agent
- ADR-016: Multi-agent harness (instructions)
- ADR-017: Harness selection, skills & hooks portability
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## [0.16.0](https://github.com/goca-se/dotcontext/compare/v0.15.0...v0.16.0) (2026-06-03)

### Features

* **multi-agent support** — dotcontext now targets six harnesses (Claude Code, OpenAI Codex, opencode, Gemini CLI, GitHub Copilot, Cursor incl. `cursor-agent`) instead of Claude only (ADR-016, ADR-017):
* **extensible adapter registry** (`src/setup/agents.sh`) — each agent is one entry (`id`, name, detection, instructions file, emit mode). Adding an agent is a single case arm
* **harness selection — only emit what you choose** — `init` confirms each detected agent interactively, or takes `--agents claude,codex` (non-interactive), or `--yes` (all detected). A Codex-only project gets **no `.claude/`** — no junk
* **instructions** — canonical **`AGENTS.md`** read natively by Codex/opencode/Copilot/Cursor; **Claude** (`CLAUDE.md`) and **Gemini** (`GEMINI.md`) via thin `@AGENTS.md` import stubs. Single source, no duplication
* **skills** — shared `SKILL.md` content emitted to `.agents/skills/` (Codex/opencode/Gemini/Copilot/Cursor) mirrored to `.claude/skills/` (Claude) via symlink (copy fallback)
* **hooks** — a "task finished / needs attention" notification wired per selected harness in its native config (`.codex/hooks.json`, `.gemini/settings.json`, `.github/hooks/`, `.cursor/hooks.json`, opencode JS plugin); Claude also keeps the tool-failure guard

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use official “GitHub” capitalization in this bullet.

Tiny wording fix, but it avoids inconsistency in release notes.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~12-~12: The official name of this software platform is spelled with a capital “H”.
Context: ...x/hooks.json, .gemini/settings.json, .github/hooks/, .cursor/hooks.json`, opencode...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 12, Update the release-note bullet that mentions
".github/hooks/" to use the official capitalization "GitHub" instead of "github"
— edit the line containing `.github/hooks/` so it reads `.GitHub/hooks/` (and
ensure surrounding text keeps the same punctuation and casing).

* **`update` migrates legacy projects** — a content-bearing `CLAUDE.md` with no `AGENTS.md` is offered migration into the shared `AGENTS.md` (content- and behavior-preserving), plus a `GEMINI.md` stub when the Gemini CLI is present
* **`--version --json`** reports `multiagent: true`, `skills: true`, `hooks: true` and the supported `agents` list; **`doctor`** is `AGENTS.md`-aware and reports detected agents

### Notes

* Slash **commands** remain Claude-native; per-agent command ports (ADR-018 — invocation-mode classification + a portable `{{ASK}}` rendered to each agent's native structured-question tool) are the next phase. Non-Claude hook configs are validated as well-formed but are best-effort (not runtime-tested per agent); the tool-failure guard stays Claude-only.

## [0.15.0](https://github.com/goca-se/dotcontext/compare/v0.14.2...v0.15.0) (2026-06-02)

### Features
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SOURCES = \
src/core/utils.sh \
src/setup/notifications.sh \
src/setup/mcp.sh \
src/setup/agents.sh \
src/commands/init.sh \
src/commands/update.sh \
src/commands/doctor.sh \
Expand Down
Loading
Loading