@event4u/agent-config 8.3.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.
@@ -9,7 +9,7 @@
9
9
  "homepage": "https://github.com/event4u-app/agent-config#readme",
10
10
  "name": "@event4u/agent-config",
11
11
  "repository": "https://github.com/event4u-app/agent-config",
12
- "version": "8.3.0"
12
+ "version": "8.4.0"
13
13
  },
14
14
  "registries": [
15
15
  {
@@ -0,0 +1,103 @@
1
+ # Surface Matrix — per-tool canonical-surface contract
2
+
3
+ > Machine-checked inventory of which install surface is canonical per tool,
4
+ > which alternates are legitimate, what counts as a duplicate surface, and
5
+ > how a duplicate converges. One data file replaces 23 hand-maintained
6
+ > special cases (council Q3, 2026-07-07 — see
7
+ > `agents/settings/contexts/claude-code-single-surface-decision.md` for the
8
+ > parent decision).
9
+
10
+ ## The file
11
+
12
+ `src/config/surface-matrix.yml` — ships in the npm package, resolved at
13
+ runtime relative to the package root (works from both the tsx dev path and
14
+ the bundled CLI).
15
+
16
+ ```yaml
17
+ schema_version: 1
18
+ tools:
19
+ <tool-id>: # must exist in install.ts::USER_SCOPE_PATHS
20
+ surface: projection | plugin | bundles | export-only
21
+ scope_path: "~/..." # must equal USER_SCOPE_PATHS[tool-id]
22
+ hooks: managed-settings-block | settings-hooks-opt-in | plugin | none
23
+ alternates: # optional — legitimate secondary surfaces
24
+ - id: <slug>
25
+ role: <why it is legitimate>
26
+ detail: <prose>
27
+ duplicate: # optional — the duplicate-surface class
28
+ description: <prose>
29
+ detect:
30
+ all_of: [<path>, …] # ~/ = user scope, ./ = package-relative;
31
+ # ALL present ⇒ duplicate surface exists
32
+ # OR, when suspected but unverified:
33
+ pending_evidence: <prose + pointer to the evidence gate>
34
+ converge: # required when detect is defined
35
+ action: <slug>
36
+ command: "<copy-paste fix>"
37
+ reaps: [<path>, …] # package-tagged locations converge may remove
38
+ notes: <provenance>
39
+ ```
40
+
41
+ ## Semantics
42
+
43
+ - **`surface`** — `projection` (installer writes content into the user
44
+ scope path; that projection is canonical), `plugin` (the tool's own
45
+ plugin channel is canonical — e.g. Copilot, where no user-scope
46
+ projection exists), `bundles` (manual import artifacts, e.g.
47
+ Claude Desktop ZIPs), `export-only` (config/marker export, no content
48
+ tree).
49
+ - **`duplicate.detect.all_of`** — existence checks only, never content
50
+ reads. All paths present ⇒ the duplicate class is live. Tools without a
51
+ `detect` block are never flagged.
52
+ - **`pending_evidence`** — documents a *suspected* class that MUST NOT be
53
+ acted on (doctor ignores it, converge refuses it) until an evidence gate
54
+ defines real detect paths. Current example: Augment
55
+ (`agents/settings/contexts/augment-surface-parity.md`).
56
+ - **`converge`** — the consented cleanup. `converge.reaps` is the
57
+ exhaustive allowlist of what `agent-config converge` may remove for this
58
+ tool; anything outside it is refused (hard floor: never user-authored
59
+ files).
60
+
61
+ ## Consumers
62
+
63
+ | Consumer | What it reads | Behavior |
64
+ |---|---|---|
65
+ | `agent-config doctor` (`surface-state` check) | `duplicate.detect.all_of` | Existence-checks every declared duplicate class; `fail` names the tool + the `converge.command` as copy-paste remedy. The legacy `claude-plugin` check stays as the named first consumer with richer version diagnostics. |
66
+ | `agent-config converge` (+ `upgrade --converge`) | `converge.*` | Performs the per-tool cleanup, only on matrix-declared, package-tagged paths (`converge.reaps`), after consent (`install.auto_converge` or interactive y/N). |
67
+ | `dispatch:hook` `surface-probe` concern | `duplicate.detect.all_of` | Once-per-day SessionStart existence probe; one-line nudge naming the duplicate + the converge command. Fail-open, never blocking. |
68
+ | CI (`task lint-surface-matrix` → `src/scripts/lint_surface_matrix.ts`) | whole file | Set equality with `USER_SCOPE_PATHS`, scope-path drift, enum validity, detect-path resolution, converge-command presence, plugin-id drift guard. |
69
+
70
+ ## Onboarding a new tool
71
+
72
+ 1. Add the tool to `install.ts::USER_SCOPE_PATHS` (and `SCOPE_SUPPORT`,
73
+ deploy sources) as usual.
74
+ 2. Add the matrix entry in the same commit — `lint-surface-matrix` fails
75
+ the build on a missing entry (that is the point: no tool ships without
76
+ a declared canonical surface).
77
+ 3. Default shape for a plain projection with no plugin channel:
78
+ `surface: projection`, `hooks: none`, no `duplicate` block.
79
+ 4. Only add a `duplicate` block when a second install channel actually
80
+ exists for the tool — and only add `detect.all_of` once the class has
81
+ been reproduced on a real setup (evidence gate; until then use
82
+ `pending_evidence`).
83
+
84
+ ## Consent model (converge)
85
+
86
+ - First `agent-config converge` run persists `install.auto_converge: true`
87
+ into the **global** settings file
88
+ (`~/.event4u/agent-config/agent-settings.yml`). The key is read directly
89
+ by the CLI (converge/upgrade); it is intentionally NOT part of the
90
+ `MERGEABLE_KEYS` whitelist — it never merges into project-level agent
91
+ settings and never reaches session context.
92
+ - Plain `upgrade` without the key keeps the print-only prompt (no silent
93
+ mutation of a user-owned surface — council Q2, 2026-07-07).
94
+ - `converge --dry-run` prints the exact actions without touching anything.
95
+
96
+ ## See also
97
+
98
+ - `agents/settings/contexts/claude-code-single-surface-decision.md` —
99
+ parent decision (single surface for Claude Code).
100
+ - `agents/settings/contexts/augment-surface-parity.md` — the Augment
101
+ evidence gate that keeps its duplicate class `pending_evidence`.
102
+ - `docs/contracts/skill-distribution-channels.md` — canonical-channel
103
+ contract the matrix operationalizes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "8.3.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,
@@ -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).