diff --git a/docs/assets/social-preview.png b/docs/assets/social-preview.png index 7896e79..fcba1c1 100644 Binary files a/docs/assets/social-preview.png and b/docs/assets/social-preview.png differ diff --git a/docs/assets/social-preview.svg b/docs/assets/social-preview.svg index 23a2fe1..985d216 100644 --- a/docs/assets/social-preview.svg +++ b/docs/assets/social-preview.svg @@ -1,5 +1,5 @@ + role="img" aria-label="agentseam — the primitives layer for every coding agent: one handler API over per-agent hooks, instruction files, plugin packaging, and config. 12 adapters (claude_code, antigravity, codex_cli, cursor, devin, gemini_cli, grok, junie, kimi_code, tabnine, vscode_copilot, windsurf); 12 normalized events (pre_tool, post_tool, tool_failure, prompt_submit, session_start, session_end, subagent_start, subagent_stop, instructions_loaded, file_changed, pre_compact, stop); 6 decision outcomes (allow, deny, escalate, transform, warn, vouch); and the 5 honest enforcement levels a consumer may claim (enforced, enforceable, best-effort, detect, none). 18 agents in the capability matrix, 12 adapted, zero dependencies, Apache-2.0, version 0.3.5."> @@ -119,7 +119,7 @@ none - 16 + 18 AGENTS IN MATRIX 12 ADAPTED diff --git a/docs/figures/family-dark.svg b/docs/figures/family-dark.svg index 507b8e2..681a682 100644 --- a/docs/figures/family-dark.svg +++ b/docs/figures/family-dark.svg @@ -28,7 +28,7 @@ agentseam the primitives — one handler API and a verified capability matrix across - 16 agents + 18 agents context-report the evidence — a diff --git a/docs/figures/family-light.svg b/docs/figures/family-light.svg index 4775f14..b8500b7 100644 --- a/docs/figures/family-light.svg +++ b/docs/figures/family-light.svg @@ -28,7 +28,7 @@ agentseam the primitives — one handler API and a verified capability matrix across - 16 agents + 18 agents context-report the evidence — a diff --git a/docs/figures/make_matrix.py b/docs/figures/make_matrix.py index e6860ab..ee0aa7f 100644 --- a/docs/figures/make_matrix.py +++ b/docs/figures/make_matrix.py @@ -1,4 +1,4 @@ -"""Render agentseam's capability matrix: 16 agents x 12 events, graded from src/agentseam/matrix.py. +"""Render agentseam's capability matrix: 18 agents x 12 events, graded from src/agentseam/matrix.py. Run from this directory: @@ -40,7 +40,7 @@ GRID_X0 = MARGIN_L + LABEL_W GRID_Y0 = TITLE_H + HEADER_H -GRID_H = 16 * CELL_H +GRID_H = 18 * CELL_H H = GRID_Y0 + GRID_H + LEGEND_H #: Column order is a display choice (roughly lifecycle order); the set is not -- it is @@ -64,7 +64,7 @@ assert set(EVENTS) == _actual_events, f"EVENTS list drifted from matrix.py: {_actual_events}" AGENTS = matrix.agents() # sorted() -- the same order matrix.py itself considers canonical -assert len(AGENTS) == 16, f"expected 16 agents, matrix.py now has {len(AGENTS)}" +assert len(AGENTS) == 18, f"expected 18 agents, matrix.py now has {len(AGENTS)}" #: Ordinal position each grade takes in the shared 5-step LEVELS ramp (index 4 = darkest = #: strongest, matching the ENFORCEMENT ramp's own advisory-to-enforced direction). `none` is @@ -95,7 +95,7 @@ def cell_grades(): - """{(agent, event): grade} for the full 16x12 grid, and a grade -> count tally.""" + """{(agent, event): grade} for the full 18x12 grid, and a grade -> count tally.""" grades = {} counts = {g: 0 for g in GRADE_ORDER_DISPLAY} for agent in AGENTS: @@ -116,18 +116,19 @@ def render(t, name, grades, counts): total = sum(counts.values()) present = [g for g in GRADE_ORDER_DISPLAY if counts[g] > 0] desc = ( - "Grid of 16 coding agents by 12 lifecycle events, shaded by the enforcement grade " + "Grid of 18 coding agents by 12 lifecycle events, shaded by the enforcement grade " "agentseam can honestly claim at that surface. Of %d cells: %s. No agent is graded " "enforced at any event -- eleven agents reach only best-effort at pre_tool, Cursor " - "alone reaches enforceable there, and aider, Copilot, Replit and Zed have no hook " - "surface at pre_tool at all." % (total, "; ".join("%d %s" % (counts[g], LABEL[g]) for g in present)) + "alone reaches enforceable there, and aider, Copilot, Kilo Code, OpenCode, Replit " + "and Zed have nothing agentseam can gate at pre_tool." + % (total, "; ".join("%d %s" % (counts[g], LABEL[g]) for g in present)) ) svg = p.open_svg(W, H, t, "agentseam capability matrix", desc) svg += p.text(MARGIN_L, 20, "What each agent can honestly do, by event", t["text"], 15, p.SANS, "600") svg += p.text( MARGIN_L, 36, - "16 agents × 12 events, graded from src/agentseam/matrix.py -- not one cell says “enforced”", + "18 agents × 12 events, graded from src/agentseam/matrix.py -- not one cell says “enforced”", t["secondary"], 10.5, ) diff --git a/docs/figures/make_social.py b/docs/figures/make_social.py index 9bfb301..bb0db57 100644 --- a/docs/figures/make_social.py +++ b/docs/figures/make_social.py @@ -64,7 +64,7 @@ def build(): svg += p.text( 74, 500, - "16 agents × 12 events, verified from src/agentseam/matrix.py — not one cell claims more than its evidence.", + "18 agents × 12 events, verified from src/agentseam/matrix.py — not one cell claims more than its evidence.", t["secondary"], 15, ) diff --git a/docs/figures/matrix-dark.svg b/docs/figures/matrix-dark.svg index ccf600b..8cd27b0 100644 --- a/docs/figures/matrix-dark.svg +++ b/docs/figures/matrix-dark.svg @@ -1,9 +1,9 @@ - + agentseam capability matrix - Grid of 16 coding agents by 12 lifecycle events, shaded by the enforcement grade agentseam can honestly claim at that surface. Of 192 cells: 2 enforceable; 34 best-effort; 55 detect; 101 none. No agent is graded enforced at any event -- eleven agents reach only best-effort at pre_tool, Cursor alone reaches enforceable there, and aider, Copilot, Replit and Zed have no hook surface at pre_tool at all. - + Grid of 18 coding agents by 12 lifecycle events, shaded by the enforcement grade agentseam can honestly claim at that surface. Of 216 cells: 2 enforceable; 34 best-effort; 55 detect; 125 none. No agent is graded enforced at any event -- eleven agents reach only best-effort at pre_tool, Cursor alone reaches enforceable there, and aider, Copilot, Kilo Code, OpenCode, Replit and Zed have nothing agentseam can gate at pre_tool. + What each agent can honestly do, by event - 16 agents × 12 events, graded from src/agentseam/matrix.py -- not one cell says “enforced” + 18 agents × 12 events, graded from src/agentseam/matrix.py -- not one cell says “enforced” pre_tool post_tool stop @@ -26,12 +26,14 @@ gemini_cli grok junie - kimi_code - replit - tabnine - vscode_copilot - windsurf - zed + kilo_code + kimi_code + opencode + replit + tabnine + vscode_copilot + windsurf + zed – @@ -272,70 +274,70 @@ – – - - BE - - DT - - BE - - DT - - BE - - DT - - DT - - DT - - DT - - DT + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – – – - - – - - – - - – - - – - - – - - – - - – - - – - - – - - – + + BE + + DT + + BE + + DT + + BE + + DT + + DT + + DT + + DT + + DT – – - - BE - - BE - - BE + + – + + – + + – – - - BE - - DT - - DT - - DT + + – + + – + + – + + – – @@ -344,46 +346,46 @@ – – - - BE - - BE - - BE + + – + + – + + – – - - BE - - DT + + – + + – – – - - DT - - BE + + – + + – – – BE - - DT - - DT + + BE + + BE – BE - - – - - – - - – + + DT + + DT + + DT – @@ -392,42 +394,90 @@ – – - - – - - – - - – + + BE + + BE + + BE – - - – - - – + + BE + + DT – – - - – - - – + + DT + + BE – – - - EA - enforceable (2) - - BE - best-effort (34) - - DT - detect (55) - - – - none (101) - “enforced” never appears above: no agent in this matrix blocks and fails closed at any event. - – marks no hook surface at all, not a weak grade -- it is drawn in grey, never on the ramp. + + BE + + DT + + DT + + – + + BE + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + EA + enforceable (2) + + BE + best-effort (34) + + DT + detect (55) + + – + none (125) + “enforced” never appears above: no agent in this matrix blocks and fails closed at any event. + – marks no hook surface at all, not a weak grade -- it is drawn in grey, never on the ramp. diff --git a/docs/figures/matrix-light.svg b/docs/figures/matrix-light.svg index 4608888..fa96726 100644 --- a/docs/figures/matrix-light.svg +++ b/docs/figures/matrix-light.svg @@ -1,9 +1,9 @@ - + agentseam capability matrix - Grid of 16 coding agents by 12 lifecycle events, shaded by the enforcement grade agentseam can honestly claim at that surface. Of 192 cells: 2 enforceable; 34 best-effort; 55 detect; 101 none. No agent is graded enforced at any event -- eleven agents reach only best-effort at pre_tool, Cursor alone reaches enforceable there, and aider, Copilot, Replit and Zed have no hook surface at pre_tool at all. - + Grid of 18 coding agents by 12 lifecycle events, shaded by the enforcement grade agentseam can honestly claim at that surface. Of 216 cells: 2 enforceable; 34 best-effort; 55 detect; 125 none. No agent is graded enforced at any event -- eleven agents reach only best-effort at pre_tool, Cursor alone reaches enforceable there, and aider, Copilot, Kilo Code, OpenCode, Replit and Zed have nothing agentseam can gate at pre_tool. + What each agent can honestly do, by event - 16 agents × 12 events, graded from src/agentseam/matrix.py -- not one cell says “enforced” + 18 agents × 12 events, graded from src/agentseam/matrix.py -- not one cell says “enforced” pre_tool post_tool stop @@ -26,12 +26,14 @@ gemini_cli grok junie - kimi_code - replit - tabnine - vscode_copilot - windsurf - zed + kilo_code + kimi_code + opencode + replit + tabnine + vscode_copilot + windsurf + zed – @@ -272,70 +274,70 @@ – – - - BE - - DT - - BE - - DT - - BE - - DT - - DT - - DT - - DT - - DT + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – – – - - – - - – - - – - - – - - – - - – - - – - - – - - – - - – + + BE + + DT + + BE + + DT + + BE + + DT + + DT + + DT + + DT + + DT – – - - BE - - BE - - BE + + – + + – + + – – - - BE - - DT - - DT - - DT + + – + + – + + – + + – – @@ -344,46 +346,46 @@ – – - - BE - - BE - - BE + + – + + – + + – – - - BE - - DT + + – + + – – – - - DT - - BE + + – + + – – – BE - - DT - - DT + + BE + + BE – BE - - – - - – - - – + + DT + + DT + + DT – @@ -392,42 +394,90 @@ – – - - – - - – - - – + + BE + + BE + + BE – - - – - - – + + BE + + DT – – - - – - - – + + DT + + BE – – - - EA - enforceable (2) - - BE - best-effort (34) - - DT - detect (55) - - – - none (101) - “enforced” never appears above: no agent in this matrix blocks and fails closed at any event. - – marks no hook surface at all, not a weak grade -- it is drawn in grey, never on the ramp. + + BE + + DT + + DT + + – + + BE + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + – + + EA + enforceable (2) + + BE + best-effort (34) + + DT + detect (55) + + – + none (125) + “enforced” never appears above: no agent in this matrix blocks and fails closed at any event. + – marks no hook surface at all, not a weak grade -- it is drawn in grey, never on the ramp. diff --git a/docs/figures/social-card.svg b/docs/figures/social-card.svg index 6860eb4..576b60e 100644 --- a/docs/figures/social-card.svg +++ b/docs/figures/social-card.svg @@ -1,12 +1,12 @@ agentseam - agentseam: one handler API over every coding agent's hooks, instruction files, plugin packaging and config. 0 of 192 capability-matrix cells are graded enforced. + agentseam: one handler API over every coding agent's hooks, instruction files, plugin packaging and config. 0 of 216 capability-matrix cells are graded enforced. agentseam one handler API over every coding agent's hooks — graded, not assumed – - 0 of 192 capability-matrix cells graded enforced - 16 agents × 12 events, verified from src/agentseam/matrix.py — not one cell claims more than its evidence. + 0 of 216 capability-matrix cells graded enforced + 18 agents × 12 events, verified from src/agentseam/matrix.py — not one cell claims more than its evidence. diff --git a/src/agentseam/data/matrix.json b/src/agentseam/data/matrix.json index 402839b..7e5650b 100644 --- a/src/agentseam/data/matrix.json +++ b/src/agentseam/data/matrix.json @@ -2586,5 +2586,31 @@ }, "events": {}, "notes": "No lifecycle hooks. Only --lint-cmd/--test-cmd post-edit steps. Observation possible via git hooks; no interception." + }, + "opencode": { + "display": "OpenCode", + "tier": "unadapted", + "config": null, + "verified": { + "basis": "vendor-docs", + "version": "opencode-ai 1.18.35 (v1) and @opencode/cli 2.0.26 (v2), the npm latest of each on 2026-10-11", + "date": "2026-10-11", + "method": "read the vendor's own docs and config schema on 2026-10-11: https://opencode.ai/docs/plugins/ (v1), https://opencode.ai/v2/docs/plugins, https://opencode.ai/v2/docs/build/plugins and https://opencode.ai/v2/docs/config (v2), and https://opencode.ai/config.json. The one interception surface documented is an in-process JavaScript/TypeScript plugin API: v1 plugins return a 'tool.execute.before' hook that can throw to stop a tool call, v2 plugins register ctx.tool.hook('execute.before'). Both load from .opencode/plugins/ or the config's plugin array. The config schema's top-level object is additionalProperties: false and has no key that runs an external command on a lifecycle event." + }, + "events": {}, + "notes": "Unadapted, not none: OpenCode has a real interception surface, but it is an in-process JS/TS plugin API (tool.execute.before), not a command hook that hands a JSON payload to an external process. Every agentseam adapter speaks a command-hook dialect, and the org keeps in-process plugin APIs on watch for now, so nothing here gates OpenCode's tool calls. A plugin shim that calls an agentseam handler would be a new feature, not an adapter. Instruction files still reach it through AGENTS.md. Evidence wanted (to test or overturn this row): https://github.com/open-coder-ai/agentseam/issues/174" + }, + "kilo_code": { + "display": "Kilo Code", + "tier": "unadapted", + "config": null, + "verified": { + "basis": "vendor-docs", + "version": "@kilocode/cli 7.8.8, the npm latest on 2026-10-11; the docs page says it applies to the current VS Code extension and CLI", + "date": "2026-10-11", + "method": "read the vendor's own docs and config schema on 2026-10-11: https://kilo.ai/docs/automate/extending/plugins, https://kilo.ai/articles/claude-code-to-kilo-code-migration-guide and https://app.kilo.ai/config.json. The one interception surface documented is an in-process JavaScript/TypeScript plugin API, which the plugins page calls behaviourally identical to OpenCode's: a 'tool.execute.before' hook that can throw to block, loaded from .kilo/plugin/ (legacy .kilocode/plugin/) or the config's plugin array. The migration guide maps Claude Code's PreToolUse to that plugin hook rather than to a command hook. No config key that runs an external command on a lifecycle event was found in the schema. The vendor issue asking for one (Kilo-Org/kilocode#7859) was closed in a bulk close of legacy-extension issues, with no statement that command hooks exist." + }, + "events": {}, + "notes": "Unadapted, not none: Kilo Code has a real interception surface, but it is the OpenCode-derived in-process JS/TS plugin API (tool.execute.before), not a command hook that hands a JSON payload to an external process. Every agentseam adapter speaks a command-hook dialect, and the org keeps in-process plugin APIs on watch for now, so nothing here gates Kilo Code's tool calls. Instruction files still reach it through AGENTS.md. Evidence wanted (to test or overturn this row): https://github.com/open-coder-ai/agentseam/issues/175" } } diff --git a/src/agentseam/data/packaging-limits.json b/src/agentseam/data/packaging-limits.json index 584c6b0..58c6666 100644 --- a/src/agentseam/data/packaging-limits.json +++ b/src/agentseam/data/packaging-limits.json @@ -56,6 +56,8 @@ "replit": "no packaging format established here", "tabnine": "no packaging format established here; vendor documentation is unreachable from this environment", "windsurf": "vendor documentation unreachable from the environment this was written in", - "zed": "no packaging format established here" + "zed": "no packaging format established here", + "kilo_code": "plugins, skills and agents provably exist (.kilo/plugin/, .kilo/skills/ and .kilo/agent/ per https://kilo.ai/docs, read 2026-10-11) but a bundle layout for them was not established here", + "opencode": "plugins, skills, agents and commands provably exist (.opencode/plugins/ and .opencode/skills/ per https://opencode.ai/v2/docs, read 2026-10-11) but a bundle layout for them was not established here" } } diff --git a/src/agentseam/data/permissions-unrecorded.json b/src/agentseam/data/permissions-unrecorded.json index e2f523c..cb4ad66 100644 --- a/src/agentseam/data/permissions-unrecorded.json +++ b/src/agentseam/data/permissions-unrecorded.json @@ -10,5 +10,7 @@ "replit": "no permission model established here", "tabnine": "no permission model established here; vendor documentation is unreachable from this environment", "windsurf": "vendor documentation unreachable from the environment this was written in; no permission model claimed rather than one guessed", - "zed": "no permission model established here. As with Aider, this is independent of its lack of a hook surface" + "zed": "no permission model established here. As with Aider, this is independent of its lack of a hook surface", + "kilo_code": "a permission model provably exists -- its config schema (https://app.kilo.ai/config.json, read 2026-10-11) has a permission key taking allow, ask or deny per tool -- but it was not mapped here", + "opencode": "a permission model provably exists -- its config schema (https://opencode.ai/config.json, read 2026-10-11) has a permission key taking allow, ask or deny per tool -- but it was not mapped here" } diff --git a/src/agentseam/data/vendor-releases.json b/src/agentseam/data/vendor-releases.json index 8f0db93..f0be15a 100644 --- a/src/agentseam/data/vendor-releases.json +++ b/src/agentseam/data/vendor-releases.json @@ -50,10 +50,20 @@ "kind": null, "note": "JetBrains plugin marketplace. Feed exists but is not yet wired here." }, + "kilo_code": { + "kind": "npm", + "id": "@kilocode/cli", + "note": "The Kilo CLI. Resolved on 2026-10-11 to 7.8.8. The VS Code extension is marketplace-only; the docs read say they apply to both." + }, "kimi_code": { "kind": null, "note": "No confirmed release feed. Manual check." }, + "opencode": { + "kind": "npm", + "id": "@opencode/cli", + "note": "OpenCode v2. Resolved on 2026-10-11 to 2.0.26. The v1 line still publishes as opencode-ai (1.18.35 on 2026-10-11); this row was read against both." + }, "replit": { "kind": null, "note": "Hosted; see devin." diff --git a/src/agentseam/instructions.py b/src/agentseam/instructions.py index 494e491..3732b35 100644 --- a/src/agentseam/instructions.py +++ b/src/agentseam/instructions.py @@ -31,6 +31,8 @@ "devin": {"files": [".devin/README.md"], "shared": False, "imports": None}, "grok": {"files": [".grok/GROK.md"], "shared": False, "imports": None}, "kimi_code": {"files": [".kimi-code/AGENTS.md"], "shared": True, "imports": None}, + "opencode": {"files": ["AGENTS.md"], "shared": True, "imports": None}, + "kilo_code": {"files": ["AGENTS.md"], "shared": True, "imports": None}, "replit": {"files": ["replit.md"], "shared": False, "imports": None}, "tabnine": {"files": ["guidelines.md"], "shared": False, "imports": None}, "antigravity": {"files": [".agents/rules/agentseam.md"], "shared": False, "imports": None}, diff --git a/tests/test_instructions.py b/tests/test_instructions.py index bf422cc..94fb0ce 100644 --- a/tests/test_instructions.py +++ b/tests/test_instructions.py @@ -105,9 +105,9 @@ def test_nested_paths_are_created(tmp_path): def test_the_readme_arithmetic_cannot_drift(): - """README says "16 agents reached with 9 files written". Pin it to the data.""" + """README's "agents reached with 9 files written" arithmetic, pinned to the data.""" p = I.plan(I.agents(), repo_root=".") agents_reached = len(p["covered"]) + len(p["per_agent"]) files_written = (1 if p["shared"] else 0) + len(p["per_agent"]) - assert agents_reached == len(I.INSTRUCTION_FILES) == 16 + assert agents_reached == len(I.INSTRUCTION_FILES) == 18 assert files_written == 9