agentbundle 0.2.0__py3-none-any.whl

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 (99) hide show
  1. agentbundle/__init__.py +14 -0
  2. agentbundle/__main__.py +5 -0
  3. agentbundle/_data/adapter.schema.json +270 -0
  4. agentbundle/_data/adapter.toml +584 -0
  5. agentbundle/_data/install-marker.py +1099 -0
  6. agentbundle/_data/pack.schema.json +152 -0
  7. agentbundle/_data/plugin-manifest.derived.schema.json +33 -0
  8. agentbundle/_data/plugin-manifest.schema.json +18 -0
  9. agentbundle/build/__init__.py +206 -0
  10. agentbundle/build/__main__.py +8 -0
  11. agentbundle/build/adapter_root_bins.py +336 -0
  12. agentbundle/build/adapters/__init__.py +46 -0
  13. agentbundle/build/adapters/claude_code.py +142 -0
  14. agentbundle/build/adapters/codex.py +227 -0
  15. agentbundle/build/adapters/copilot.py +149 -0
  16. agentbundle/build/adapters/kiro.py +608 -0
  17. agentbundle/build/adapters/kiro_cli.py +53 -0
  18. agentbundle/build/adapters/kiro_ide.py +275 -0
  19. agentbundle/build/contract.py +20 -0
  20. agentbundle/build/lint_packs.py +555 -0
  21. agentbundle/build/main.py +596 -0
  22. agentbundle/build/phase_order.py +40 -0
  23. agentbundle/build/projections/__init__.py +13 -0
  24. agentbundle/build/projections/codex_agent_toml.py +232 -0
  25. agentbundle/build/projections/copilot_agent_md.py +206 -0
  26. agentbundle/build/projections/copilot_hooks_json.py +142 -0
  27. agentbundle/build/projections/direct_directory.py +41 -0
  28. agentbundle/build/projections/hook_id.py +27 -0
  29. agentbundle/build/projections/kiro_ide_hook.py +256 -0
  30. agentbundle/build/projections/merge_into_agent_json.py +264 -0
  31. agentbundle/build/projections/merge_json.py +58 -0
  32. agentbundle/build/projections/user_merge_json.py +324 -0
  33. agentbundle/build/scope_rails.py +728 -0
  34. agentbundle/build/self_host.py +1486 -0
  35. agentbundle/build/shared_libs.py +309 -0
  36. agentbundle/build/target_resolver.py +85 -0
  37. agentbundle/build/tests/__init__.py +0 -0
  38. agentbundle/build/tests/test_adapter_claude_code.py +275 -0
  39. agentbundle/build/tests/test_adapter_codex.py +699 -0
  40. agentbundle/build/tests/test_adapter_copilot.py +91 -0
  41. agentbundle/build/tests/test_adapter_kiro.py +449 -0
  42. agentbundle/build/tests/test_adapter_kiro_alias.py +105 -0
  43. agentbundle/build/tests/test_adapter_kiro_cli.py +102 -0
  44. agentbundle/build/tests/test_adapter_kiro_ide.py +173 -0
  45. agentbundle/build/tests/test_adapter_root_bins_projection.py +429 -0
  46. agentbundle/build/tests/test_build_ships_seeds.py +78 -0
  47. agentbundle/build/tests/test_contract.py +582 -0
  48. agentbundle/build/tests/test_contract_scope.py +224 -0
  49. agentbundle/build/tests/test_contract_v07.py +191 -0
  50. agentbundle/build/tests/test_contract_v08.py +230 -0
  51. agentbundle/build/tests/test_direct_directory_cleanup.py +65 -0
  52. agentbundle/build/tests/test_end_to_end_build.py +227 -0
  53. agentbundle/build/tests/test_lint_agents_md_legacy_block.py +135 -0
  54. agentbundle/build/tests/test_lint_agents_md_risk_block.py +116 -0
  55. agentbundle/build/tests/test_lint_packs.py +703 -0
  56. agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +176 -0
  57. agentbundle/build/tests/test_pack_schema.py +265 -0
  58. agentbundle/build/tests/test_pack_schema_allowed_adapters.py +258 -0
  59. agentbundle/build/tests/test_pack_schema_install.py +305 -0
  60. agentbundle/build/tests/test_pipeline.py +272 -0
  61. agentbundle/build/tests/test_plugin_manifest_schema.py +327 -0
  62. agentbundle/build/tests/test_projections_merge_json.py +148 -0
  63. agentbundle/build/tests/test_scope_rails.py +398 -0
  64. agentbundle/build/tests/test_security.py +97 -0
  65. agentbundle/build/tests/test_self_host_check.py +2100 -0
  66. agentbundle/build/tests/test_shared_libs_projection.py +415 -0
  67. agentbundle/build/tests/test_shipped_packs_v07_declarations.py +100 -0
  68. agentbundle/build/tests/test_shipped_packs_v08_declarations.py +80 -0
  69. agentbundle/build/tests/test_validate.py +250 -0
  70. agentbundle/build/validate.py +141 -0
  71. agentbundle/catalogue.py +164 -0
  72. agentbundle/cli.py +486 -0
  73. agentbundle/commands/__init__.py +5 -0
  74. agentbundle/commands/_common.py +174 -0
  75. agentbundle/commands/_drop_warning.py +329 -0
  76. agentbundle/commands/adapt.py +343 -0
  77. agentbundle/commands/config.py +125 -0
  78. agentbundle/commands/diff.py +211 -0
  79. agentbundle/commands/init_state.py +279 -0
  80. agentbundle/commands/install.py +3026 -0
  81. agentbundle/commands/list_packs.py +170 -0
  82. agentbundle/commands/list_targets.py +23 -0
  83. agentbundle/commands/reconcile.py +161 -0
  84. agentbundle/commands/render.py +165 -0
  85. agentbundle/commands/scaffold.py +69 -0
  86. agentbundle/commands/uninstall.py +294 -0
  87. agentbundle/commands/upgrade.py +699 -0
  88. agentbundle/commands/validate.py +688 -0
  89. agentbundle/config.py +747 -0
  90. agentbundle/render.py +123 -0
  91. agentbundle/safety.py +633 -0
  92. agentbundle/scope.py +319 -0
  93. agentbundle/user_config.py +284 -0
  94. agentbundle/version.py +49 -0
  95. agentbundle-0.2.0.dist-info/METADATA +37 -0
  96. agentbundle-0.2.0.dist-info/RECORD +99 -0
  97. agentbundle-0.2.0.dist-info/WHEEL +5 -0
  98. agentbundle-0.2.0.dist-info/entry_points.txt +2 -0
  99. agentbundle-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,584 @@
