@event4u/agent-config 8.2.0 → 8.4.0

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.
Files changed (55) hide show
  1. package/.claude-plugin/marketplace.json +4 -426
  2. package/.claude-plugin/skills/install-agent-config/SKILL.md +32 -0
  3. package/CHANGELOG.md +57 -0
  4. package/MIGRATION.md +18 -0
  5. package/README.md +86 -3
  6. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  7. package/dist/cli/registry.js +1 -0
  8. package/dist/cli/registry.js.map +1 -1
  9. package/dist/discovery/deprecation-report.md +1 -1
  10. package/dist/discovery/discovery-manifest.json +1 -1
  11. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  12. package/dist/discovery/discovery-manifest.summary.md +1 -1
  13. package/dist/discovery/orphan-report.md +1 -1
  14. package/dist/discovery/packs.json +1 -1
  15. package/dist/discovery/trust-report.md +1 -1
  16. package/dist/discovery/workspaces.json +1 -1
  17. package/dist/install/install.mjs +586 -386
  18. package/dist/mcp/registry-manifest.json +2 -2
  19. package/docs/contracts/CHANGELOG-conventions.md +8 -5
  20. package/docs/contracts/branch-protection-policy.md +14 -5
  21. package/docs/contracts/mcp-phase-1-scope.md +75 -0
  22. package/docs/contracts/mcp-tool-inventory.md +22 -15
  23. package/docs/contracts/release-pr-gating.md +22 -11
  24. package/docs/contracts/surface-matrix.md +103 -0
  25. package/docs/decisions/ADR-111-canonical-glama-listing.md +97 -0
  26. package/docs/decisions/ADR-112-stdio-lite-stays-read-only.md +92 -0
  27. package/docs/decisions/ADR-113-ci-native-release-label-trigger.md +201 -0
  28. package/docs/decisions/INDEX.md +3 -0
  29. package/docs/distribution/registry-submissions.md +1 -1
  30. package/docs/getting-started.md +8 -6
  31. package/docs/installation.md +13 -14
  32. package/docs/mcp-server.md +32 -20
  33. package/docs/setup/mcp-cloud-endpoints.md +9 -2
  34. package/package.json +2 -2
  35. package/src/config/surface-matrix.yml +213 -0
  36. package/src/scripts/_cli/cmd_converge.ts +399 -0
  37. package/src/scripts/_cli/cmd_doctor.ts +203 -9
  38. package/src/scripts/_cli/cmd_uninstall.ts +22 -0
  39. package/src/scripts/_cli/cmd_upgrade.ts +101 -16
  40. package/src/scripts/_dispatch.bash +13 -0
  41. package/src/scripts/_lib/claude_settings_hooks.ts +251 -0
  42. package/src/scripts/condense.ts +74 -65
  43. package/src/scripts/hook_manifest.yaml +16 -7
  44. package/src/scripts/install +23 -4
  45. package/src/scripts/install.ts +30 -0
  46. package/src/scripts/lint_glama_drift.ts +75 -0
  47. package/src/scripts/lint_marketplace.ts +54 -56
  48. package/src/scripts/lint_surface_matrix.ts +200 -0
  49. package/src/scripts/mcp_exec/safety_envelope.ts +105 -0
  50. package/src/scripts/mcp_registry_submit.sh +14 -3
  51. package/src/scripts/mcp_server/__main__.ts +6 -8
  52. package/src/scripts/mcp_server/consumer_tool_catalog.json +78 -3
  53. package/src/scripts/mcp_server/tools.ts +731 -0
  54. package/src/scripts/release.ts +203 -39
  55. package/src/scripts/surface_probe_hook.ts +231 -0