1
+ # Adapter contract — every (primitive × adapter) pair enumerated.
2
+ # Validates against ./adapter.schema.json.
3
+ # Managed by: docs/specs/distribution-adapters/spec.md
4
+ # RFC reference: RFC-0001 (base contract); RFC-0004 (scope dimension, v0.2);
5
+ # RFC-0005 (hook-body / hook-wiring forks, v0.3);
6
+ # RFC-0008 (claude-plugins install route, v0.4);
7
+ # RFC-0010 (apm install route, v0.5);
8
+ # RFC-0011 / docs/specs/pack-allowed-adapters (codex user-scope table, v0.6);
9
+ # RFC-0012 / docs/specs/repo-scope-per-adapter-projection (per-IDE projection
10
+ # at repo scope; `allowed-prefixes.repo` on every adapter; copilot scope
11
+ # table; v0.7).
12
+ # RFC-0013 / docs/specs/credential-broker-contract (governance bump, v0.7 —
13
+ # admitted as a co-residing v0.7 contributor; the `metadata.auth` lint
14
+ # surface lives in tools/lint-agent-artifacts.py, not in this file).
15
+ # docs/specs/dropped-primitives-coverage (v0.8): codex `agent` projects to
16
+ # `.codex/agents/<name>.toml` via new `codex-agent-toml` mode; codex
17
+ # `hook-wiring` projects to `.codex/hooks.json` via existing `merge-json`
18
+ # mode; codex `.codex/` added to allowed-prefixes; new `codex-agent-
19
+ # frontmatter-v0.8` mapping. Dropped-primitives warning rail introduced
20
+ # in `agentbundle install` for any (adapter, pack) pair where the
21
+ # resolved adapter projects a primitive type the pack ships as `dropped`.
22
+ # RFC-0022 / docs/specs/kiro-adapter-split (v0.9): kiro adapter split into
23
+ # `kiro-ide` (IDE, .md agents, kiro-ide-hook active, flat path confirmed by
24
+ # Q6 probe no×yes 2026-06-01) and `kiro-cli` (CLI binary, .json agents,
25
+ # hook-wiring retained). `kiro` retained as deprecated alias for `kiro-ide`.
26
+ # `kiro-ide-hook` primitive activated; `kiro-ide-agent-frontmatter-v0.9` renamed
27
+ # to `kiro-ide-agent-frontmatter-v0.9`.
28
+ # RFC-0024 / ADR-0013 / docs/specs/copilot-full-parity (v0.10): copilot becomes
29
+ # a full-parity, user-scope-capable adapter. `agent` flips `dropped`→
30
+ # `copilot-agent-md` (markdown → `.github/agents/<name>.agent.md`); `hook-wiring`
31
+ # flips `dropped`→`copilot-hooks-json` (one self-contained `<name>.json` per
32
+ # source file at `.github/hooks/`); `hook-body` retargets `tools/hooks/`→
33
+ # `.github/hooks/`; `skill` gains a user target (`~/.copilot/instructions/`);
34
+ # `[adapter.copilot.scope]` gains `user = "~"` + `allowed-prefixes.user`; new
35
+ # `copilot-agent-frontmatter-v0.10` mapping. `command` stays `dropped`
36
+ # (copilot-cli#618/#1113). Two-pack bump (research + core), not all-pack.
37
+
38
+ [contract]
39
+ version = "0.10"
40
+
41
+ # Sibling schemas this contract references — pack metadata and the
42
+ # per-pack Claude-plugin manifest. Defined by spec AC #3 + #4.
43
+ [contract.schemas]
44
+ pack = "pack.schema.json"
45
+ plugin-manifest = "plugin-manifest.schema.json"
46
+
47
+ # ---------------------------------------------------------------------------
48
+ # Primitive types — source paths within a pack's .apm/ directory
49
+ # ---------------------------------------------------------------------------
50
+
51
+ [primitive.skill]
52
+ source-path = ".apm/skills/"
53
+
54
+ [primitive.agent]
55
+ source-path = ".apm/agents/"
56
+
57
+ [primitive."hook-body"]
58
+ source-path = ".apm/hooks/"
59
+
60
+ [primitive."hook-wiring"]
61
+ source-path = ".apm/hook-wiring/"
62
+
63
+ [primitive.command]
64
+ source-path = ".apm/commands/"
65
+
66
+ # RFC-0022 / kiro-ide-hook: standalone IDE event hook files (.kiro.hook JSON).
67
+ # Activated at v0.9 for the kiro-ide adapter; dropped for kiro-cli and others.
68
+ [primitive."kiro-ide-hook"]
69
+ source-path = ".apm/kiro-ide-hooks/"
70
+
71
+ # RFC-0013 § 4c — `shared-libs/` carries Python sibling files that the
72
+ # build pipeline projects into every consumer skill declaring
73
+ # `metadata.auth: creds`. The projection is cross-cutting (not adapter-
74
+ # keyed) and lives in `agentbundle.build.shared_libs`; the declaration
75
+ # here documents the source path so future readers see the full
76
+ # primitive surface in one place.
77
+ [primitive."shared-libs"]
78
+ source-path = ".apm/shared-libs/"
79
+
80
+ # RFC-0013 § 4d — `adapter-root-bins/` carries executable scripts that
81
+ # project to the per-scope artifact root (`~/.agentbundle/bin/` at user
82
+ # scope, `<repo>/.agentbundle/bin/` at repo scope). T6 wires the
83
+ # projection; the declaration is here so the contract is complete at
84
+ # v0.7. Adapter projection rules for `adapter-root-bins` are NOT
85
+ # declared because the target is `<scope-root>/.agentbundle/bin/`,
86
+ # which is fenced by `allowed-prefixes.<scope>`, not by per-adapter
87
+ # target paths.
88
+ [primitive."adapter-root-bins"]
89
+ source-path = ".apm/adapter-root-bins/"
90
+
91
+ # ---------------------------------------------------------------------------
92
+ # Claude Code adapter — 5 projections (one per primitive) + v0.3 forks
93
+ #
94
+ # The legacy `[[adapter."claude-code".projection]]` array carries the
95
+ # repo-scope shape every adapter has consumed since v0.1. RFC-0005 adds two
96
+ # forward-looking `[adapter."claude-code".projections.<primitive>]` tables
97
+ # (hook-body / hook-wiring) carrying the scope-conditional shape that the
98
+ # v0.3 user-scope pipeline reads. Until that pipeline lands, the legacy
99
+ # entries remain authoritative; the new tables are declarative metadata.
100
+ # ---------------------------------------------------------------------------
101
+
102
+ # Install routes declared for this adapter (RFC-0008 / spec claude-plugins-install-route;
103
+ # RFC-0010 / spec apm-install-route-parity adds "apm").
104
+ # Kiro, Copilot, and Codex do not declare install-routes; the field defaults to ["cli"]
105
+ # on read for adapters that omit it.
106
+ [adapter."claude-code"]
107
+ install-routes = ["cli", "claude-plugins", "apm"]
108
+
109
+ [[adapter."claude-code".projection]]
110
+ primitive = "skill"
111
+ mode = "direct-directory"
112
+ target-path = ".claude/skills/"
113
+ on-conflict = "prompt-then-preserve"
114
+
115
+ [[adapter."claude-code".projection]]
116
+ primitive = "agent"
117
+ mode = "direct-file"
118
+ target-path = ".claude/agents/"
119
+ on-conflict = "prompt-then-preserve"
120
+
121
+ [[adapter."claude-code".projection]]
122
+ primitive = "hook-body"
123
+ mode = "direct-file"
124
+ target-path = "tools/hooks/"
125
+ on-conflict = "prompt-then-preserve"
126
+
127
+ [[adapter."claude-code".projection]]
128
+ primitive = "hook-wiring"
129
+ mode = "merge-json"
130
+ target-path = ".claude/settings.local.json"
131
+ managed-key = "hooks"
132
+ on-conflict = "merge-managed-key-only"
133
+
134
+ [[adapter."claude-code".projection]]
135
+ primitive = "command"
136
+ mode = "direct-file"
137
+ target-path = ".claude/commands/"
138
+ on-conflict = "prompt-then-preserve"
139
+
140
+ # hook-body — scope-conditional target (RFC-0005 § hook-body at user scope).
141
+ # Forward-looking v0.3 declaration; the legacy array entry above remains the
142
+ # pipeline-of-record until T5/T7 land.
143
+ [adapter."claude-code".projections.hook-body]
144
+ mode = "direct-file"
145
+ target.repo = "tools/hooks/<name>.{sh,py}"
146
+ target.user = ".claude/hooks/<name>.{sh,py}"
147
+ on-conflict = "prompt-then-preserve"
148
+
149
+ # hook-wiring — scope-conditional mode/target; user-scope `managed-key`
150
+ # required (RFC-0005 § hook-wiring for Claude Code at user scope).
151
+ [adapter."claude-code".projections.hook-wiring]
152
+ mode.repo = "merge-json"
153
+ mode.user = "user-merge-json"
154
+ target.repo = ".claude/settings.local.json"
155
+ target.user = ".claude/settings.json"
156
+ managed-key.user = "hooks"
157
+
158
+ # Scope dimension (RFC-0004). Two roots: repo-local and user-local.
159
+ # `allowed-prefixes.<scope>` fences every write under that scope to a
160
+ # declared prefix list — at user scope this stops a buggy projection
161
+ # rule from resolving under `~/Documents/`. The two-prefix shape covers
162
+ # projected primitives (`.claude/`) and CLI infrastructure writes
163
+ # (`.agentbundle/` — user-scope state file, per-scope discovery and
164
+ # pending artifacts).
165
+ [adapter."claude-code".scope]
166
+ repo = "."
167
+ user = "~"
168
+ # RFC-0012: repo-scope projection lands primitives under `.claude/` (skills,
169
+ # agents, commands, hook-wiring) plus `tools/hooks/` for hook bodies — the
170
+ # legacy repo-scope hook-body target that pre-dates the scope dimension.
171
+ allowed-prefixes.repo = [".claude/", ".agentbundle/", "tools/hooks/"]
172
+ allowed-prefixes.user = [".claude/", ".agentbundle/"]
173
+
174
+ # ---------------------------------------------------------------------------
175
+ # Kiro adapter — DEPRECATED ALIAS for kiro-ide (RFC-0022 D1).
176
+ #
177
+ # `kiro` is retained as a working alias with no removal timeline so existing
178
+ # packs declaring `allowed-adapters = ["kiro"]` keep working. The Python
179
+ # registry maps "kiro" → kiro_ide.project and emits a build-time
180
+ # DeprecationWarning on use. Update `allowed-adapters` to `["kiro-ide"]` or
181
+ # `["kiro-cli"]` in pack.toml to silence the warning.
182
+ #
183
+ # The projection blocks below are preserved verbatim so `validate` keeps
184
+ # accepting "kiro" and `_shipped_for_cli` (derived from the adapter key set)
185
+ # continues to include it.
186
+ # ---------------------------------------------------------------------------
187
+
188
+ [[adapter.kiro.projection]]
189
+ primitive = "skill"
190
+ mode = "direct-directory"
191
+ target-path = ".kiro/skills/"
192
+ on-conflict = "prompt-then-preserve"
193
+
194
+ [[adapter.kiro.projection]]
195
+ primitive = "agent"
196
+ mode = "direct-file"
197
+ target-path = ".kiro/agents/"
198
+ frontmatter-mapping = "kiro-ide-agent-frontmatter-v0.9"
199
+ on-conflict = "prompt-then-preserve"
200
+
201
+ [[adapter.kiro.projection]]
202
+ primitive = "hook-body"
203
+ mode = "direct-file"
204
+ target-path = "tools/hooks/"
205
+ on-conflict = "prompt-then-preserve"
206
+
207
+ [[adapter.kiro.projection]]
208
+ primitive = "command"
209
+ mode = "dropped"
210
+
211
+ # hook-body — scope-conditional target. User-scope lands under `~/.kiro/hooks/`
212
+ # per RFC-0005 § hook-body at user scope. Forward-looking v0.3 declaration;
213
+ # the legacy array entry above remains authoritative until T5/T7.
214
+ [adapter.kiro.projections.hook-body]
215
+ mode = "direct-file"
216
+ target.repo = "tools/hooks/<name>.{sh,py}"
217
+ target.user = ".kiro/hooks/<name>.{sh,py}"
218
+ on-conflict = "prompt-then-preserve"
219
+
220
+ # hook-wiring — merge into the pack-owned agent JSON. Same mode at both scopes;
221
+ # the agent-file target is scope-conditional via scope-root resolution
222
+ # (RFC-0005 § hook-wiring for Kiro at both scopes). The legacy
223
+ # `degraded-info-log` array entry is removed (AC2).
224
+ [adapter.kiro.projections.hook-wiring]
225
+ mode = "merge-into-agent-json"
226
+ target.repo = ".kiro/agents/<attach-to-agent>.json"
227
+ target.user = ".kiro/agents/<attach-to-agent>.json"
228
+ managed-key = "hooks"
229
+ agent-event-vocabulary = [
230
+ "agentSpawn",
231
+ "userPromptSubmit",
232
+ "preToolUse",
233
+ "postToolUse",
234
+ "stop",
235
+ ]
236
+
237
+ # Scope dimension for Kiro (RFC-0005 § hook-wiring for Kiro at both scopes).
238
+ # User-scope agents live under `~/.kiro/agents/` per Kiro's documented layout
239
+ # (https://kiro.dev/docs/cli/custom-agents/creating/); CLI infrastructure
240
+ # shares the `.agentbundle/` prefix.
241
+ [adapter.kiro.scope]
242
+ repo = "."
243
+ user = "~"
244
+ # RFC-0012: Kiro projects skills/agents to `.kiro/`; hook bodies land in the
245
+ # legacy `tools/hooks/` at repo scope (matching the contract's hook-body
246
+ # array entry above).
247
+ allowed-prefixes.repo = [".kiro/", ".agentbundle/", "tools/hooks/"]
248
+ allowed-prefixes.user = [".kiro/", ".agentbundle/"]
249
+
250
+ # ---------------------------------------------------------------------------
251
+ # kiro-ide adapter — targets the Kiro VS Code-fork IDE (RFC-0022).
252
+ #
253
+ # Projects agents as `.md` (gray-matter YAML frontmatter + body); the IDE
254
+ # reads `.kiro/agents/<name>.md` via its gray-matter loader. hook-wiring is
255
+ # DROPPED — the IDE loader silently drops any agent carrying a `hooks` key
256
+ # (RFC-0022 E2). kiro-ide-hook is ACTIVATED with the flat path confirmed by
257
+ # Q6 probe (no-recursion, yes-extension-filter, 2026-06-01, Kiro 0.12.224):
258
+ # `.kiro/hooks/<pack>--<name>.kiro.hook`. RFC-0022 assumed yes-recursion;
259
+ # T1 carries the corrected no-recursion flat path (no T-E1b fires).
260
+ # ---------------------------------------------------------------------------
261
+
262
+ [[adapter.kiro-ide.projection]]
263
+ primitive = "skill"
264
+ mode = "direct-directory"
265
+ target-path = ".kiro/skills/"
266
+ on-conflict = "prompt-then-preserve"
267
+
268
+ [[adapter.kiro-ide.projection]]
269
+ primitive = "agent"
270
+ mode = "direct-file"
271
+ target-path = ".kiro/agents/"
272
+ frontmatter-mapping = "kiro-ide-agent-frontmatter-v0.9"
273
+ on-conflict = "prompt-then-preserve"
274
+
275
+ [[adapter.kiro-ide.projection]]
276
+ primitive = "hook-body"
277
+ mode = "direct-file"
278
+ target-path = "tools/hooks/"
279
+ on-conflict = "prompt-then-preserve"
280
+
281
+ [[adapter.kiro-ide.projection]]
282
+ primitive = "hook-wiring"
283
+ mode = "dropped"
284
+
285
+ [[adapter.kiro-ide.projection]]
286
+ primitive = "command"
287
+ mode = "dropped"
288
+
289
+ # hook-body — scope-conditional target (RFC-0005 § hook-body at user scope).
290
+ [adapter.kiro-ide.projections.hook-body]
291
+ mode = "direct-file"
292
+ target.repo = "tools/hooks/<name>.{sh,py}"
293
+ target.user = ".kiro/hooks/<name>.{sh,py}"
294
+ on-conflict = "prompt-then-preserve"
295
+
296
+ # kiro-ide-hook — activated for the IDE target (Q6 probe: no-recursion,
297
+ # yes-extension-filter). Flat path uses `<pack>--<name>` prefix separator
298
+ # so pack hooks coexist in the single flat `.kiro/hooks/` directory.
299
+ [adapter.kiro-ide.projections.kiro-ide-hook]
300
+ mode = "direct-file"
301
+ target.repo = ".kiro/hooks/<pack>--<name>.kiro.hook"
302
+ ide-event-vocabulary = [
303
+ "fileEdited",
304
+ "fileCreated",
305
+ "fileDeleted",
306
+ "userTriggered",
307
+ "promptSubmit",
308
+ "agentStop",
309
+ "preToolUse",
310
+ "postToolUse",
311
+ "preTaskExecution",
312
+ "postTaskExecution",
313
+ "sessionStart",
314
+ ]
315
+ ide-action-vocabulary = ["askAgent", "runCommand"]
316
+
317
+ [adapter.kiro-ide.scope]
318
+ repo = "."
319
+ user = "~"
320
+ allowed-prefixes.repo = [".kiro/", ".agentbundle/", "tools/hooks/"]
321
+ allowed-prefixes.user = [".kiro/", ".agentbundle/"]
322
+
323
+ # ---------------------------------------------------------------------------
324
+ # kiro-cli adapter — targets the `kiro` terminal binary (RFC-0022).
325
+ #
326
+ # Projects agents as `.json` with CLI short-name tool tokens. Retains
327
+ # `hook-wiring` via `merge-into-agent-json`. `kiro-ide-hook` is dropped —
328
+ # the IDE-only event-hook primitive is not supported by the CLI target.
329
+ # ---------------------------------------------------------------------------
330
+
331
+ [[adapter.kiro-cli.projection]]
332
+ primitive = "skill"
333
+ mode = "direct-directory"
334
+ target-path = ".kiro/skills/"
335
+ on-conflict = "prompt-then-preserve"
336
+
337
+ [[adapter.kiro-cli.projection]]
338
+ primitive = "agent"
339
+ mode = "direct-file"
340
+ target-path = ".kiro/agents/"
341
+ frontmatter-mapping = "kiro-cli-agent-frontmatter-v1.0"
342
+ on-conflict = "prompt-then-preserve"
343
+
344
+ [[adapter.kiro-cli.projection]]
345
+ # Legacy repo-scope entry — the pipeline-of-record for repo-scope hook-body
346
+ # projection (mirrors the `kiro` adapter's RFC-0005 hybrid). The table form
347
+ # below is the scope-conditional declaration for the user-scope pipeline;
348
+ # both coexist intentionally. `_iter_primitives` deduplicates via set union.
349
+ primitive = "hook-body"
350
+ mode = "direct-file"
351
+ target-path = "tools/hooks/"
352
+ on-conflict = "prompt-then-preserve"
353
+
354
+ [[adapter.kiro-cli.projection]]
355
+ primitive = "command"
356
+ mode = "dropped"
357
+
358
+ # hook-body — scope-conditional target (RFC-0005 § hook-body at user scope).
359
+ [adapter.kiro-cli.projections.hook-body]
360
+ mode = "direct-file"
361
+ target.repo = "tools/hooks/<name>.{sh,py}"
362
+ target.user = ".kiro/hooks/<name>.{sh,py}"
363
+ on-conflict = "prompt-then-preserve"
364
+
365
+ # hook-wiring — merge into the pack-owned agent JSON (same as legacy kiro).
366
+ [adapter.kiro-cli.projections.hook-wiring]
367
+ mode = "merge-into-agent-json"
368
+ target.repo = ".kiro/agents/<attach-to-agent>.json"
369
+ target.user = ".kiro/agents/<attach-to-agent>.json"
370
+ managed-key = "hooks"
371
+ agent-event-vocabulary = [
372
+ "agentSpawn",
373
+ "userPromptSubmit",
374
+ "preToolUse",
375
+ "postToolUse",
376
+ "stop",
377
+ ]
378
+
379
+ # kiro-ide-hook — dropped for the CLI target. The IDE-only event-hook
380
+ # primitive is not supported by the kiro binary; packs shipping
381
+ # .apm/kiro-ide-hooks/ content must use the kiro-ide adapter instead.
382
+ [adapter.kiro-cli.projections.kiro-ide-hook]
383
+ mode = "dropped"
384
+
385
+ [adapter.kiro-cli.scope]
386
+ repo = "."
387
+ user = "~"
388
+ allowed-prefixes.repo = [".kiro/", ".agentbundle/", "tools/hooks/"]
389
+ allowed-prefixes.user = [".kiro/", ".agentbundle/"]
390
+
391
+ # ---------------------------------------------------------------------------
392
+ # Copilot adapter — 5 projections (one per primitive)
393
+ # ---------------------------------------------------------------------------
394
+
395
+ [[adapter.copilot.projection]]
396
+ primitive = "skill"
397
+ mode = "instruction-file"
398
+ target-path = ".github/instructions/"
399
+ frontmatter-default = "copilot-instruction"
400
+ on-conflict = "prompt-then-overwrite"
401
+
402
+ [[adapter.copilot.projection]]
403
+ primitive = "agent"
404
+ mode = "copilot-agent-md"
405
+ target-path = ".github/agents/"
406
+ frontmatter-mapping = "copilot-agent-frontmatter-v0.10"
407
+ on-conflict = "prompt-then-preserve"
408
+
409
+ [[adapter.copilot.projection]]
410
+ primitive = "hook-body"
411
+ mode = "direct-file"
412
+ target-path = ".github/hooks/"
413
+ on-conflict = "prompt-then-preserve"
414
+
415
+ [[adapter.copilot.projection]]
416
+ primitive = "hook-wiring"
417
+ mode = "copilot-hooks-json"
418
+ target-path = ".github/hooks/"
419
+ on-conflict = "prompt-then-preserve"
420
+
421
+ [[adapter.copilot.projection]]
422
+ primitive = "command"
423
+ mode = "dropped"
424
+
425
+ # Scope dimension for Copilot (RFC-0024 / ADR-0013 / docs/specs/copilot-full-parity).
426
+ # Copilot is now a full-parity, user-scope-capable adapter: the app + CLI
427
+ # discover agents/instructions/hooks from `.github/` (repo) and `~/.copilot/`
428
+ # (user). The repo-only restriction RFC-0012 recorded is superseded-in-part.
429
+ # `skill` keeps its `instruction-file` mode; its user target
430
+ # (`~/.copilot/instructions/<name>.instructions.md`) is produced by the install
431
+ # handler's copilot user-scope prefix rewrite (`.github/X/`→`.copilot/X/`),
432
+ # since the build adapter is scope-agnostic and emits repo-relpaths.
433
+ [adapter.copilot.scope]
434
+ repo = "."
435
+ user = "~"
436
+ # RFC-0024: repo-scope agents at `.github/agents/`, instructions at
437
+ # `.github/instructions/`, hook wiring + bodies at `.github/hooks/`.
438
+ allowed-prefixes.repo = [".github/instructions/", ".github/agents/", ".github/hooks/"]
439
+ # User-scope home is `~/.copilot/` — the prefix the install rewrite produces
440
+ # from the adapter's repo-relpaths. `.agentbundle/` carries the install
441
+ # state file (`~/.agentbundle/state.toml`), same as every other user-scope-
442
+ # capable adapter (claude-code, codex).
443
+ allowed-prefixes.user = [".copilot/agents/", ".copilot/instructions/", ".copilot/hooks/", ".agentbundle/"]
444
+
445
+ # ---------------------------------------------------------------------------
446
+ # Codex adapter — 5 projections (one per primitive)
447
+ # ---------------------------------------------------------------------------
448
+
449
+ [[adapter.codex.projection]]
450
+ primitive = "skill"
451
+ mode = "direct-directory"
452
+ target-path = ".agents/skills/"
453
+ on-conflict = "prompt-then-preserve"
454
+
455
+ [[adapter.codex.projection]]
456
+ primitive = "agent"
457
+ mode = "codex-agent-toml"
458
+ target-path = ".codex/agents/"
459
+ frontmatter-mapping = "codex-agent-frontmatter-v0.8"
460
+ on-conflict = "prompt-then-preserve"
461
+
462
+ [[adapter.codex.projection]]
463
+ primitive = "hook-body"
464
+ mode = "direct-file"
465
+ target-path = "tools/hooks/"
466
+ on-conflict = "prompt-then-preserve"
467
+
468
+ [[adapter.codex.projection]]
469
+ primitive = "hook-wiring"
470
+ mode = "merge-json"
471
+ target-path = ".codex/hooks.json"
472
+ managed-key = "hooks"
473
+ on-conflict = "merge-managed-key-only"
474
+
475
+ [[adapter.codex.projection]]
476
+ primitive = "command"
477
+ mode = "dropped"
478
+
479
+ # Scope dimension for Codex (RFC-0011 / docs/specs/pack-allowed-adapters).
480
+ # User-scope skills live under `~/.agents/skills/` per the codex
481
+ # `direct-directory` projection's `.agents/skills/` target-path above;
482
+ # CLI infrastructure shares the `.agentbundle/` prefix.
483
+ [adapter.codex.scope]
484
+ repo = "."
485
+ user = "~"
486
+ # RFC-0012: codex projects skills to `.agents/skills/`; hook bodies land in
487
+ # the legacy `tools/hooks/` (matching codex's hook-body array entry).
488
+ allowed-prefixes.repo = [".agents/skills/", ".codex/", ".agentbundle/", "tools/hooks/"]
489
+ allowed-prefixes.user = [".agents/skills/", ".codex/", ".agentbundle/"]
490
+
491
+ # ---------------------------------------------------------------------------
492
+ # Frontmatter mappings — rewrite rules applied when projecting a primitive
493
+ # ---------------------------------------------------------------------------
494
+
495
+ # Kiro agent frontmatter v0.9: renames Claude Code agent fields to Kiro's schema.
496
+ # Adapters consume this table generically; no field dictionary hardcoded in Python.
497
+ [frontmatter-mapping."kiro-ide-agent-frontmatter-v0.9"]
498
+
499
+ [frontmatter-mapping."kiro-ide-agent-frontmatter-v0.9".description]
500
+ rename = "description"
501
+
502
+ [frontmatter-mapping."kiro-ide-agent-frontmatter-v0.9".tools]
503
+ normalize = "to-list"
504
+ # Translate Claude Code tool names to specific Kiro tool *ids*. Kiro matches
505
+ # an agent's `tools` entries by id or tag (never by Claude Code names); we
506
+ # prefer ids for a faithful, least-privilege 1:1 mapping rather than the
507
+ # broad category tags (the `read` tag also grants diagnostics + read_code;
508
+ # `write` also grants delete_file). `WebSearch` is the exception — the IDE
509
+ # exposes no granular web-search tool id, so it maps to the `web` tag.
510
+ # Applied per list element after `to-list`; duplicates collapse and an
511
+ # unmapped token drops with a build-time warning. These are Kiro IDE ids;
512
+ # the Kiro CLI's short names land in the kiro-cli adapter.
513
+ values = { Read = "read_file", Grep = "grep_search", Glob = "file_search", Edit = "str_replace", Write = "fs_write", MultiEdit = "str_replace", Bash = "execute_bash", WebFetch = "web_fetch", WebSearch = "web" }
514
+
515
+ [frontmatter-mapping."kiro-ide-agent-frontmatter-v0.9".model]
516
+ rename = "model"
517
+ # Translate Claude Code's friendly aliases to Kiro's documented model IDs
518
+ # (https://kiro.dev/docs/cli/custom-agents/configuration-reference/). A
519
+ # source value not in the map is dropped from the JSON output, leaving
520
+ # Kiro to fall back to its CLI default with a warning rather than
521
+ # rejecting the agent for an unknown model.
522
+ values = { opus = "claude-opus-4.6", sonnet = "claude-sonnet-4.5", haiku = "claude-haiku-4.5" }
523
+
524
+ # kiro-cli agent frontmatter v1.0 (RFC-0022): rewrite rules from Claude Code
525
+ # agent markdown to Kiro CLI JSON. Tools map to CLI short-names (not IDE ids).
526
+ # The `kiro` CLI matches agents' `tools` entries by short name; the IDE uses
527
+ # ids — hence the separate table rather than reusing kiro-ide-agent-frontmatter-v0.9.
528
+ [frontmatter-mapping."kiro-cli-agent-frontmatter-v1.0"]
529
+
530
+ [frontmatter-mapping."kiro-cli-agent-frontmatter-v1.0".description]
531
+ rename = "description"
532
+
533
+ [frontmatter-mapping."kiro-cli-agent-frontmatter-v1.0".tools]
534
+ normalize = "to-list"
535
+ # Translate Claude Code tool names to Kiro CLI short-name tool tokens.
536
+ # Applied per list element after `to-list`; duplicates collapse and an
537
+ # unmapped token drops with a build-time warning.
538
+ values = { Read = "read", Grep = "grep", Glob = "glob", Edit = "write", Write = "write", MultiEdit = "write", Bash = "shell", WebFetch = "web_fetch", WebSearch = "web_search" }
539
+
540
+ [frontmatter-mapping."kiro-cli-agent-frontmatter-v1.0".model]
541
+ rename = "model"
542
+ values = { opus = "claude-opus-4.6", sonnet = "claude-sonnet-4.5", haiku = "claude-haiku-4.5" }
543
+
544
+ # Codex agent frontmatter v0.8 (docs/specs/dropped-primitives-coverage):
545
+ # rewrite rules from claude-code-style markdown agent (YAML frontmatter with
546
+ # `name`, `description`, optionally `tools`, `model`) to codex's TOML agent
547
+ # shape (`name`, `description`, `developer_instructions`). The markdown body
548
+ # lands in TOML `developer_instructions` via a mode-level convention in the
549
+ # `codex-agent-toml` projection mode, NOT via a rename rule (frontmatter
550
+ # mapping is keyed on frontmatter fields; the body is not one). Fields not
551
+ # in this mapping (e.g., `tools`, `model`) drop silently — codex TOML agent
552
+ # format has no equivalent slots; a future RFC can add MCP-server mapping.
553
+ [frontmatter-mapping."codex-agent-frontmatter-v0.8"]
554
+
555
+ [frontmatter-mapping."codex-agent-frontmatter-v0.8".name]
556
+ rename = "name"
557
+
558
+ [frontmatter-mapping."codex-agent-frontmatter-v0.8".description]
559
+ rename = "description"
560
+
561
+ # Copilot agent frontmatter v0.10 (RFC-0024 / docs/specs/copilot-full-parity):
562
+ # rewrite rules from claude-code-style markdown agent (YAML frontmatter with
563
+ # `name`, `description`, optionally `tools`, `model`) to Copilot's `.agent.md`
564
+ # shape. `name` / `description` pass through (identity renames). `tools` is
565
+ # NOT a rename rule — the `copilot-agent-md` mode emits it verbatim after an
566
+ # allow-list validation (Copilot's parser self-resolves the Claude names), so
567
+ # a `values` map here would be redundant. `model` is absent from this mapping
568
+ # and so drops on projection (the CLI ignores it; our values aren't Copilot
569
+ # model ids — copilot-cli#2133/#1195). `target` is never emitted.
570
+ [frontmatter-mapping."copilot-agent-frontmatter-v0.10"]
571
+
572
+ [frontmatter-mapping."copilot-agent-frontmatter-v0.10".name]
573
+ rename = "name"
574
+
575
+ [frontmatter-mapping."copilot-agent-frontmatter-v0.10".description]
576
+ rename = "description"
577
+
578
+ # ---------------------------------------------------------------------------
579
+ # Frontmatter defaults — fields injected when a primitive has no frontmatter
580
+ # ---------------------------------------------------------------------------
581
+
582
+ # Copilot instruction file default: applyTo covers the whole repo.
583
+ [frontmatter-default."copilot-instruction"]
584
+ applyTo = "**"