@@ -0,0 +1,201 @@
1
+ ---
2
+ adr: 113
3
+ status: accepted
4
+ date: 2026-07-08
5
+ decision: ci-native-release-label-trigger
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: road-to-ci-native-release · Phase 1
9
+ ---
10
+
11
+ # ADR-113 — CI-native release path, triggered by a `release` label on a merged PR
12
+
13
+ ## Status
14
+
15
+ **Accepted** · 2026-07-08.
16
+
17
+ ## Context
18
+
19
+ `task release` (`src/scripts/release.ts`) is a fully interactive, local
20
+ 9-step pipeline: preflight → plan → confirm → branch+bump → commit/push+PR →
21
+ wait for CI → merge → tag → GitHub Release. The back half is already CI
22
+ (`publish-npm.yml`, `cloud-release.yml`, `release-guard.yml` all trigger on
23
+ the pushed numeric tag), but a maintainer must run the front half from a
24
+ terminal. This ADR adds an unattended, CI-native entry point alongside
25
+ `task release` — not a replacement.
26
+
27
+ ## Decision
28
+
29
+ 1. **Trigger: a `release` / `release:major` / `release:minor` /
30
+ `release:patch` label on a PR, checked at merge time**
31
+ (`pull_request: types: [closed]`, job-guarded on `merged == true` +
32
+ an exact label match). `release` auto-detects the bump from
33
+ Conventional Commits since the last tag (same logic `task release`
34
+ uses); the `release:*` variants force the bump. `workflow_dispatch`
35
+ (with `bump` / `version` / `dry_run` / `resume` inputs) is the
36
+ manual/recovery entry for a release not tied to a PR merge.
37
+
38
+ 2. **The numeric `X.Y.Z` tag stays the pipeline's *output*, never its
39
+ input.** `publish-npm.yml`, `cloud-release.yml`, and
40
+ `release-guard.yml` all trigger on `push: tags:
41
+ [0-9]+.[0-9]+.[0-9]+` and assume the tagged commit already carries
42
+ the bumped `package.json` / `marketplace.json` / regenerated
43
+ projections. A tag-shaped trigger (hand-pushed numeric tag, or a
44
+ `cut-*` intent tag) was considered and rejected — see Alternatives.
45
+
46
+ 3. **One orchestration workflow (`release.yml`), not a prepare/finalize
47
+ split.** GitHub's `GITHUB_TOKEN` recursion guard means events caused
48
+ by the default token do not start new workflow runs (with narrow,
49
+ documented exceptions — see the bot-PR finding below). A
50
+ bot-auto-merged release PR would never trigger a separate
51
+ merge-listening "finalize" workflow. `release.yml` instead runs the
52
+ whole chain synchronously in one job, calling
53
+ `src/scripts/release.ts --ci` end-to-end — the exact same pipeline
54
+ `task release` runs locally, just non-interactively.
55
+
56
+ 4. **`release.ts` gains a `--ci` mode, not a rewrite.** `--ci` changes
57
+ exactly three things relative to the existing interactive path:
58
+ - the `gh`-auth preflight probe (`gh api repos/{slug} --jq .id`
59
+ instead of `gh api user --jq .login` — the default `GITHUB_TOKEN`
60
+ is an installation token and `gh api user` returns 403 for it even
61
+ when perfectly valid);
62
+ - a `nothing_to_release_ci` short-circuit (empty commits + no
63
+ explicit bump/version override → exit 0) so firing the label path
64
+ twice in a row is a clean no-op, not a spurious empty release;
65
+ - explicit post-release dispatch of `release-guard.yml`,
66
+ `publish-npm.yml`, and `cloud-release.yml` via their `tag` input,
67
+ because a `GITHUB_TOKEN`-pushed tag does not fire their
68
+ `push: tags:` trigger either.
69
+
70
+ Every other code path (bump inference, changelog-era rendering, the
71
+ 10-step `execute()` sequence, all idempotent-resume probes) is
72
+ shared, unmodified, between `task release` and `release.yml`.
73
+
74
+ 5. **Token: `secrets.RELEASE_PR_TOKEN` with a `GITHUB_TOKEN` fallback.**
75
+ `release.yml` uses `${{ secrets.RELEASE_PR_TOKEN || secrets.GITHUB_TOKEN
76
+ }}` for checkout, git push, and `gh` auth. See the bot-PR-approval
77
+ finding below for why this matters and why the fallback is safe to
78
+ ship without the secret configured.
79
+
80
+ ## Finding — bot-created PRs need a manual "Approve workflows to run" click (no PAT)
81
+
82
+ Verified against GitHub's own changelog and community docs (2026-06-11,
83
+ ["Bot-created pull requests can run workflows if
84
+ approved"](https://github.blog/changelog/2026-06-11-bot-created-pull-requests-can-run-workflows-if-approved/)):
85
+ when a workflow uses the default `GITHUB_TOKEN` to open or update a PR,
86
+ the resulting `pull_request` events (`opened` / `synchronize` /
87
+ `reopened`) DO create workflow runs for other `pull_request`-triggered
88
+ workflows — but those runs sit in an **approval-required** state until a
89
+ repo collaborator with write access clicks **Approve workflows to run**
90
+ in the PR's merge box. This is a deliberate GitHub security control
91
+ (distinct from, but related to, the fork-first-time-contributor approval
92
+ gate), not a bug in this design.
93
+
94
+ This repo's branch-protection ruleset (verified live via `gh api
95
+ repos/event4u-app/agent-config/rulesets/17749383`) requires
96
+ **zero** approving reviews (`required_approving_review_count: 0`) and
97
+ exactly **one** required status check, `Sync + Generate Tools
98
+ Consistency` (from `consistency.yml`, `pull_request`-triggered). That
99
+ check does not run automatically on a `GITHUB_TOKEN`-opened release PR
100
+ without the one-time approval click — so without `RELEASE_PR_TOKEN`, a
101
+ release via the label path pauses at "waiting for checks" until a
102
+ maintainer approves the run once per release.
103
+
104
+ **Accepted as the default**, not worked around, because:
105
+
106
+ - It requires zero new secrets and zero change to repo-wide security
107
+ settings (disabling the org-wide first-time-contributor approval
108
+ setting would lower security posture for every fork/bot PR, not just
109
+ release PRs — out of proportion to this problem).
110
+ - A release is a production action; per this repo's own engineering
111
+ safety floor (`engineering-safety-floor` rule) and Hard-Floor stance
112
+ on deploys, a single human checkpoint before a release's own CI even
113
+ runs is arguably a feature, not friction.
114
+ - `RELEASE_PR_TOKEN` (a fine-grained PAT or GitHub App installation
115
+ token with `contents: write` + `pull-requests: write` on this repo)
116
+ removes the approval requirement entirely — documented as the
117
+ zero-friction upgrade path in `release.yml`'s header comment. Adding
118
+ it is a maintainer action, not part of this ADR.
119
+
120
+ ## Verified facts (not assumed)
121
+
122
+ - Branch protection ruleset `main protection` (id `17749383`):
123
+ `required_approving_review_count: 0`; required check =
124
+ `Sync + Generate Tools Consistency`; `bypass_actors` includes a
125
+ repository-role bypass. No human-review gate blocks a bot merge once
126
+ checks are green.
127
+ - `consistency.yml` triggers on `pull_request` with path filters that
128
+ match every file a release PR touches (`package.json`,
129
+ `.claude-plugin/marketplace.json`, `CHANGELOG.md`, `dist/agent-src/**`,
130
+ `.augment/**`) — the required check fires (subject to the approval
131
+ gate above), it is not silently skipped.
132
+ - No `RELEASE_PR_TOKEN`-shaped secret exists in the repo today (`gh
133
+ secret list`) — the fallback path is the one that ships by default.
134
+ - `softprops/action-gh-release@v2`'s `overwrite_files` input defaults to
135
+ `true` — re-attaching the same-named cloud-release assets on a
136
+ dispatch-chain re-run is idempotent by construction, no extra guard
137
+ needed.
138
+ - `npm publish` hard-rejects re-publishing an existing version — added a
139
+ `npm view @event4u/agent-config@<tag> version` pre-check to
140
+ `publish-npm.yml` so a double-dispatch (native tag-push trigger racing
141
+ the explicit dispatch, when `RELEASE_PR_TOKEN` IS configured) is a
142
+ clean skip, not a red run.
143
+
144
+ ## Consequences
145
+
146
+ - Releasing needs exactly one human action: label a PR `release` (or a
147
+ `release:*` variant) and merge it. Without `RELEASE_PR_TOKEN`, one
148
+ additional "Approve workflows to run" click is needed once per
149
+ release on the auto-created release PR.
150
+ - `task release` is unaffected — same script, same flags, same tests.
151
+ It remains the interactive/local path and the documented fallback if
152
+ the CI path misbehaves.
153
+ - Three existing workflows (`release-guard.yml`, `publish-npm.yml`)
154
+ gained a `workflow_dispatch` input / idempotency guard respectively;
155
+ `cloud-release.yml` needed no change (already idempotent).
156
+ - A future maintainer who configures `RELEASE_PR_TOKEN` gets a fully
157
+ unattended release with zero code changes required — the fallback
158
+ expression already prefers it.
159
+
160
+ ## Alternatives considered
161
+
162
+ - **Hand-pushed numeric tag as the trigger.** Rejected: the tag-triggered
163
+ workflows require the tagged commit to already carry the bump: a
164
+ hand-pushed `X.Y.Z` on plain main fires them against the *un-bumped*
165
+ tree (red `release-guard`, wrong npm tarball), and the tag would then
166
+ have to be deleted and re-pushed onto the eventual bump-PR merge
167
+ commit — mutable tags are an anti-pattern (stale fetches, npm
168
+ provenance binds to the tag commit).
169
+ - **A `cut-*` intent tag** (`cut-X.Y.Z` / `cut-auto` / `cut-major` / …)
170
+ in a separate namespace from the numeric tags. Functionally workable
171
+ (does not collide with the publish/guard tag patterns), but the
172
+ release label keeps the intent visible on the PR itself — reviewable,
173
+ revocable pre-merge, no second git-tag vocabulary to teach.
174
+ - **`workflow_dispatch` as the sole/primary trigger**, no label. Loses
175
+ the "the intent to release lives on the PR, and is revocable until
176
+ merge" property that the label gives for free; kept as the
177
+ manual/recovery entry, not the primary path.
178
+ - **Prepare + finalize workflow split** (one workflow opens the release
179
+ PR, a second listens for its merge and finalizes). Needs a
180
+ `RELEASE_PR_TOKEN`-class token as a *hard* requirement — under plain
181
+ `GITHUB_TOKEN`, the bot-merged PR's `pull_request: closed` event is
182
+ the SAME kind of GITHUB_TOKEN-caused event subject to the same
183
+ approval/recursion nuance, and splitting the pipeline across two
184
+ workflow boundaries adds a second place idempotency can drift. The
185
+ single-workflow design collapses this into one synchronous run using
186
+ the already-battle-tested `execute()` sequence.
187
+ - **Disable the org-wide "require approval for first-time contributors"
188
+ setting** to remove the bot-PR approval gate without a PAT. Rejected:
189
+ it is an org-wide security posture change affecting every fork/bot PR
190
+ in the organization, not scoped to releases — disproportionate to
191
+ this problem; `RELEASE_PR_TOKEN` is the properly-scoped fix.
192
+
193
+ ## References
194
+
195
+ - `.github/workflows/release.yml` — the orchestration workflow.
196
+ - `src/scripts/release.ts` — the shared pipeline (`--ci` mode).
197
+ - `docs/contracts/release-pr-gating.md`,
198
+ `docs/contracts/branch-protection-policy.md` — release-PR shape and
199
+ required-check contracts this design must keep satisfying.
200
+ - [GitHub Changelog — Bot-created pull requests can run workflows if
201
+ approved (2026-06-11)](https://github.blog/changelog/2026-06-11-bot-created-pull-requests-can-run-workflows-if-approved/)
@@ -114,6 +114,9 @@ _Auto-generated by `scripts/adr/regenerate_index.py`. Do not edit._
114
114
  | [ADR-108](ADR-108-open-source-forever-no-commercial-tier.md) | Open Source Forever No Commercial Tier | accepted | 2026-06-24 | — |
115
115
  | [ADR-109](ADR-109-subagent-v1-contract.md) | Subagent V1 Contract | accepted | 2026-07-04 | — |
116
116
  | [ADR-110](ADR-110-discipline-profile-resolution-locus.md) | Discipline Profile Resolution Locus | accepted | 2026-07-07 | — |
117
+ | [ADR-111](ADR-111-canonical-glama-listing.md) | Canonical Glama Listing | accepted | 2026-07-07 | — |
118
+ | [ADR-112](ADR-112-stdio-lite-stays-read-only.md) | Stdio Lite Stays Read Only | accepted | 2026-07-07 | — |
119
+ | [ADR-113](ADR-113-ci-native-release-label-trigger.md) | Ci Native Release Label Trigger | accepted | 2026-07-08 | — |
117
120
  | [ADR-200](ADR-200-python-to-typescript-migration.md) | Python To Typescript Migration | accepted | 2026-06-11 | — |
118
121
 
119
122
  ## Unnumbered (legacy)
@@ -34,7 +34,7 @@ the submission shape evolves; this file accumulates history.
34
34
 
35
35
  | # | Registry | Submission shape | Status | PR / form URL | Date | Maintainer notes |
36
36
  |---|---|---|---|---|---|---|
37
- | 1 | `punkpeye/awesome-mcp-servers` | One-line entry under agent-tooling section; PR via `scripts/mcp_registry_submit.sh` | `pending` | — | — | Scaffold ready. Run `bash scripts/mcp_registry_submit.sh --dry-run` once before live; the live path needs the maintainer's GitHub identity. |
37
+ | 1 | `punkpeye/awesome-mcp-servers` | One-line entry under agent-tooling section; PR via `scripts/mcp_registry_submit.sh` | `submitted` | <https://github.com/punkpeye/awesome-mcp-servers/pull/9607> | 2026-07-07 | PR opened via the submit script (two script bugs fixed on the way: idempotent upstream remote, `--head OWNER:branch` format). Awaiting upstream review. |
38
38
  | 2 | `mcp.so` | Directory form submission (web form, no programmatic API) | `pending` | — | — | Form URL: <https://mcp.so/>. Submission shape: same one-line entry, paste into the form's `description` field. |
39
39
  | 3 | `mcpservers.org` | Directory form submission (web form, verify URL at submission time) | `pending` | — | — | Form URL: <https://mcpservers.org/>. Submission shape: one-line entry; check the site is live before posting. |
40
40
 
@@ -37,16 +37,18 @@ The suite is global-only (ADR-020) — refresh the global install and every
37
37
  project sees the new skills, rules, and hooks at once, no per-repo bump:
38
38
 
39
39
  ```bash
40
- agent-config upgrade # fetch + install the latest globally (binary + plugin)
41
- agent-config refresh --global # idempotent re-install, same version (root + plugin)
40
+ agent-config upgrade # fetch + install the latest globally (content + hooks)
41
+ agent-config refresh --global # idempotent re-install, same version
42
42
  agent-config refresh --project # refresh a project's minimal surface — bridge
43
43
  # marker, agents/overrides/, .gitignore (no wizard)
44
- agent-config doctor # PATH, binary↔plugin version drift, bridge presence
44
+ agent-config doctor # PATH, hook wiring, duplicate surfaces, bridge presence
45
45
  ```
46
46
 
47
- The Claude marketplace plugin updates on Claude Code's own cadence,
48
- independent of npm; `doctor` surfaces binary↔plugin drift so you know when to
49
- update the plugin from the marketplace.
47
+ Claude Code is single-surface: the file projection carries content AND the
48
+ managed hooks in `~/.claude/settings.json` — there is no marketplace plugin
49
+ to keep in sync anymore. A leftover plugin from an older install is flagged
50
+ by `doctor` as `claude-plugin: duplicate surface` (fix:
51
+ `claude plugin uninstall agent-config@event4u-agent-config`).
50
52
 
51
53
  ## Project CLI — `./agent-config`
52
54
 
@@ -413,25 +413,24 @@ This is additional to project-installed mode, not a replacement.
413
413
  auggie plugin install agent-config@event4u-agent-config
414
414
  ```
415
415
 
416
- ### Claude Code
416
+ ### Claude Code — plugin deprecated (single-surface model)
417
417
 
418
- Two equivalent paths — pick whichever surface you're already in:
418
+ **Do not install the marketplace plugin for Claude Code.** The npx/npm
419
+ global install (`npx -y @event4u/agent-config init`) is the single supported
420
+ surface: it deploys skills/commands/rules to `~/.claude/` **and** registers
421
+ the deterministic hooks in a managed `~/.claude/settings.json` block. The
422
+ plugin would only duplicate every skill/command listing while its git-SHA
423
+ snapshot silently lags each release.
419
424
 
420
- ```bash
421
- # From your shell (CLI)
422
- claude plugin install agent-config@event4u-agent-config
423
- ```
425
+ Already have the plugin from an earlier install?
424
426
 
425
- ```text
426
- # From inside Claude Code (slash command)
427
- /plugin marketplace add event4u-app/agent-config
428
- /plugin install agent-config@event4u-agent-config
427
+ ```bash
428
+ claude plugin uninstall agent-config@event4u-agent-config
429
429
  ```
430
430
 
431
- The slash-command path is the canonical Claude Code Plugin Marketplace
432
- flow ([reference](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces)).
433
- It pulls the repo via git-clone and reads the skills directly from
434
- `.claude/skills/` — no separate ZIP download.
431
+ Hooks keep firing after removal (they live in `settings.json`, not the
432
+ plugin); `agent-config doctor` verifies via the `hook-wiring` check and
433
+ flags a leftover plugin as `claude-plugin: duplicate surface`.
435
434
 
436
435
  ### Copilot CLI
437
436
 
@@ -1,6 +1,6 @@
1
1
  # MCP Server
2
2
 
3
- > Status: **experimental** — Phase 1 + 2 + 3 shipped. No `tools/*` primitive yet (Phase 4, deferred behind a design call). Promotion to **beta** is gated on the six criteria in [`docs/contracts/mcp-beta-criteria.md`](contracts/mcp-beta-criteria.md); current gate status: `./agent-config doctor --check mcp-beta-readiness` (Phase 3 of `road-to-surface-discipline.md`).
3
+ > Status: **experimental** — read-only prompts + resources plus a growing `tools/*` surface (stub-by-default: every catalogued tool name resolves, unimplemented ones return a structured `not_implemented` envelope). Tool coverage and the write/exec unlock path are governed by [`agents/settings/contexts/mcp-coverage-strategy.md`](../agents/settings/contexts/mcp-coverage-strategy.md). Promotion to **beta** is gated on the six criteria in [`docs/contracts/mcp-beta-criteria.md`](contracts/mcp-beta-criteria.md); current gate status: `./agent-config doctor --check mcp-beta-readiness`.
4
4
 
5
5
  `agent-config` ships a built-in [Model Context Protocol](https://modelcontextprotocol.io)
6
6
  server that exposes the package's read-only governance surface to MCP-aware
@@ -20,22 +20,30 @@ coexist:
20
20
  [`docs/contracts/mcp-cloud-scope.md`](contracts/mcp-cloud-scope.md).
21
21
  Wire-parity-checked against the local stdio kernel on every release.
22
22
 
23
- The MCP server **never executes engine code, never writes files, never spawns
24
- shells**. It is a read-only instructional surface — see
25
- [`docs/contracts/mcp-phase-1-scope.md`](contracts/mcp-phase-1-scope.md).
23
+ Every implemented tool is either read-only or writes only inside the
24
+ consumer's project tree via a path-guard (`_validateInTreePath`) —
25
+ [`docs/contracts/mcp-phase-1-scope.md`](contracts/mcp-phase-1-scope.md)
26
+ is the scope contract; exec-tier tools (shell-spawning) and network-tier
27
+ tools (billable) are gated behind
28
+ [`agents/settings/contexts/mcp-coverage-strategy.md`](../agents/settings/contexts/mcp-coverage-strategy.md).
26
29
 
27
30
  ## What the server exposes
28
31
 
29
- | Primitive | URIs | Source | Count (this package) |
30
- |---|---|---|---|
31
- | `prompts/list` + `prompts/get` | `skill.<name>`, `command.<name>` | `dist/agent-src/skills/`, `dist/agent-src/commands/` | 174 skills + 104 commands |
32
- | `resources/list` + `resources/read` | `rule://<stem>` | `dist/agent-src/rules/` | 60 rules |
33
- | ↳ | `guideline://<relpath>` | `docs/guidelines/` | 69 guidelines |
34
- | ↳ | `context://<relpath>` | `dist/agent-src/contexts/` | 31 contexts |
32
+ | Primitive | URIs | Source |
33
+ |---|---|---|
34
+ | `prompts/list` + `prompts/get` | `skill.<name>`, `command.<name>` | `dist/agent-src/skills/`, `dist/agent-src/commands/` |
35
+ | `resources/list` + `resources/read` | `rule://<stem>` | `dist/agent-src/rules/` |
36
+ | ↳ | `guideline://<relpath>` | `docs/guidelines/` |
37
+ | ↳ | `context://<relpath>` | `dist/agent-src/contexts/` |
38
+ | `tools/list` + `tools/call` | see [`agents/settings/contexts/mcp-tool-tier-map.md`](../agents/settings/contexts/mcp-tool-tier-map.md) for the full candidate surface | `src/scripts/mcp_server/consumer_tool_catalog.json` |
35
39
 
36
40
  All resources are served with `mimeType: text/markdown`. Pagination is
37
41
  cursor-based (default page size: 100). Hot-reload triggers automatically on
38
42
  file mtime changes — edit a rule, reissue `resources/list`, see the update.
43
+ Exact prompt/resource/tool counts drift with every content change — the smoke
44
+ test below reports the live numbers rather than a number pinned in prose.
45
+ _Last verified boot (`task mcp:glama-test`, 2026-07-07): 430 prompts / 232
46
+ resources / 27 tools (18 implemented, 9 stubs — post write/exec cut)._
39
47
 
40
48
  ## Setup — one-line install
41
49
 
@@ -60,10 +68,9 @@ task mcp:run # maintainer / dev repo
60
68
  ./agent-config mcp:run # consumer projects
61
69
  ```
62
70
 
63
- Both forms launch the TypeScript MCP server over stdio via `tsx`. Use these for
64
-
65
- (Claude Desktop, Cursor, Zed, Continue) launch the server themselves via
66
- the config snippets below.
71
+ Both forms launch the TypeScript MCP server over stdio via `tsx`. Use these
72
+ for a manual smoke test — MCP clients (Claude Desktop, Cursor, Zed, Continue)
73
+ launch the server themselves via the config snippets below.
67
74
 
68
75
  ## Client configuration
69
76
 
@@ -140,8 +147,9 @@ boots cleanly:
140
147
 
141
148
  ```bash
142
149
  ./agent-config mcp:run < /dev/null
143
- # Expect stderr: "mcp-server: loaded N prompts (0 warnings)" and
144
- # "mcp-server: loaded 160 resources (0 warnings)"
150
+ # Expect stderr: "mcp-server: loaded N prompts (0 warnings)",
151
+ # "mcp-server: loaded N resources (0 warnings)", and
152
+ # "mcp-server: registered N tools (N implemented, N stubs): [...]"
145
153
  ```
146
154
 
147
155
  ## Troubleshooting
@@ -155,9 +163,13 @@ boots cleanly:
155
163
  ## Scope
156
164
 
157
165
  - **In scope:** read-only prompts + resources, pagination, hot-reload, stdio
158
- transport, free-tier client compatibility.
159
- - **Out of scope (Phase 4+):** `tools/*` primitive, SSE / HTTP transport,
160
- cloud distribution, signed payloads. Tracked in
161
- [`agents/roadmaps/road-to-mcp-server.md`](../agents/roadmaps/road-to-mcp-server.md).
166
+ transport, free-tier client compatibility, a growing read-only and
167
+ in-tree-write `tools/*` surface (see
168
+ [`agents/settings/contexts/mcp-tool-tier-map.md`](../agents/settings/contexts/mcp-tool-tier-map.md)).
169
+ - **Out of scope:** SSE / native HTTP transport for this server (the
170
+ Cloudflare Worker above is the HTTP bridge instead), shell-exec and
171
+ network-tier tools until the safety envelope in
172
+ [`agents/settings/contexts/mcp-coverage-strategy.md`](../agents/settings/contexts/mcp-coverage-strategy.md)
173
+ ships, signed payloads.
162
174
 
163
175
  ← [Architecture](architecture.md) · [MCP config generation (consumer side)](mcp.md)
@@ -19,8 +19,15 @@ resources. `tools/list` returns two **deprecated stubs**
19
19
  successors; `tools/call` against either returns `isError=true`. No
20
20
  script execution, no FS access, no shell.
21
21
 
22
- Full power — the ~112 Python scripts (linters, audits, `task ci`,
23
- work-engine hooks) — requires the local install. See
22
+ Full power — the implemented tool surface (18 tools as of the 2026-07-07
23
+ write/exec cut: memory, roadmap, capabilities, doctor/conformance,
24
+ telemetry, council-estimate, and the vitest `run_tests` pilot) — requires
25
+ the **local kernel server** (`agent-config mcp:run` on a repo checkout).
26
+ `implemented_on` stays `["stdio"]` for every execution tool, permanently:
27
+ the Worker has no kernel runtime endpoint — it serves a release-pinned
28
+ content snapshot from R2, so there is no process that could run the
29
+ handlers, and the A0-cloud contract's no-execution boundary is a design
30
+ invariant, not a backlog item. See
24
31
  [`../contracts/mcp-cloud-scope.md`](../contracts/mcp-cloud-scope.md)
25
32
  for the execution-safety boundary and the Phase-7-DEFERRED gate that
26
33
  governs any future tool restoration.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "8.2.0",
3
+ "version": "8.4.0",
4
4
  "description": "Universal AI Agent OS — audited skills, governance rules, commands, and templates for AI coding tools (Claude Code, Cursor, Windsurf, Copilot).",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "scripts": {
58
58
  "build:cli": "tsc -p tsconfig.json && chmod +x dist/cli/agent-config.js",
59
- "build:install-bundle": "esbuild src/scripts/install.ts --bundle --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --outfile=dist/install/install.mjs",
59
+ "build:install-bundle": "esbuild src/scripts/install.ts --bundle --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --outfile=dist/install/install.mjs --banner:js=\"import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);\"",
60
60
  "build:ui": "vite build",
61
61
  "build:discovery": "./scripts-run src/scripts/build_discovery_manifest --write --strict",
62
62
  "build:mcp-manifest": "./scripts-run src/scripts/build_mcp_registry_manifest --write --strict",
@@ -0,0 +1,213 @@
1
+ # Surface Matrix — machine-checked per-tool canonical-surface declarations.
2
+ #
3
+ # One entry per tool in install.ts::USER_SCOPE_PATHS (set equality enforced by
4
+ # lint_surface_matrix). Consumed by:
5
+ # - `agent-config doctor` (surface-state check — flags duplicate surfaces)
6
+ # - `agent-config converge` (per-tool cleanup actions)
7
+ # - CI (src/scripts/lint_surface_matrix.ts — coverage + drift)
8
+ # Contract: docs/contracts/surface-matrix.md
9
+ #
10
+ # Fields per tool:
11
+ # surface: projection | plugin | bundles | export-only
12
+ # projection = installer writes content files into the user
13
+ # scope path; that projection is canonical
14
+ # plugin = the tool's own plugin/marketplace channel is
15
+ # canonical (no user-scope projection exists)
16
+ # bundles = manual import artifacts (ZIPs); no filesystem
17
+ # discovery convention
18
+ # export-only = a config/marker export; no content tree
19
+ # hooks: managed-settings-block | settings-hooks-opt-in | plugin | none
20
+ # alternates: legitimate secondary surfaces (NOT duplicates), with role
21
+ # duplicate: the duplicate-surface definition — `detect` paths that, when
22
+ # ALL present, mean the tool has a duplicate content surface.
23
+ # Only tools with a defined duplicate class are checked by
24
+ # doctor/converge. `pending-evidence` documents a suspected but
25
+ # unverified class (never acted on).
26
+ # converge: the consented cleanup action for the duplicate class
27
+ # notes: provenance — where the classification comes from
28
+
29
+ schema_version: 1
30
+
31
+ tools:
32
+ claude-code:
33
+ surface: projection
34
+ scope_path: "~/.claude/"
35
+ hooks: managed-settings-block
36
+ alternates:
37
+ - id: marketplace-plugin
38
+ role: bootstrap-shim
39
+ detail: >-
40
+ hooks/hooks.json (byte-identical to the managed settings block, so
41
+ Claude Code dedupes) plus one install-pointer skill; zero content
42
+ skills by construction (lint_marketplace enforces).
43
+ duplicate:
44
+ description: >-
45
+ A pre-shim marketplace plugin snapshot (content skills) installed next
46
+ to the ~/.claude/ file projection — every skill/command lists twice
47
+ and the snapshot rots silently.
48
+ detect:
49
+ all_of:
50
+ - "~/.claude/skills"
51
+ - "~/.claude/plugins/cache/event4u-agent-config"
52
+ converge:
53
+ action: plugin-uninstall
54
+ command: "claude plugin uninstall agent-config@event4u-agent-config"
55
+ reaps:
56
+ - "~/.claude/plugins/cache/event4u-agent-config"
57
+ notes: >-
58
+ Single-surface decision (agents/settings/contexts/
59
+ claude-code-single-surface-decision.md); shim invariant verified via
60
+ scratch marketplace install, 2026-07-08.
61
+
62
+ augment:
63
+ surface: projection
64
+ scope_path: "~/.augment/"
65
+ hooks: settings-hooks-opt-in
66
+ alternates:
67
+ - id: augment-plugin
68
+ role: dormant
69
+ detail: >-
70
+ .augment-plugin/ manifest-only wrapper (source: "."). Marketplace
71
+ feature is account-gated ("Plugin marketplace feature is not
72
+ enabled for your account") — dual install unreproducible today.
73
+ duplicate:
74
+ pending_evidence: >-
75
+ Suspected duplicate class analogous to Claude Code IF Augment enables
76
+ the plugin marketplace broadly. NOT acted on — evidence gate
77
+ agents/settings/contexts/augment-surface-parity.md (2026-07-08) could
78
+ not reproduce; re-run the gate before defining detect paths.
79
+ notes: >-
80
+ Projection-primary on evidence. NO retirement move without a fresh
81
+ parity gate (roadmap Phase 0 rule).
82
+
83
+ copilot:
84
+ surface: plugin
85
+ scope_path: "~/.copilot/"
86
+ hooks: plugin
87
+ notes: >-
88
+ Plugin-primary by design — no user-scope content projection exists for
89
+ Copilot; the project bridge is .github/plugin/marketplace.json. The
90
+ plugin is the correct surface here, not a duplicate (council Q3,
91
+ 2026-07-07). Do not "fix".
92
+
93
+ claude-desktop:
94
+ surface: bundles
95
+ scope_path: "~/Library/Application Support/Claude/"
96
+ hooks: none
97
+ notes: >-
98
+ Skill ZIPs imported manually via Customize → Skills; no filesystem
99
+ discovery, no plugin channel — no dual-surface class (Phase 0 survey).
100
+
101
+ cursor:
102
+ surface: projection
103
+ scope_path: "~/.cursor/"
104
+ hooks: none
105
+ notes: Plain projection (rules/commands/personas); no plugin channel.
106
+
107
+ windsurf:
108
+ surface: projection
109
+ scope_path: "~/.codeium/windsurf/"
110
+ hooks: none
111
+ notes: Plain projection (rules only); no plugin channel.
112
+
113
+ cline:
114
+ surface: projection
115
+ scope_path: "~/Documents/Cline/Rules/"
116
+ hooks: none
117
+ notes: Plain projection (rules only); no plugin channel.
118
+
119
+ gemini-cli:
120
+ surface: projection
121
+ scope_path: "~/.gemini/"
122
+ hooks: none
123
+ notes: Plain projection (skill bundle); no plugin channel (Phase 0 survey).
124
+
125
+ codex:
126
+ surface: projection
127
+ scope_path: "~/.codex/"
128
+ hooks: none
129
+ notes: Plain projection (skill bundle); no plugin channel (Phase 0 survey).
130
+
131
+ continue:
132
+ surface: projection
133
+ scope_path: "~/.continue/"
134
+ hooks: none
135
+ notes: Plain projection (skill bundle); no plugin channel (Phase 0 survey).
136
+
137
+ droid:
138
+ surface: projection
139
+ scope_path: "~/.factory/"
140
+ hooks: none
141
+ notes: Plain projection (skill bundle); no plugin channel (Phase 0 survey).
142
+
143
+ roocode:
144
+ surface: projection
145
+ scope_path: "~/.roo/"
146
+ hooks: none
147
+ notes: Plain projection (skill bundle); no plugin channel.
148
+
149
+ kilocode:
150
+ surface: projection
151
+ scope_path: "~/.kilocode/"
152
+ hooks: none
153
+ notes: Plain projection (skill bundle); no plugin channel.
154
+
155
+ kiro:
156
+ surface: projection
157
+ scope_path: "~/.kiro/"
158
+ hooks: none
159
+ notes: Plain projection (rules/steering/personas); no plugin channel.
160
+
161
+ qoder:
162
+ surface: projection
163
+ scope_path: "~/.qoder/"
164
+ hooks: none
165
+ notes: Plain projection (skill bundle); no plugin channel.
166
+
167
+ opencode:
168
+ surface: projection
169
+ scope_path: "~/.opencode/"
170
+ hooks: none
171
+ notes: Plain projection (skill bundle); no plugin channel.
172
+
173
+ trae:
174
+ surface: projection
175
+ scope_path: "~/.trae/"
176
+ hooks: none
177
+ notes: Plain projection (skill bundle); no plugin channel.
178
+
179
+ antigravity:
180
+ surface: projection
181
+ scope_path: "~/.agents/"
182
+ hooks: none
183
+ notes: Plain projection (skill bundle); no plugin channel.
184
+
185
+ codebuddy:
186
+ surface: projection
187
+ scope_path: "~/.codebuddy/"
188
+ hooks: none
189
+ notes: Plain projection (skill bundle); no plugin channel.
190
+
191
+ warp:
192
+ surface: projection
193
+ scope_path: "~/.warp/"
194
+ hooks: none
195
+ notes: Plain projection (skill bundle); no plugin channel.
196
+
197
+ aider:
198
+ surface: export-only
199
+ scope_path: "~/.aider.conf.yml"
200
+ hooks: none
201
+ notes: Config-file export; no content tree, no plugin channel (Phase 0 survey).
202
+
203
+ zed:
204
+ surface: export-only
205
+ scope_path: "~/.config/zed/"
206
+ hooks: none
207
+ notes: Export/marker only; no plugin channel (Phase 0 survey).
208
+
209
+ jetbrains:
210
+ surface: export-only
211
+ scope_path: "~/.config/JetBrains/"
212
+ hooks: none
213
+ notes: Export/marker only; no plugin channel (Phase 0 survey).