agents-inc 0.162.0 → 0.164.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.
- package/CHANGELOG.md +28 -0
- package/dist/{chunk-HRVPZMKK.js → chunk-2CQNPLVF.js} +35 -14
- package/dist/chunk-2CQNPLVF.js.map +1 -0
- package/dist/{chunk-VFZF7LVY.js → chunk-3WVH2CTK.js} +3 -3
- package/dist/{chunk-5J6DO4VW.js → chunk-4VL3CEOS.js} +3 -3
- package/dist/{chunk-QM3ZNOWJ.js → chunk-6MV4JOCL.js} +2 -2
- package/dist/{chunk-WIJM6BX6.js → chunk-7ANJQLPJ.js} +2 -2
- package/dist/{chunk-3JDVBHWO.js → chunk-7REKOTKG.js} +2 -2
- package/dist/{chunk-MI7LKLD7.js → chunk-ABAZMMG4.js} +2 -2
- package/dist/{chunk-XSM3IBMG.js → chunk-AOTCIUGX.js} +2 -2
- package/dist/{chunk-L65XGQKR.js → chunk-ARYNOWKF.js} +8 -8
- package/dist/{chunk-3QBOVV6A.js → chunk-AVK2HEKB.js} +5 -5
- package/dist/{chunk-3QBOVV6A.js.map → chunk-AVK2HEKB.js.map} +1 -1
- package/dist/{chunk-AQSMNUKJ.js → chunk-B3Y3QMWI.js} +4 -4
- package/dist/{chunk-ES7WGE32.js → chunk-B6FSLXYN.js} +3 -3
- package/dist/{chunk-S6GX7IJ2.js → chunk-DSL66I4N.js} +6 -6
- package/dist/{chunk-IMTWWA3N.js → chunk-ECURHW3T.js} +12 -12
- package/dist/{chunk-VEONZFTL.js → chunk-FLW25ORT.js} +3 -3
- package/dist/{chunk-53XPSAJ4.js → chunk-G2JJ5BO5.js} +17 -16
- package/dist/chunk-G2JJ5BO5.js.map +1 -0
- package/dist/{chunk-H2MDPOLG.js → chunk-JIERYE6B.js} +5 -5
- package/dist/{chunk-GFO55TMY.js → chunk-JU4ZGJ7A.js} +100 -24
- package/dist/chunk-JU4ZGJ7A.js.map +1 -0
- package/dist/{chunk-K26SBQLO.js → chunk-K5ITEA3I.js} +4 -4
- package/dist/{chunk-4KVJJJG2.js → chunk-LT5GXEB2.js} +6 -6
- package/dist/{chunk-2IMHZEIK.js → chunk-NKGYKOB7.js} +3 -3
- package/dist/{chunk-X6KXPRKI.js → chunk-NQXO4LR3.js} +4 -4
- package/dist/{chunk-ZFPQM63K.js → chunk-NTF4UXGK.js} +5 -5
- package/dist/{chunk-77YZFVQD.js → chunk-PHCPUQVR.js} +2 -2
- package/dist/{chunk-T2RPUNYP.js → chunk-Q4IRRVXK.js} +3 -3
- package/dist/{chunk-EN5MEPAS.js → chunk-QGUP3QJF.js} +5 -5
- package/dist/{chunk-MSUTHS2V.js → chunk-QZX7SYKU.js} +2 -2
- package/dist/{chunk-BR3TNSO3.js → chunk-RGYDFBCT.js} +4 -4
- package/dist/{chunk-4NAWM4OQ.js → chunk-S63LXWMC.js} +2 -2
- package/dist/{chunk-IV42Z63R.js → chunk-UITEKY2R.js} +19 -9
- package/dist/chunk-UITEKY2R.js.map +1 -0
- package/dist/{chunk-RMMEYCEA.js → chunk-URXIQE7I.js} +2 -2
- package/dist/{chunk-57YWAMNT.js → chunk-V5GLL2JB.js} +7 -7
- package/dist/{chunk-C53RJ7AA.js → chunk-X37UYIE3.js} +43 -41
- package/dist/chunk-X37UYIE3.js.map +1 -0
- package/dist/{chunk-J2YG7P7L.js → chunk-X4SSJZLY.js} +49 -6
- package/dist/chunk-X4SSJZLY.js.map +1 -0
- package/dist/{chunk-VEBEGZUV.js → chunk-XATLUKXK.js} +5 -5
- package/dist/{chunk-33ZKIYJM.js → chunk-XHPWTL4I.js} +3 -3
- package/dist/{chunk-UNASGGW2.js → chunk-XPDVAJDH.js} +69 -8
- package/dist/chunk-XPDVAJDH.js.map +1 -0
- package/dist/{chunk-FL2CJ5T5.js → chunk-YRS3QZP2.js} +3 -3
- package/dist/{chunk-FXL63LDL.js → chunk-ZVXGW2IC.js} +2 -2
- package/dist/commands/build/marketplace.js +7 -7
- package/dist/commands/build/plugins.js +7 -7
- package/dist/commands/compile.js +82 -30
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +10 -10
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +40 -38
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +10 -10
- package/dist/commands/init.js +36 -36
- package/dist/commands/list.js +8 -8
- package/dist/commands/new/marketplace.js +7 -7
- package/dist/commands/search.js +10 -10
- package/dist/commands/share.js +8 -8
- package/dist/commands/uninstall.js +11 -11
- package/dist/commands/update.js +6 -6
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/wizard/category-grid.js +4 -4
- package/dist/components/wizard/checkbox-grid.js +4 -4
- package/dist/components/wizard/domain-selection.js +9 -9
- package/dist/components/wizard/run-wizard-session.js +26 -26
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +5 -5
- package/dist/components/wizard/source-grid.js +5 -5
- package/dist/components/wizard/stack-selection.js +7 -7
- package/dist/components/wizard/step-agents.js +8 -8
- package/dist/components/wizard/step-build.js +7 -7
- package/dist/components/wizard/step-confirm.js +9 -9
- package/dist/components/wizard/step-sources.js +8 -8
- package/dist/components/wizard/step-stack.js +8 -8
- package/dist/components/wizard/summary-panel.js +8 -8
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +12 -12
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard.js +25 -25
- package/dist/hooks/init.js +36 -36
- package/dist/load-agent-defs-7IM3GBEQ.js +13 -0
- package/dist/recompile-project-agents-VR4NLGOU.js +17 -0
- package/dist/{source-loader-KAWB76OH.js → source-loader-GRBVNRAW.js} +4 -4
- package/dist/src/agents/_templates/agent.liquid +30 -122
- package/dist/src/agents/_templates/methodologies/operating-principles.liquid +27 -0
- package/dist/src/agents/developer/ai-developer/critical-reminders.md +9 -48
- package/dist/src/agents/developer/ai-developer/critical-requirements.md +29 -47
- package/dist/src/agents/developer/ai-developer/identity.md +31 -40
- package/dist/src/agents/developer/ai-developer/output.md +92 -245
- package/dist/src/agents/developer/ai-developer/playbook.md +116 -270
- package/dist/src/agents/developer/api-developer/critical-reminders.md +9 -40
- package/dist/src/agents/developer/api-developer/critical-requirements.md +19 -34
- package/dist/src/agents/developer/api-developer/identity.md +18 -33
- package/dist/src/agents/developer/api-developer/output.md +118 -255
- package/dist/src/agents/developer/api-developer/playbook.md +103 -284
- package/dist/src/agents/developer/cli-developer/critical-reminders.md +9 -45
- package/dist/src/agents/developer/cli-developer/critical-requirements.md +21 -39
- package/dist/src/agents/developer/cli-developer/identity.md +22 -36
- package/dist/src/agents/developer/cli-developer/output.md +72 -185
- package/dist/src/agents/developer/cli-developer/playbook.md +107 -307
- package/dist/src/agents/developer/web-developer/critical-reminders.md +9 -34
- package/dist/src/agents/developer/web-developer/critical-requirements.md +11 -30
- package/dist/src/agents/developer/web-developer/identity.md +15 -15
- package/dist/src/agents/developer/web-developer/output.md +67 -220
- package/dist/src/agents/developer/web-developer/playbook.md +93 -283
- package/dist/src/agents/meta/agent-summoner/critical-reminders.md +6 -39
- package/dist/src/agents/meta/agent-summoner/critical-requirements.md +6 -44
- package/dist/src/agents/meta/agent-summoner/identity.md +20 -23
- package/dist/src/agents/meta/agent-summoner/metadata.yaml +1 -1
- package/dist/src/agents/meta/agent-summoner/output.md +85 -261
- package/dist/src/agents/meta/agent-summoner/playbook.md +220 -1398
- package/dist/src/agents/meta/codex-keeper/critical-reminders.md +11 -32
- package/dist/src/agents/meta/codex-keeper/critical-requirements.md +32 -22
- package/dist/src/agents/meta/codex-keeper/identity.md +31 -32
- package/dist/src/agents/meta/codex-keeper/output.md +49 -335
- package/dist/src/agents/meta/codex-keeper/playbook.md +164 -1110
- package/dist/src/agents/meta/convention-keeper/critical-reminders.md +11 -26
- package/dist/src/agents/meta/convention-keeper/critical-requirements.md +36 -25
- package/dist/src/agents/meta/convention-keeper/identity.md +35 -21
- package/dist/src/agents/meta/convention-keeper/metadata.yaml +1 -1
- package/dist/src/agents/meta/convention-keeper/output.md +33 -123
- package/dist/src/agents/meta/convention-keeper/playbook.md +64 -144
- package/dist/src/agents/meta/skill-summoner/critical-reminders.md +8 -71
- package/dist/src/agents/meta/skill-summoner/critical-requirements.md +9 -73
- package/dist/src/agents/meta/skill-summoner/identity.md +18 -22
- package/dist/src/agents/meta/skill-summoner/metadata.yaml +1 -1
- package/dist/src/agents/meta/skill-summoner/output.md +164 -270
- package/dist/src/agents/meta/skill-summoner/playbook.md +150 -1398
- package/dist/src/agents/planning/pm/critical-requirements.md +23 -25
- package/dist/src/agents/planning/pm/identity.md +24 -23
- package/dist/src/agents/planning/pm/output.md +5 -9
- package/dist/src/agents/planning/pm/playbook.md +50 -140
- package/dist/src/agents/researcher/ai-researcher/critical-reminders.md +8 -53
- package/dist/src/agents/researcher/ai-researcher/critical-requirements.md +31 -26
- package/dist/src/agents/researcher/ai-researcher/identity.md +36 -77
- package/dist/src/agents/researcher/ai-researcher/output.md +44 -151
- package/dist/src/agents/researcher/ai-researcher/playbook.md +130 -394
- package/dist/src/agents/researcher/api-researcher/critical-reminders.md +6 -38
- package/dist/src/agents/researcher/api-researcher/critical-requirements.md +15 -17
- package/dist/src/agents/researcher/api-researcher/identity.md +29 -63
- package/dist/src/agents/researcher/api-researcher/output.md +61 -153
- package/dist/src/agents/researcher/api-researcher/playbook.md +63 -140
- package/dist/src/agents/researcher/cli-researcher/critical-reminders.md +8 -45
- package/dist/src/agents/researcher/cli-researcher/critical-requirements.md +29 -24
- package/dist/src/agents/researcher/cli-researcher/identity.md +36 -78
- package/dist/src/agents/researcher/cli-researcher/output.md +22 -128
- package/dist/src/agents/researcher/cli-researcher/playbook.md +108 -263
- package/dist/src/agents/researcher/web-researcher/critical-reminders.md +5 -34
- package/dist/src/agents/researcher/web-researcher/critical-requirements.md +11 -16
- package/dist/src/agents/researcher/web-researcher/identity.md +28 -60
- package/dist/src/agents/researcher/web-researcher/output.md +41 -134
- package/dist/src/agents/researcher/web-researcher/playbook.md +48 -162
- package/dist/src/agents/reviewer/reviewer/critical-reminders.md +9 -22
- package/dist/src/agents/reviewer/reviewer/critical-requirements.md +24 -19
- package/dist/src/agents/reviewer/reviewer/identity.md +23 -20
- package/dist/src/agents/reviewer/reviewer/metadata.yaml +7 -2
- package/dist/src/agents/reviewer/reviewer/output.md +8 -26
- package/dist/src/agents/reviewer/reviewer/playbook.md +50 -91
- package/dist/src/agents/tester/ai-tester/critical-reminders.md +7 -40
- package/dist/src/agents/tester/ai-tester/critical-requirements.md +39 -31
- package/dist/src/agents/tester/ai-tester/identity.md +25 -40
- package/dist/src/agents/tester/ai-tester/output.md +8 -144
- package/dist/src/agents/tester/ai-tester/playbook.md +28 -40
- package/dist/src/agents/tester/api-tester/critical-reminders.md +8 -35
- package/dist/src/agents/tester/api-tester/critical-requirements.md +36 -25
- package/dist/src/agents/tester/api-tester/identity.md +18 -29
- package/dist/src/agents/tester/api-tester/metadata.yaml +1 -1
- package/dist/src/agents/tester/api-tester/output.md +3 -86
- package/dist/src/agents/tester/api-tester/playbook.md +10 -2
- package/dist/src/agents/tester/cli-tester/critical-reminders.md +7 -30
- package/dist/src/agents/tester/cli-tester/critical-requirements.md +29 -21
- package/dist/src/agents/tester/cli-tester/identity.md +25 -33
- package/dist/src/agents/tester/cli-tester/output.md +13 -105
- package/dist/src/agents/tester/cli-tester/playbook.md +8 -5
- package/dist/src/agents/tester/web-tester/critical-reminders.md +7 -25
- package/dist/src/agents/tester/web-tester/critical-requirements.md +25 -16
- package/dist/src/agents/tester/web-tester/identity.md +24 -30
- package/dist/src/agents/tester/web-tester/output.md +11 -116
- package/dist/src/agents/tester/web-tester/playbook.md +58 -221
- package/dist/stores/wizard-store.js +4 -4
- package/package.json +1 -1
- package/src/agents/_templates/agent.liquid +30 -122
- package/src/agents/_templates/methodologies/operating-principles.liquid +27 -0
- package/src/agents/developer/ai-developer/critical-reminders.md +9 -48
- package/src/agents/developer/ai-developer/critical-requirements.md +29 -47
- package/src/agents/developer/ai-developer/identity.md +31 -40
- package/src/agents/developer/ai-developer/output.md +92 -245
- package/src/agents/developer/ai-developer/playbook.md +116 -270
- package/src/agents/developer/api-developer/critical-reminders.md +9 -40
- package/src/agents/developer/api-developer/critical-requirements.md +19 -34
- package/src/agents/developer/api-developer/identity.md +18 -33
- package/src/agents/developer/api-developer/output.md +118 -255
- package/src/agents/developer/api-developer/playbook.md +103 -284
- package/src/agents/developer/cli-developer/critical-reminders.md +9 -45
- package/src/agents/developer/cli-developer/critical-requirements.md +21 -39
- package/src/agents/developer/cli-developer/identity.md +22 -36
- package/src/agents/developer/cli-developer/output.md +72 -185
- package/src/agents/developer/cli-developer/playbook.md +107 -307
- package/src/agents/developer/web-developer/critical-reminders.md +9 -34
- package/src/agents/developer/web-developer/critical-requirements.md +11 -30
- package/src/agents/developer/web-developer/identity.md +15 -15
- package/src/agents/developer/web-developer/output.md +67 -220
- package/src/agents/developer/web-developer/playbook.md +93 -283
- package/src/agents/meta/agent-summoner/critical-reminders.md +6 -39
- package/src/agents/meta/agent-summoner/critical-requirements.md +6 -44
- package/src/agents/meta/agent-summoner/identity.md +20 -23
- package/src/agents/meta/agent-summoner/metadata.yaml +1 -1
- package/src/agents/meta/agent-summoner/output.md +85 -261
- package/src/agents/meta/agent-summoner/playbook.md +220 -1398
- package/src/agents/meta/codex-keeper/critical-reminders.md +11 -32
- package/src/agents/meta/codex-keeper/critical-requirements.md +32 -22
- package/src/agents/meta/codex-keeper/identity.md +31 -32
- package/src/agents/meta/codex-keeper/output.md +49 -335
- package/src/agents/meta/codex-keeper/playbook.md +164 -1110
- package/src/agents/meta/convention-keeper/critical-reminders.md +11 -26
- package/src/agents/meta/convention-keeper/critical-requirements.md +36 -25
- package/src/agents/meta/convention-keeper/identity.md +35 -21
- package/src/agents/meta/convention-keeper/metadata.yaml +1 -1
- package/src/agents/meta/convention-keeper/output.md +33 -123
- package/src/agents/meta/convention-keeper/playbook.md +64 -144
- package/src/agents/meta/skill-summoner/critical-reminders.md +8 -71
- package/src/agents/meta/skill-summoner/critical-requirements.md +9 -73
- package/src/agents/meta/skill-summoner/identity.md +18 -22
- package/src/agents/meta/skill-summoner/metadata.yaml +1 -1
- package/src/agents/meta/skill-summoner/output.md +164 -270
- package/src/agents/meta/skill-summoner/playbook.md +150 -1398
- package/src/agents/planning/pm/critical-requirements.md +23 -25
- package/src/agents/planning/pm/identity.md +24 -23
- package/src/agents/planning/pm/output.md +5 -9
- package/src/agents/planning/pm/playbook.md +50 -140
- package/src/agents/researcher/ai-researcher/critical-reminders.md +8 -53
- package/src/agents/researcher/ai-researcher/critical-requirements.md +31 -26
- package/src/agents/researcher/ai-researcher/identity.md +36 -77
- package/src/agents/researcher/ai-researcher/output.md +44 -151
- package/src/agents/researcher/ai-researcher/playbook.md +130 -394
- package/src/agents/researcher/api-researcher/critical-reminders.md +6 -38
- package/src/agents/researcher/api-researcher/critical-requirements.md +15 -17
- package/src/agents/researcher/api-researcher/identity.md +29 -63
- package/src/agents/researcher/api-researcher/output.md +61 -153
- package/src/agents/researcher/api-researcher/playbook.md +63 -140
- package/src/agents/researcher/cli-researcher/critical-reminders.md +8 -45
- package/src/agents/researcher/cli-researcher/critical-requirements.md +29 -24
- package/src/agents/researcher/cli-researcher/identity.md +36 -78
- package/src/agents/researcher/cli-researcher/output.md +22 -128
- package/src/agents/researcher/cli-researcher/playbook.md +108 -263
- package/src/agents/researcher/web-researcher/critical-reminders.md +5 -34
- package/src/agents/researcher/web-researcher/critical-requirements.md +11 -16
- package/src/agents/researcher/web-researcher/identity.md +28 -60
- package/src/agents/researcher/web-researcher/output.md +41 -134
- package/src/agents/researcher/web-researcher/playbook.md +48 -162
- package/src/agents/reviewer/reviewer/critical-reminders.md +9 -22
- package/src/agents/reviewer/reviewer/critical-requirements.md +24 -19
- package/src/agents/reviewer/reviewer/identity.md +23 -20
- package/src/agents/reviewer/reviewer/metadata.yaml +7 -2
- package/src/agents/reviewer/reviewer/output.md +8 -26
- package/src/agents/reviewer/reviewer/playbook.md +50 -91
- package/src/agents/tester/ai-tester/critical-reminders.md +7 -40
- package/src/agents/tester/ai-tester/critical-requirements.md +39 -31
- package/src/agents/tester/ai-tester/identity.md +25 -40
- package/src/agents/tester/ai-tester/output.md +8 -144
- package/src/agents/tester/ai-tester/playbook.md +28 -40
- package/src/agents/tester/api-tester/critical-reminders.md +8 -35
- package/src/agents/tester/api-tester/critical-requirements.md +36 -25
- package/src/agents/tester/api-tester/identity.md +18 -29
- package/src/agents/tester/api-tester/metadata.yaml +1 -1
- package/src/agents/tester/api-tester/output.md +3 -86
- package/src/agents/tester/api-tester/playbook.md +10 -2
- package/src/agents/tester/cli-tester/critical-reminders.md +7 -30
- package/src/agents/tester/cli-tester/critical-requirements.md +29 -21
- package/src/agents/tester/cli-tester/identity.md +25 -33
- package/src/agents/tester/cli-tester/output.md +13 -105
- package/src/agents/tester/cli-tester/playbook.md +8 -5
- package/src/agents/tester/web-tester/critical-reminders.md +7 -25
- package/src/agents/tester/web-tester/critical-requirements.md +25 -16
- package/src/agents/tester/web-tester/identity.md +24 -30
- package/src/agents/tester/web-tester/output.md +11 -116
- package/src/agents/tester/web-tester/playbook.md +58 -221
- package/src/schemas/agent-frontmatter.schema.json +14 -0
- package/src/schemas/agent.schema.json +14 -0
- package/dist/chunk-53XPSAJ4.js.map +0 -1
- package/dist/chunk-C53RJ7AA.js.map +0 -1
- package/dist/chunk-GFO55TMY.js.map +0 -1
- package/dist/chunk-HRVPZMKK.js.map +0 -1
- package/dist/chunk-IV42Z63R.js.map +0 -1
- package/dist/chunk-J2YG7P7L.js.map +0 -1
- package/dist/chunk-UNASGGW2.js.map +0 -1
- package/dist/load-agent-defs-57YKPVQW.js +0 -13
- package/dist/recompile-project-agents-IQD3HRRS.js +0 -17
- package/dist/src/agents/_templates/methodologies/anti-over-engineering.liquid +0 -135
- package/dist/src/agents/_templates/methodologies/context-management.liquid +0 -15
- package/dist/src/agents/_templates/methodologies/improvement-protocol.liquid +0 -150
- package/dist/src/agents/_templates/methodologies/investigation-requirements.liquid +0 -61
- package/dist/src/agents/_templates/methodologies/success-criteria.liquid +0 -121
- package/dist/src/agents/_templates/methodologies/write-verification.liquid +0 -43
- package/dist/src/agents/planning/pm/critical-reminders.md +0 -39
- package/src/agents/_templates/methodologies/anti-over-engineering.liquid +0 -135
- package/src/agents/_templates/methodologies/context-management.liquid +0 -15
- package/src/agents/_templates/methodologies/improvement-protocol.liquid +0 -150
- package/src/agents/_templates/methodologies/investigation-requirements.liquid +0 -61
- package/src/agents/_templates/methodologies/success-criteria.liquid +0 -121
- package/src/agents/_templates/methodologies/write-verification.liquid +0 -43
- package/src/agents/planning/pm/critical-reminders.md +0 -39
- /package/dist/{chunk-VFZF7LVY.js.map → chunk-3WVH2CTK.js.map} +0 -0
- /package/dist/{chunk-5J6DO4VW.js.map → chunk-4VL3CEOS.js.map} +0 -0
- /package/dist/{chunk-QM3ZNOWJ.js.map → chunk-6MV4JOCL.js.map} +0 -0
- /package/dist/{chunk-WIJM6BX6.js.map → chunk-7ANJQLPJ.js.map} +0 -0
- /package/dist/{chunk-3JDVBHWO.js.map → chunk-7REKOTKG.js.map} +0 -0
- /package/dist/{chunk-MI7LKLD7.js.map → chunk-ABAZMMG4.js.map} +0 -0
- /package/dist/{chunk-XSM3IBMG.js.map → chunk-AOTCIUGX.js.map} +0 -0
- /package/dist/{chunk-L65XGQKR.js.map → chunk-ARYNOWKF.js.map} +0 -0
- /package/dist/{chunk-AQSMNUKJ.js.map → chunk-B3Y3QMWI.js.map} +0 -0
- /package/dist/{chunk-ES7WGE32.js.map → chunk-B6FSLXYN.js.map} +0 -0
- /package/dist/{chunk-S6GX7IJ2.js.map → chunk-DSL66I4N.js.map} +0 -0
- /package/dist/{chunk-IMTWWA3N.js.map → chunk-ECURHW3T.js.map} +0 -0
- /package/dist/{chunk-VEONZFTL.js.map → chunk-FLW25ORT.js.map} +0 -0
- /package/dist/{chunk-H2MDPOLG.js.map → chunk-JIERYE6B.js.map} +0 -0
- /package/dist/{chunk-K26SBQLO.js.map → chunk-K5ITEA3I.js.map} +0 -0
- /package/dist/{chunk-4KVJJJG2.js.map → chunk-LT5GXEB2.js.map} +0 -0
- /package/dist/{chunk-2IMHZEIK.js.map → chunk-NKGYKOB7.js.map} +0 -0
- /package/dist/{chunk-X6KXPRKI.js.map → chunk-NQXO4LR3.js.map} +0 -0
- /package/dist/{chunk-ZFPQM63K.js.map → chunk-NTF4UXGK.js.map} +0 -0
- /package/dist/{chunk-77YZFVQD.js.map → chunk-PHCPUQVR.js.map} +0 -0
- /package/dist/{chunk-T2RPUNYP.js.map → chunk-Q4IRRVXK.js.map} +0 -0
- /package/dist/{chunk-EN5MEPAS.js.map → chunk-QGUP3QJF.js.map} +0 -0
- /package/dist/{chunk-MSUTHS2V.js.map → chunk-QZX7SYKU.js.map} +0 -0
- /package/dist/{chunk-BR3TNSO3.js.map → chunk-RGYDFBCT.js.map} +0 -0
- /package/dist/{chunk-4NAWM4OQ.js.map → chunk-S63LXWMC.js.map} +0 -0
- /package/dist/{chunk-RMMEYCEA.js.map → chunk-URXIQE7I.js.map} +0 -0
- /package/dist/{chunk-57YWAMNT.js.map → chunk-V5GLL2JB.js.map} +0 -0
- /package/dist/{chunk-VEBEGZUV.js.map → chunk-XATLUKXK.js.map} +0 -0
- /package/dist/{chunk-33ZKIYJM.js.map → chunk-XHPWTL4I.js.map} +0 -0
- /package/dist/{chunk-FL2CJ5T5.js.map → chunk-YRS3QZP2.js.map} +0 -0
- /package/dist/{chunk-FXL63LDL.js.map → chunk-ZVXGW2IC.js.map} +0 -0
- /package/dist/{load-agent-defs-57YKPVQW.js.map → load-agent-defs-7IM3GBEQ.js.map} +0 -0
- /package/dist/{recompile-project-agents-IQD3HRRS.js.map → recompile-project-agents-VR4NLGOU.js.map} +0 -0
- /package/dist/{source-loader-KAWB76OH.js.map → source-loader-GRBVNRAW.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/operations/source/load-source.ts","../src/cli/lib/operations/project/detect-project.ts","../src/cli/lib/operations/project/detect-both-installations.ts","../src/cli/lib/config-gate/propagate.ts","../../compile/src/config-source.ts","../src/cli/lib/config-gate/index.ts","../src/cli/lib/config-gate/classify.ts","../src/cli/lib/config-gate/deps.ts","../src/cli/lib/config-gate/pair-writer.ts","../src/cli/lib/config-gate/recompile.ts","../src/cli/lib/operations/project/write-project-config.ts","../src/cli/lib/operations/project/compile-agents-all-scopes.ts"],"sourcesContent":["import { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../../loading/index.js\";\nimport type { SourceCaller } from \"../../configuration/index.js\";\nimport {\n enableBuffering,\n drainBuffer,\n disableBuffering,\n type StartupMessage,\n} from \"../../../utils/logger.js\";\n\nexport type LoadSourceOptions = {\n /** Whether this load may reach the init-time source rungs — see {@link SourceCaller}. */\n caller?: SourceCaller;\n sourceFlag?: string;\n projectDir: string;\n /** When true, enables message buffering and captures startup messages. Default: false. */\n captureStartupMessages?: boolean;\n};\n\nexport type LoadedSource = {\n sourceResult: SourceLoadResult;\n /** Empty array when captureStartupMessages is false. */\n startupMessages: StartupMessage[];\n};\n\n/**\n * Loads the skills matrix from a resolved source.\n *\n * When `captureStartupMessages` is true, wraps the load in buffer mode so\n * warn() calls during loading are captured instead of written to stderr.\n * The caller (init/edit) hands them to the wizard, which paints them as a band\n * above the step — stderr does not survive the wizard clearing the terminal.\n *\n * @throws {Error} If source resolution or fetching fails.\n */\nexport async function loadSource(options: LoadSourceOptions): Promise<LoadedSource> {\n const { caller, sourceFlag, projectDir, captureStartupMessages } = options;\n\n if (captureStartupMessages) {\n enableBuffering();\n }\n\n let sourceResult: SourceLoadResult;\n try {\n sourceResult = await loadSkillsMatrixFromSource({\n ...(caller !== undefined && { caller }),\n ...(sourceFlag !== undefined && { sourceFlag }),\n projectDir,\n });\n } catch (error) {\n if (captureStartupMessages) {\n disableBuffering();\n }\n throw error;\n }\n\n let startupMessages: StartupMessage[] = [];\n if (captureStartupMessages) {\n startupMessages = drainBuffer();\n disableBuffering();\n }\n\n return { sourceResult, startupMessages };\n}\n","import { detectInstallation, type Installation } from \"../../installation/index.js\";\nimport { ConfigLoadError, loadProjectConfig } from \"../../configuration/index.js\";\nimport type { ProjectConfig } from \"../../../types/index.js\";\n\nexport type DetectedProject = {\n installation: Installation;\n config: ProjectConfig | null;\n configPath: string | null;\n};\n\n/**\n * Detects an existing CLI installation and loads its project config.\n *\n * Uses detectInstallation() which checks project-level first, then falls back\n * to global. Returns the installation metadata plus the loaded config.\n *\n * Does NOT throw. Returns null when no installation is found OR when the config\n * file exists but is corrupt — the caller (doctor, edit) reports the resulting\n * null as a config/installation problem to the user. `compile` deliberately\n * does NOT use this wrapper: it detects scopes directly so it can hard-error on\n * a corrupt config instead of degrading to null.\n */\nexport async function detectProject(projectDir?: string): Promise<DetectedProject | null> {\n const resolvedDir = projectDir ?? process.cwd();\n\n let installation: Installation | null;\n try {\n installation = await detectInstallation(resolvedDir);\n } catch (error) {\n if (error instanceof ConfigLoadError) return null;\n throw error;\n }\n\n if (!installation) {\n return null;\n }\n\n const loaded = await loadProjectConfig(installation.projectDir);\n\n return {\n installation,\n config: loaded?.config ?? null,\n configPath: loaded?.configPath ?? null,\n };\n}\n","import {\n detectGlobalInstallation,\n detectProjectInstallation,\n isHomeDirectory,\n type Installation,\n} from \"../../installation/index.js\";\n\nexport type BothInstallations = {\n global: Installation | null;\n project: Installation | null;\n hasBoth: boolean;\n};\n\n/**\n * Detects both global and project installations.\n *\n * Skips project detection when projectDir is the home directory\n * to avoid double-compile. Returns a convenience `hasBoth` flag\n * used by callers to set scopeFilter on compile passes.\n */\nexport async function detectBothInstallations(projectDir: string): Promise<BothInstallations> {\n const global = await detectGlobalInstallation();\n\n const project = isHomeDirectory(projectDir) ? null : await detectProjectInstallation(projectDir);\n return { global, project, hasBoth: !!global && !!project };\n}\n","import fs from \"fs\";\nimport { isDeepEqual, unique } from \"remeda\";\nimport type {\n AgentDefinition,\n AgentName,\n Category,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillAssignment,\n SkillId,\n StackAgentConfig,\n} from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { loadProjectConfigFromDir } from \"../configuration/project-config\";\nimport { mergeConfigs, type AuthoritativeScope } from \"../configuration/config-merger\";\nimport {\n activeProjectAgentNames,\n isActiveAt,\n isGlobalTombstone,\n type ScopedEntry,\n} from \"../configuration/scope-predicates\";\nimport { generateConfigSource, type ConfigSourceOptions } from \"../configuration/config-writer\";\nimport {\n buildConfigTypesBackgroundData,\n type ConfigTypesExtras,\n deriveCategories,\n deriveDomains,\n regenerateConfigTypes,\n} from \"../configuration/config-types-writer\";\n// The catalogue the renderers take as a parameter. It is the singleton this CLI seats at\n// startup, which is what `generateConfigSource` read directly before the renderers moved into\n// `@workspace/compile` and the editor became a second caller with a catalogue of its own.\nimport { matrix as activeMatrix } from \"../matrix/matrix-provider\";\nimport { fileExists, writeFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { GLOBAL_CONFIG_NAME, LOCAL_PSEUDO_CATEGORY } from \"../../consts\";\n\nexport async function writeConfigFile(\n config: ProjectConfig,\n configPath: string,\n options?: ConfigSourceOptions,\n): Promise<void> {\n const source = generateConfigSource(config, activeMatrix, options);\n await writeFile(configPath, source);\n}\n\n/**\n * Deep-additive stack merge: appends any (agent, category, skill) triple present in\n * `incoming` but missing in `existing`. Never removes or overwrites existing entries\n * (including their `preloaded` flags). Returns a fresh stack object — inputs are not\n * mutated. `changed` is true iff at least one new agent, category, or skill assignment\n * was appended.\n */\nfunction additiveMergeStack(\n existing: Partial<Record<AgentName, StackAgentConfig>> | undefined,\n incoming: Partial<Record<AgentName, StackAgentConfig>> | undefined,\n): { stack: Partial<Record<AgentName, StackAgentConfig>>; changed: boolean } {\n const merged: Partial<Record<AgentName, StackAgentConfig>> = existing\n ? structuredClone(existing)\n : {};\n if (!incoming) return { stack: merged, changed: false };\n\n let changed = false;\n for (const [agentName, incomingAgentStack] of typedEntries<AgentName, StackAgentConfig>(\n incoming,\n )) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!incomingAgentStack) continue;\n\n const existingAgentStack = merged[agentName];\n if (!existingAgentStack) {\n merged[agentName] = structuredClone(incomingAgentStack);\n changed = true;\n continue;\n }\n\n if (mergeAgentCategories(existingAgentStack, incomingAgentStack)) {\n changed = true;\n }\n }\n\n return { stack: merged, changed };\n}\n\n/**\n * Mutates `existingAgentStack` in place by appending any category or skill assignment\n * from `incomingAgentStack` that is not already present. Returns true if anything was\n * appended. Caller must pass a cloned `existingAgentStack` — this function is only\n * called on the merged copy, never on the original input.\n */\nfunction mergeAgentCategories(\n existingAgentStack: StackAgentConfig,\n incomingAgentStack: StackAgentConfig,\n): boolean {\n let changed = false;\n for (const [category, incomingAssignments] of typedEntries<Category, SkillAssignment[]>(\n incomingAgentStack,\n )) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!incomingAssignments) continue;\n\n const existingAssignments = existingAgentStack[category];\n if (!existingAssignments) {\n existingAgentStack[category] = incomingAssignments.map((a) => ({ ...a }));\n changed = true;\n continue;\n }\n\n const existingIds = new Set(existingAssignments.map((a) => a.id));\n for (const assignment of incomingAssignments) {\n if (!existingIds.has(assignment.id)) {\n existingAssignments.push({ ...assignment });\n existingIds.add(assignment.id);\n changed = true;\n }\n }\n }\n return changed;\n}\n\n/**\n * Merges new global-scoped items into an existing global config.\n * Adds skills/agents that don't already exist. Never removes existing items.\n *\n * Exported for unit testing. See `mergeGlobalConfigs` describe block in\n * `local-installer.test.ts`.\n */\nexport function mergeGlobalConfigs(\n existing: ProjectConfig,\n incoming: ProjectConfig,\n): { config: ProjectConfig; changed: boolean } {\n const existingSkillIds = new Set(existing.skills.map((s) => s.id));\n const existingAgentNames = new Set(existing.agents.map((a) => a.name));\n\n const incomingActiveSkills = incoming.skills.filter((s) => !s.excluded);\n const incomingActiveAgents = incoming.agents.filter((a) => !a.excluded);\n const newSkills = incomingActiveSkills.filter((s) => !existingSkillIds.has(s.id));\n const newAgents = incomingActiveAgents.filter((a) => !existingAgentNames.has(a.name));\n\n const mergedSkills = [...existing.skills, ...newSkills];\n const mergedAgents = [...existing.agents, ...newAgents];\n\n // Per-agent stack merge policy: deep-additive. Project-context edits must NEVER remove\n // or overwrite global state; individual projects express their local view via tombstones\n // in the PROJECT config, not by rewriting the GLOBAL config (see commit 403df46:\n // \"never modify global config from project-level operations\").\n //\n // Merge rule per triple (agent, category, skill):\n // - agent absent in existing -> add from incoming\n // - category absent in existing -> add from incoming\n // - skill id absent in existing -> append from incoming\n // - everything already present -> keep existing as-is (including its preloaded flag)\n // Anything present only in `existing` is left untouched.\n const { stack: mergedStack, changed: stackChanged } = additiveMergeStack(\n existing.stack,\n incoming.stack,\n );\n\n // Merge selected domains (union, no duplicates)\n const mergedSelectedDomains = [\n ...new Set([...(existing.selectedDomains ?? []), ...(incoming.selectedDomains ?? [])]),\n ];\n\n // Marketplace identity (`marketplace`, `marketplaceName`) travels on the global partition of\n // `splitConfigByScope` but was previously lost here, leaving the global config with no\n // record of where its plugins came from. `uninstall` reads `config.marketplaceName` to build\n // the `<id>@<marketplace name>` registry key (getCliInstalledPluginKeys) — without it a global\n // uninstall silently owns nothing and leaves registered plugins behind.\n //\n // Precedence is FILL-ONLY: existing wins, incoming is used solely when the global config\n // has no value yet. Both fields are scalar but the merged config is multi-marketplace by\n // construction — this merge never removes skills, so after a second project init from a\n // different marketplace the skills array holds plugins from BOTH, and whichever label is\n // recorded orphans the other's registry key. Repointing is therefore never a strict\n // improvement, and doing it from a project context would silently rewrite global state on\n // behalf of every other registered project (commit 403df46). This also matches\n // `mergeConfigs`, which preserves `existingConfig.marketplaceName` on the home-root install\n // path. Changing global marketplace identity stays an explicit global-scope operation\n // (`init` run from ~), which writes the global config directly and bypasses this merge.\n const mergedMarketplaceName = existing.marketplaceName ?? incoming.marketplaceName;\n const mergedMarketplace = existing.marketplace ?? incoming.marketplace;\n\n // Newly-filled marketplace identity must mark the merge dirty: this flag becomes\n // `resolveEffectiveGlobalConfig`'s `changed`, which is the condition `writeFromProjectContext`\n // (lib/config-gate/index.ts) tests before calling `writeGlobalPair`, so a run whose only delta\n // is the now-known marketplace would otherwise skip the global write and drop the field again.\n const changed =\n newSkills.length > 0 ||\n newAgents.length > 0 ||\n stackChanged ||\n !isDeepEqual(existing.selectedDomains ?? [], mergedSelectedDomains) ||\n mergedMarketplaceName !== existing.marketplaceName ||\n mergedMarketplace !== existing.marketplace;\n\n return {\n config: {\n ...existing,\n skills: mergedSkills,\n agents: mergedAgents,\n stack: mergedStack,\n selectedDomains: mergedSelectedDomains,\n ...(mergedMarketplaceName !== undefined && { marketplaceName: mergedMarketplaceName }),\n ...(mergedMarketplace !== undefined && { marketplace: mergedMarketplace }),\n },\n changed,\n };\n}\n\n/**\n * The single normalization for every value compared against the global config's\n * `projects` array — the one written by {@link registerProjectPath}, the one the\n * gate's `deregister-project` mutation filters against, and the current-project\n * skip in {@link propagateGlobalChangesToProjects}. Symlinks are resolved, so an entry\n * stored under one of them matches byte-for-byte under the others. The two ends\n * normalizing differently is what left symlinked layouts (macOS `/tmp`, a\n * `~/dev/repo` pointing at `/data/repo`) registered forever after an uninstall.\n *\n * Throws when the directory does not exist. That is deliberate: a path that\n * cannot be resolved is an error, not a cue to fall back to a weaker\n * normalization — a second tier would reintroduce exactly the asymmetry this\n * helper exists to remove. The one caller that must survive it (`uninstall`'s\n * deregistration) already wraps the call in a warn-and-continue guard.\n */\nexport function normalizeProjectPath(projectDir: string): string {\n return fs.realpathSync(projectDir);\n}\n\n/**\n * Registers a project directory in the global config's `projects` array.\n * Paths are normalized via {@link normalizeProjectPath} to resolve symlinks.\n * Filters stale entries (where .claude-src/config.ts no longer exists).\n */\nasync function registerProjectPath(\n globalConfig: ProjectConfig,\n projectDir: string,\n): Promise<{ config: ProjectConfig; changed: boolean }> {\n const normalizedPath = normalizeProjectPath(projectDir);\n const existing = globalConfig.projects ?? [];\n\n // Filter stale entries\n const staleChecks = await Promise.all(\n existing.map(async (p) => ({\n path: p,\n hasConfig: await fileExists(getProjectConfigPath(p)),\n })),\n );\n const valid = staleChecks.filter((c) => c.hasConfig).map((c) => c.path);\n\n if (valid.includes(normalizedPath)) {\n const changed = valid.length !== existing.length;\n return { config: changed ? { ...globalConfig, projects: valid } : globalConfig, changed };\n }\n\n return { config: { ...globalConfig, projects: [...valid, normalizedPath] }, changed: true };\n}\n\nfunction isProjectScopedEntry(entry: ScopedEntry): boolean {\n return entry.scope === \"project\";\n}\n\n/** True when the global config still has an active (non-excluded) skill for this id. */\nfunction globalHasActiveSkill(globalConfig: ProjectConfig, id: SkillId): boolean {\n return globalConfig.skills.some((s) => s.id === id && isActiveAt(s, \"global\"));\n}\n\n/** True when the global config still has an active (non-excluded) agent for this name. */\nfunction globalHasActiveAgent(globalConfig: ProjectConfig, name: AgentName): boolean {\n return globalConfig.agents.some((a) => a.name === name && isActiveAt(a, \"global\"));\n}\n\n/**\n * Keeps a project's own skill entries when re-inlining fresh global data, dropping\n * tombstones that no longer correspond to a real global install.\n *\n * A tombstone (`scope === \"global\" && excluded`) only has meaning while the global entry\n * it masks still exists. Once the skill has been removed from the global config, the\n * tombstone is stale — carrying it forward would leave the project showing a masked\n * global item that no longer exists. Project-scoped entries are always retained.\n */\nfunction retainProjectOwnedSkills(\n skills: SkillConfig[],\n globalConfig: ProjectConfig,\n): SkillConfig[] {\n return skills.filter(\n (entry) =>\n isProjectScopedEntry(entry) ||\n (isGlobalTombstone(entry) && globalHasActiveSkill(globalConfig, entry.id)),\n );\n}\n\n/** Agent mirror of {@link retainProjectOwnedSkills}. */\nfunction retainProjectOwnedAgents(\n agents: AgentScopeConfig[],\n globalConfig: ProjectConfig,\n): AgentScopeConfig[] {\n return agents.filter(\n (entry) =>\n isProjectScopedEntry(entry) ||\n (isGlobalTombstone(entry) && globalHasActiveAgent(globalConfig, entry.name)),\n );\n}\n\n/**\n * Category a skill belongs to according to the MERGED matrix. `undefined` when the\n * matrix has no entry for the id (a user-authored local skill carries no matrix\n * record) or when the entry sits in the `local` pseudo-category — neither\n * participates in category rules, and neither may throw.\n */\nfunction categoryOfSkill(id: SkillId, matrix: MergedSkillsMatrix): Category | undefined {\n const category = matrix.skills[id]?.category;\n if (category === undefined || category === LOCAL_PSEUDO_CATEGORY) return undefined;\n return category;\n}\n\n/**\n * True when the merged matrix DECLARES this category as holding at most one skill.\n * Read from the matrix passed in rather than `defaultCategories` so a source repo's\n * category overrides are honoured.\n *\n * A category the matrix does not declare is deliberately NOT treated as exclusive.\n * The wizard's toggle handler defaults an undeclared one to exclusive\n * (`use-build-step-props.ts` uses `matrix.categories[categoryId]?.exclusive ?? true`),\n * but a rule that MASKS persisted entries must only fire on a flag the data\n * actually carries.\n */\nfunction isExclusiveCategory(category: Category, matrix: MergedSkillsMatrix): boolean {\n return matrix.categories[category]?.exclusive === true;\n}\n\n/** Categories occupied by an active project-scoped skill, per the merged matrix. */\nfunction activeProjectCategories(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): Set<Category> {\n return new Set(\n projectOwnedSkills\n .filter((s) => isActiveAt(s, \"project\"))\n .map((s) => categoryOfSkill(s.id, matrix))\n .filter((category): category is Category => category !== undefined),\n );\n}\n\n/**\n * The collision that justifies masking a live global skill. Two kinds, both read from the\n * project's OWN entries: IDENTITY — the project owns the same id at project scope; CATEGORY —\n * the project owns a different active skill in the same category and the matrix declares that\n * category exclusive.\n *\n * Shared by the mask producer ({@link maskCollidingGlobalSkills}) and the self-heal that\n * removes a mask once its collision clears ({@link dropOrphanedDerivedMasks}), so the two can\n * never disagree about what a mask means.\n */\nfunction buildProjectCollisionTest(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): (id: SkillId) => boolean {\n const ownedIds = new Set(\n projectOwnedSkills.filter((s) => isActiveAt(s, \"project\")).map((s) => s.id),\n );\n const occupiedExclusiveCategories = new Set(\n [...activeProjectCategories(projectOwnedSkills, matrix)].filter((category) =>\n isExclusiveCategory(category, matrix),\n ),\n );\n\n return (id) => {\n if (ownedIds.has(id)) return true;\n const category = categoryOfSkill(id, matrix);\n return category !== undefined && occupiedExclusiveCategories.has(category);\n };\n}\n\n/**\n * Drops a derived mask that no longer masks anything, so the global install becomes\n * visible again once the collision that produced it is gone.\n *\n * A derived mask and a user-authored tombstone are BYTE-IDENTICAL in config.ts — both are\n * `{ id, scope: \"global\", excluded: true }` — but the wizard can no longer mint\n * the second kind on its own: a project-scope deselect of a globally-installed skill is\n * refused, and a domain deselect only drops what the project owns. The one user route to a\n * global tombstone is the `s` scope toggle (G→P), which always pairs the tombstone with an\n * active project entry for the same id — an IDENTITY collision. So every bare mask is\n * machine-derived, and a single retention test suffices: keep it iff the collision that\n * would re-derive it is still there.\n */\nfunction dropOrphanedDerivedMasks(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): SkillConfig[] {\n const collidesWithProjectOwnership = buildProjectCollisionTest(projectOwnedSkills, matrix);\n return projectOwnedSkills.filter(\n (entry) => !isGlobalTombstone(entry) || collidesWithProjectOwnership(entry.id),\n );\n}\n\n/**\n * Agent mirror of {@link dropOrphanedDerivedMasks}, identity collisions only: agents\n * have no categories, so the project-scoped sibling with the same name is the only thing a\n * mask can be justified by.\n */\nfunction dropOrphanedDerivedAgentMasks(projectOwnedAgents: AgentScopeConfig[]): AgentScopeConfig[] {\n const ownedNames = new Set(activeProjectAgentNames(projectOwnedAgents));\n return projectOwnedAgents.filter(\n (entry) => !isGlobalTombstone(entry) || ownedNames.has(entry.name),\n );\n}\n\n/**\n * Builds the tombstones that mask live global skills this project cannot show\n * alongside what it already owns at project scope. Two collision kinds, both keyed\n * against the SAME live global config:\n *\n * 1. IDENTITY — the project owns the same id at project scope. Without the\n * mask, `partitionInlinedConfigEntries` re-inlines the global copy as a SECOND\n * active entry, leaving one id active at BOTH scopes instead of rendering the\n * dual-scope `[P][G]` pair.\n * 2. CATEGORY — the project owns a DIFFERENT active skill in the same category and\n * the matrix declares that category exclusive. Reconciliation keyed on identity\n * alone cannot see this, so a project owning Vue plus a global install of React\n * ends up with two active skills in a category that permits one.\n *\n * The project-owned skill wins locally. This is DELIBERATELY ASYMMETRIC with the `s`\n * round trip, where a user-initiated radio swap in `toggleTechnology` refuses to displace a\n * globally-locked skill: there the user is actively trying to drop a shared install,\n * whereas here the collision is PUSHED IN by a global install landing on pre-existing\n * project state. Letting global win would silently uninstall the user's own skill.\n *\n * Tombstones are spread from the global entry so they carry the global install's\n * `origin`. A skill the project merely inherits (no active project-scope entry, no\n * exclusive-category collision) is skipped — it stays a single active global entry.\n * A skill the project already tombstones is skipped so re-running is idempotent.\n */\nfunction maskCollidingGlobalSkills(\n projectOwnedSkills: SkillConfig[],\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): SkillConfig[] {\n const collidesWithProjectOwnership = buildProjectCollisionTest(projectOwnedSkills, matrix);\n const alreadyTombstoned = new Set(projectOwnedSkills.filter(isGlobalTombstone).map((s) => s.id));\n\n return globalConfig.skills\n .filter(\n (globalEntry) =>\n isActiveAt(globalEntry, \"global\") &&\n collidesWithProjectOwnership(globalEntry.id) &&\n !alreadyTombstoned.has(globalEntry.id),\n )\n .map((globalEntry) => ({ ...globalEntry, excluded: true }));\n}\n\n/**\n * Agent mirror of {@link maskCollidingGlobalSkills}, identity collisions only.\n * Agents have no categories, so there is no grouping dimension to reconcile.\n */\nfunction maskCollidingGlobalAgents(\n projectOwnedAgents: AgentScopeConfig[],\n globalConfig: ProjectConfig,\n): AgentScopeConfig[] {\n const ownedNames = new Set(activeProjectAgentNames(projectOwnedAgents));\n const alreadyTombstoned = new Set(\n projectOwnedAgents.filter(isGlobalTombstone).map((a) => a.name),\n );\n\n return globalConfig.agents\n .filter(\n (globalEntry) =>\n isActiveAt(globalEntry, \"global\") &&\n ownedNames.has(globalEntry.name) &&\n !alreadyTombstoned.has(globalEntry.name),\n )\n .map((globalEntry) => ({ ...globalEntry, excluded: true }));\n}\n\n/**\n * Reconciles a project's OWN entries against the live global config, immediately\n * before the inlining writer merges the two.\n *\n * Applied at BOTH sites that write a project `config.ts` with `globalConfig` inlined:\n * `propagateGlobalChangesToProjects` (a global change fanning out to registered\n * projects) and the project-scope save branch of `writeScopedFromWizard` (an ordinary\n * project `init`/`edit` performed while the colliding skill is already active\n * globally). Either site alone can produce the malformed shape, so both must run it.\n *\n * Self-heal runs BEFORE masking on BOTH axes so a mask whose collision has cleared is\n * removed rather than immediately re-derived, and so masking's `alreadyTombstoned` guard\n * only sees tombstones that are still warranted.\n *\n * Masking is PROJECT-LOCAL: it is applied to the project split only. The global\n * config passed in is read, never rewritten — tombstones never belong in\n * `~/.claude-src/config.ts`.\n */\nexport function reconcileProjectSplitAgainstGlobal(\n projectSplit: ProjectConfig,\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): ProjectConfig {\n const healedSkills = dropOrphanedDerivedMasks(projectSplit.skills, matrix);\n const healedAgents = dropOrphanedDerivedAgentMasks(projectSplit.agents);\n return {\n ...projectSplit,\n skills: [...healedSkills, ...maskCollidingGlobalSkills(healedSkills, globalConfig, matrix)],\n agents: [...healedAgents, ...maskCollidingGlobalAgents(healedAgents, globalConfig)],\n };\n}\n\n/**\n * Computes the skill ids that this project inherited from global scope but that are\n * no longer active at global scope after the change being propagated — and that the\n * project does not own at project scope. These are the only ids that should be pruned\n * from the project's stack: a project-scoped agent may legitimately reference a\n * globally-installed skill, and once that skill is removed at global scope the\n * reference becomes dangling.\n *\n * `priorProjectSkills` is the project's pre-reconciliation (on-disk, inlined) skills.\n * A global skill that was just removed still appears here as a `scope: \"global\"`,\n * non-excluded entry, which is the signal we key on. Project-scoped skills and\n * user-authored local skills (which carry no SkillConfig entry at all) are never in\n * this set, so they are always preserved.\n */\nfunction computeRemovedGlobalSkillIds(\n priorProjectSkills: SkillConfig[],\n globalConfig: ProjectConfig,\n): Set<SkillId> {\n const activeGlobalIds = new Set(\n globalConfig.skills.filter((s) => isActiveAt(s, \"global\")).map((s) => s.id),\n );\n const projectOwnedIds = new Set(\n priorProjectSkills.filter((s) => isActiveAt(s, \"project\")).map((s) => s.id),\n );\n return new Set(\n priorProjectSkills\n .filter(\n (s) =>\n s.scope === \"global\" &&\n !s.excluded &&\n !activeGlobalIds.has(s.id) &&\n !projectOwnedIds.has(s.id),\n )\n .map((s) => s.id),\n );\n}\n\n/**\n * Prunes stack references to global skills that were just removed at global scope,\n * so a project-scoped agent stops referencing a skill that no longer exists anywhere.\n * Only ids in `removedGlobalSkillIds` are dropped — every other assignment is kept\n * verbatim, in order, with its `preloaded` flag untouched. Categories and agents left\n * empty by the pruning are removed. When nothing was removed, the stack is returned\n * unchanged so unaffected projects produce byte-identical config output.\n */\nfunction retainReconciledStack(\n stack: Record<string, StackAgentConfig> | undefined,\n removedGlobalSkillIds: Set<SkillId>,\n): Record<string, StackAgentConfig> | undefined {\n if (!stack || removedGlobalSkillIds.size === 0) return stack;\n\n const reconciled: Record<string, StackAgentConfig> = {};\n for (const [agent, agentStack] of Object.entries(stack)) {\n const reconciledAgentStack: StackAgentConfig = {};\n for (const [category, assignments] of typedEntries<Category, SkillAssignment[]>(agentStack)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!assignments) continue;\n const kept = assignments.filter((assignment) => !removedGlobalSkillIds.has(assignment.id));\n if (kept.length > 0) reconciledAgentStack[category] = kept;\n }\n if (typedKeys<Category>(reconciledAgentStack).length > 0) {\n reconciled[agent] = reconciledAgentStack;\n }\n }\n return reconciled;\n}\n\n/** The registered projects one fan-out rewrote, and the ones it could not reach. */\nexport type PropagationResult = {\n updated: string[];\n skipped: string[];\n};\n\nexport type PropagationOptions = {\n /**\n * Whether each project's config-types.ts is rewritten alongside its config.ts.\n * False for a change that moves no type union — a project inlines the global\n * scalars into its config half, but no union is derived from them.\n */\n regenerateTypes?: boolean;\n};\n\n/**\n * The single writer for a project's config pair, used by BOTH sites that emit\n * one: the per-project propagation step below and the project branch of the\n * wizard write.\n *\n * `buildProjectTypesExtras` is fed the EFFECTIVE config — the project's own\n * reconciled rows plus the active global rows the writer is about to inline —\n * at both sites. The emitted config.ts names every one of those rows, so extras\n * derived from the project split alone declare fewer literals than the sibling\n * config.ts uses, and the pair stops type-checking against itself.\n */\nexport async function writeProjectConfigPair(\n projectDir: string,\n reconciledSplit: ProjectConfig,\n effectiveGlobal: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n options: PropagationOptions = {},\n): Promise<void> {\n // Reconcile-before-both-writes: the two halves are derived from the same\n // reconciled data in the same call, so neither can describe a config the other\n // does not.\n await writeConfigFile(reconciledSplit, getProjectConfigPath(projectDir), {\n isProjectConfig: true,\n globalConfig: effectiveGlobal,\n });\n\n if (options.regenerateTypes === false) return;\n\n // Uses the same global-aware path for project types — emits\n // `import type { SkillId as GlobalSkillId, ... }` and extends with any\n // project-scoped items the project owns. Without this, a global-scope install\n // would overwrite the project's import-form types with the standalone/inlined\n // form.\n await regenerateConfigTypes(\n projectDir,\n Promise.resolve(buildConfigTypesBackgroundData(matrix, agents)),\n buildProjectTypesExtras(inlinedProjectView(reconciledSplit, effectiveGlobal), matrix),\n );\n}\n\n/**\n * The rows the inlining writer draws a project's config.ts from: the project's\n * own reconciled entries plus everything the global config contributes. Union\n * membership is decided downstream by `buildProjectTypesExtras`, which reads the\n * active entries — a tombstone's id always arrives via the live global row it\n * masks.\n */\nfunction inlinedProjectView(\n reconciledSplit: ProjectConfig,\n effectiveGlobal: ProjectConfig,\n): ProjectConfig {\n return {\n ...reconciledSplit,\n skills: [...effectiveGlobal.skills, ...reconciledSplit.skills],\n agents: [...effectiveGlobal.agents, ...reconciledSplit.agents],\n selectedDomains: unique([\n ...(effectiveGlobal.selectedDomains ?? []),\n ...(reconciledSplit.selectedDomains ?? []),\n ]),\n stack: { ...(effectiveGlobal.stack ?? {}), ...(reconciledSplit.stack ?? {}) },\n };\n}\n\n/**\n * Propagates global config changes to all registered project configs.\n * Updates each project's config-types.ts (type unions) and config.ts (inlined global data).\n * Skips stale project paths and the current project being installed.\n */\nexport async function propagateGlobalChangesToProjects(\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n currentProjectDir?: string,\n options: PropagationOptions = {},\n): Promise<PropagationResult> {\n const projects = globalConfig.projects ?? [];\n if (projects.length === 0) return { updated: [], skipped: [] };\n\n const currentNormalized = currentProjectDir ? normalizeProjectPath(currentProjectDir) : null;\n const updated: string[] = [];\n const skipped: string[] = [];\n\n for (const projectPath of projects) {\n // Skip the project currently being installed (it's already being written)\n if (currentNormalized && projectPath === currentNormalized) continue;\n\n const projectConfigPath = getProjectConfigPath(projectPath);\n if (!(await fileExists(projectConfigPath))) {\n skipped.push(projectPath);\n verbose(`Skipped propagation to ${projectPath} (config not found)`);\n continue;\n }\n\n try {\n const existingProject = await loadProjectConfigFromDir(projectPath);\n if (!existingProject?.config) {\n skipped.push(projectPath);\n continue;\n }\n\n const projectConfig = existingProject.config;\n\n // Derive project split: project-scoped entries plus tombstones that still\n // correspond to a live global install. Tombstones whose global entry has been\n // removed are dropped here so the project stops referencing a global item that\n // no longer exists. The stack is reconciled against the same\n // now-current global data so a project-scoped agent stops referencing a global\n // skill that was just removed at global scope. `projectConfig.skills` (pre-\n // reconciliation) is used to detect removed globals because the removed entry\n // is still present here as a `scope: \"global\"` reference.\n const removedGlobalSkillIds = computeRemovedGlobalSkillIds(\n projectConfig.skills,\n globalConfig,\n );\n const retained = retainReconciledStack(projectConfig.stack, removedGlobalSkillIds);\n const reconciledStack = retained === undefined ? {} : { stack: retained };\n const projectSplit = reconcileProjectSplitAgainstGlobal(\n {\n ...projectConfig,\n skills: retainProjectOwnedSkills(projectConfig.skills, globalConfig),\n agents: retainProjectOwnedAgents(projectConfig.agents, globalConfig),\n ...reconciledStack,\n },\n globalConfig,\n matrix,\n );\n\n await writeProjectConfigPair(projectPath, projectSplit, globalConfig, matrix, agents, {\n regenerateTypes: options.regenerateTypes ?? true,\n });\n\n updated.push(projectPath);\n verbose(`Propagated global changes to ${projectPath}`);\n } catch (error) {\n skipped.push(projectPath);\n verbose(`Failed to propagate to ${projectPath}: ${getErrorMessage(error)}`);\n }\n }\n\n return { updated, skipped };\n}\n\n/**\n * Prunes CLI-inlined global-scoped entries from every registered project after a\n * GLOBAL uninstall. Reuses {@link propagateGlobalChangesToProjects} with an\n * emptied global config so every global skill/agent reads as removed: project-\n * scoped entries are retained verbatim, inlined global rows and tombstones are\n * dropped, per-agent stack refs lose their global-only ids, and each project's\n * config-types.ts is regenerated.\n *\n * Call AFTER the global .claude-src manifest has been removed so the regenerated\n * project types fall back to the standalone form instead of importing from the\n * now-deleted global config-types.ts. Unreachable project dirs are reported in\n * `skipped`, never thrown.\n */\nexport async function pruneGlobalEntriesFromRegisteredProjects(\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): Promise<{ updated: string[]; skipped: string[] }> {\n const emptiedGlobal: ProjectConfig = {\n ...globalConfig,\n skills: [],\n agents: [],\n };\n return propagateGlobalChangesToProjects(emptiedGlobal, matrix, agents);\n}\n\n/** What one resolution decided: the config to commit, and the two flags that gate the write. */\ntype ResolvedGlobalConfig = { config: ProjectConfig; changed: boolean };\n\n/**\n * Resolves the global config a project install should write, and registers this project's path.\n * `globalDataChanged` gates propagation; `changed` gates the write itself.\n *\n * `authority` is `mergeConfigs`' own word for how much of what it can see the session owns, and\n * it selects between the two resolutions below. Absent, or `\"owned\"`, keeps the standing\n * additive behaviour.\n */\nexport async function resolveEffectiveGlobalConfig(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n projectDir: string,\n authority?: AuthoritativeScope,\n): Promise<{ config: ProjectConfig; globalDataChanged: boolean; changed: boolean }> {\n const merged =\n authority === \"all\"\n ? matchGlobalToSession(globalSplit, existingGlobalConfig)\n : addSessionToGlobal(globalSplit, existingGlobalConfig);\n\n const registration = await registerProjectPath(merged.config, projectDir);\n return {\n config: registration.config,\n globalDataChanged: merged.changed,\n changed: merged.changed || registration.changed,\n };\n}\n\n/**\n * The standing resolution, and the one every caller but `edit --from` gets: the session's global\n * items are ADDED and nothing is taken away.\n *\n * A project install has asked nobody about the machine, so it may not decide for it (commit\n * 403df46, \"never modify global config from project-level operations\"). The `hasGlobalItems`\n * shortcut is part of that: a session carrying nothing global is not a statement that the global\n * install should be empty.\n */\nfunction addSessionToGlobal(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n): ResolvedGlobalConfig {\n const hasGlobalItems = globalSplit.skills.length > 0 || globalSplit.agents.length > 0;\n if (!hasGlobalItems) {\n return {\n config: existingGlobalConfig ?? { name: GLOBAL_CONFIG_NAME, skills: [], agents: [] },\n changed: false,\n };\n }\n\n if (!existingGlobalConfig) return { config: globalSplit, changed: true };\n return mergeGlobalConfigs(existingGlobalConfig, globalSplit);\n}\n\n/**\n * The resolution for a session that owns every scope it can see: the global config is made to\n * MATCH it, so a global entry the session left out is REMOVED rather than preserved.\n *\n * One caller reaches this — a confirmed `edit --from` — and it is not acting on its own\n * initiative: it states a whole roster, its plan showed every global removal under its own\n * heading, named every other registered project the removal reaches, and somebody answered yes.\n * Nothing else in the CLI may write the global config from a project, and this does not widen\n * that: the word arrives from the command, not from the shape of the data.\n *\n * `mergeConfigs` is what does it rather than a merge of this module's own, because \"absent from\n * the session means deselected\" is exactly what `authoritativeScope: \"all\"` already means at the\n * home root. It carries the global installation's identity, its stack fallback and its\n * `projects[]` registry across — a session's split says nothing about who the global\n * installation is or which projects read it, and the fan-out walks that registry.\n *\n * An empty session is a real answer here, so there is no `hasGlobalItems` shortcut: a\n * configuration that installs nothing globally removes what was.\n */\nfunction matchGlobalToSession(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n): ResolvedGlobalConfig {\n if (!existingGlobalConfig) return { config: globalSplit, changed: true };\n\n const config = mergeConfigs(globalSplit, existingGlobalConfig, { authoritativeScope: \"all\" });\n return { config, changed: !isDeepEqual(config, existingGlobalConfig) };\n}\n\n/** Category keys the emitted stack holds, across every agent it configures. */\nfunction stackCategories(stack: ProjectConfig[\"stack\"]): Category[] {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n return Object.values(stack ?? {}).flatMap((agentStack) => typedKeys<Category>(agentStack ?? {}));\n}\n\n/**\n * Derives the extras for regenerateConfigTypes so a project's config-types.ts declares every\n * literal its sibling config.ts holds — the two are written from the same config and must not\n * be able to disagree.\n *\n * ALL active (non-excluded) entries, not just project-scoped ones:\n * generateProjectConfigWithInlinedGlobal writes the active global rows into the project's own\n * config.ts verbatim, and the imported Global* unions cover those rows only for as long as the\n * global config still happens to contain them. A later global-scope run narrows those unions\n * and a project nobody touched stops type-checking (TS2322 on a skill id or domain, TS2353 on a\n * stack's category key).\n *\n * Domains and stack categories are read off the config's own arrays as well as derived from its\n * skill rows: `selectedDomains` is a wizard preference no skill row has to back, and neither it\n * nor a stack entry is pruned when the last skill that would derive it leaves.\n */\nexport function buildProjectTypesExtras(\n finalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): Required<ConfigTypesExtras> {\n const activeSkills = finalConfig.skills.filter((s) => !s.excluded);\n const activeAgents = finalConfig.agents.filter((a) => !a.excluded);\n\n const extraSkillIds = unique(activeSkills.map((s) => s.id));\n const extraAgentNames = unique(activeAgents.map((a) => a.name));\n\n const extraCategories = unique([\n ...deriveCategories(extraSkillIds, matrix),\n ...stackCategories(finalConfig.stack),\n ]);\n const extraDomains = unique([\n ...deriveDomains(extraCategories, matrix),\n ...(finalConfig.selectedDomains ?? []),\n ]);\n\n return { extraSkillIds, extraAgentNames, extraDomains, extraCategories };\n}\n","import {\n byCategoryDeclarationOrder,\n isExclusiveCategory,\n type CompileCatalog,\n} from \"./catalog.js\"\nimport {\n INDENT_STEP,\n commentEntry,\n isKeyedRecord,\n quoteText,\n renderArrayLine,\n renderKey,\n renderTypeImportLine,\n renderValueLine,\n sourceEntry,\n valueEntries,\n type ArrayEntry,\n type LinePosition,\n} from \"./installed-format.js\"\nimport { DEFAULT_PLUGIN_NAME, GLOBAL_CONFIG_NAME } from \"./paths.js\"\nimport type {\n AgentScopeConfig,\n ProjectConfig,\n SkillAssignment,\n SkillConfig,\n} from \"./types.js\"\n\n/**\n * This module renders `config.ts` sources; it writes nothing, and neither does\n * anything it is called from. Putting either half of a config pair on disk is\n * `config-gate/`'s exclusive privilege in the CLI, because that write owes\n * consequences no caller can be relied on to remember — a rendered half any\n * caller may then write is exactly the ungated write the gate exists to prevent.\n */\n\n/**\n * Which of the three emissions is wanted.\n *\n * At least one of `globalConfig` and `globalImportPath` accompanies\n * `isProjectConfig: true`, and {@link generateProjectConfig} enforces it —\n * `globalConfig` wins where both are given. The invalid pairing is refused at\n * runtime rather than made unrepresentable, which is the repository's usual\n * answer and was measured before it was rejected: the discrimination has to be\n * on `isProjectConfig`'s LITERAL type, and an un-annotated `const options = cond\n * ? { isProjectConfig: true, globalConfig } : undefined` widens that property to\n * `boolean`, so the call stops compiling with a message about inference rather\n * than about the mistake. It costs a file the union's author never opened — the\n * same shape as the Storybook-args collapse in\n * `.ai-docs/agent-findings/2026-08-26-a-discriminated-union-on-component-props-collapses-storybook-args-to-never.md`.\n */\nexport type ConfigSourceOptions = {\n /**\n * When true, generates a project config — inlining the global config's entries\n * when `globalConfig` is given, importing and spreading them when\n * `globalImportPath` is.\n */\n isProjectConfig?: boolean\n\n /**\n * When provided alongside `isProjectConfig`, inlines global skills/agents directly.\n * Produces a self-contained, readable config snapshot.\n */\n globalConfig?: ProjectConfig\n\n /**\n * Absolute path to the global `.claude-src/`, for the spread form that imports\n * from it rather than inlining it.\n *\n * A PARAMETER rather than a read, because the value is `os.homedir()` and this\n * package runs in a browser. `getGlobalConfigImportPath()` in the CLI's\n * `config-writer.ts` is the one producer, and it has no production caller:\n * `writeProjectConfigPair` is the only site passing `isProjectConfig` and it\n * always passes `globalConfig` too, which takes the inlining branch above.\n */\n globalImportPath?: string\n}\n\n/** Fields that are extracted into typed named variables above the export default */\nconst EXTRACTED_FIELDS = new Set([\n \"skills\",\n \"agents\",\n \"stack\",\n \"selectedDomains\",\n])\n\n/**\n * The loader schema's own field order, which is the order a config read back off\n * disk arrives in. Emitting in it is what makes the writer a fixed point: the\n * three producers of an in-memory config — the wizard's literal, a Zod-parsed\n * load, a merge that appends at the tail — insert their keys in three different\n * orders, and without this the same values would emit as three different files.\n */\nconst CANONICAL_FIELD_ORDER = [\n \"name\",\n \"description\",\n \"agents\",\n \"skills\",\n \"author\",\n \"selectedDomains\",\n \"stack\",\n \"marketplace\",\n \"marketplaceName\",\n \"agentsSource\",\n \"projects\",\n] as const satisfies readonly (keyof ProjectConfig)[]\n\n/**\n * The same rule one level in, for the three record shapes a config carries\n * INSIDE an array. {@link CANONICAL_FIELD_ORDER} reaches the top-level fields\n * and {@link canonicalizeStackOrder} reaches the stack's keys; an entry's own\n * keys were left to whoever minted it, and the printer emits a record's keys in\n * the order it is handed them, so they reached disk in the producer's own.\n *\n * The loader rebuilds every entry through its schema, so a producer that\n * disagrees with the schema is not a fixed point: `toggleSkillScope` mints a\n * tombstone as `{ id, scope, excluded, origin }`, and re-emitting the same\n * config after a load moved the line. An `edit` run that changed nothing about\n * that skill still rewrote it, and a second implementation drawing these bytes\n * drew a line no install writes.\n */\nconst CANONICAL_SKILL_ENTRY_ORDER = [\n \"id\",\n \"scope\",\n \"origin\",\n \"excluded\",\n] as const satisfies readonly (keyof SkillConfig)[]\n\nconst CANONICAL_AGENT_ENTRY_ORDER = [\n \"name\",\n \"scope\",\n \"model\",\n \"effort\",\n \"excluded\",\n] as const satisfies readonly (keyof AgentScopeConfig)[]\n\nconst CANONICAL_ASSIGNMENT_ORDER = [\n \"id\",\n \"preloaded\",\n \"local\",\n \"path\",\n] as const satisfies readonly (keyof SkillAssignment)[]\n\n/**\n * A record rebuilt with the keys the schema names first and in its order. A key\n * the schema does not name is passthrough data the writer has no order of its\n * own to impose, so those keep the order they arrived in, after every named one.\n */\nfunction withKeysInSchemaOrder(\n record: Record<string, unknown>,\n schemaOrder: readonly string[]\n): Record<string, unknown> {\n const named = new Set<string>(schemaOrder)\n const inSchemaOrder = schemaOrder\n .filter((key) => key in record)\n .map((key): [string, unknown] => [key, record[key]])\n const passthrough = Object.entries(record).filter(([key]) => !named.has(key))\n\n return Object.fromEntries([...inSchemaOrder, ...passthrough])\n}\n\n/** The cleaned config rebuilt in the loader schema's top-level field order. */\nfunction canonicalizeFieldOrder(\n cleaned: Record<string, unknown>\n): Record<string, unknown> {\n return withKeysInSchemaOrder(cleaned, CANONICAL_FIELD_ORDER)\n}\n\n/**\n * The cleaned config with the elements of `skills` and `agents` rebuilt in their\n * own schema's key order.\n *\n * An array the config does not carry stays absent: assigning would mint the key,\n * and the emission tells an absent array from an empty one.\n */\nfunction withEntriesInSchemaOrder(\n cleaned: Record<string, unknown>\n): Record<string, unknown> {\n const reordered = { ...cleaned }\n if (Array.isArray(reordered.skills)) {\n reordered.skills = entriesInSchemaOrder(\n reordered.skills,\n CANONICAL_SKILL_ENTRY_ORDER\n )\n }\n if (Array.isArray(reordered.agents)) {\n reordered.agents = entriesInSchemaOrder(\n reordered.agents,\n CANONICAL_AGENT_ENTRY_ORDER\n )\n }\n return reordered\n}\n\n/**\n * Every element of one entry array rebuilt in the schema's key order. The writer\n * emits whatever it is handed, and these arrive off a `JSON.parse`, so an\n * element that is not a keyed record has no keys to order and passes through\n * whole rather than being flattened by `Object.entries`.\n */\nfunction entriesInSchemaOrder(\n entries: unknown[],\n schemaOrder: readonly string[]\n): unknown[] {\n return entries.map((entry: unknown) =>\n isKeyedRecord(entry) ? withKeysInSchemaOrder(entry, schemaOrder) : entry\n )\n}\n\n/** A record rebuilt with its keys reordered; the values themselves are untouched. */\nfunction withKeysOrderedBy<T>(\n record: Record<string, T>,\n compareKeys: (a: string, b: string) => number\n): Record<string, T> {\n return Object.fromEntries(\n Object.entries(record).sort(([a], [b]) => compareKeys(a, b))\n )\n}\n\n/**\n * Code-unit order over two names — what a bare `.sort()` gives, and so what\n * `generateProjectConfigFromSkills` already emits its sub-agent keys in.\n * `localeCompare` is deliberately not used: it orders the same two names\n * differently under different locales, which would make the emitted bytes a\n * property of the machine.\n */\nfunction compareNamesInCodeUnitOrder(a: string, b: string): number {\n if (a === b) return 0\n return a < b ? -1 : 1\n}\n\n/**\n * The stack's key order, decided by the roster rather than by whoever assembled\n * the stack: sub-agents by name, and each sub-agent's categories in the\n * catalogue's declaration order — the two orders the generator already builds a\n * stack in.\n *\n * The generator is not the only producer. The seed decode assembles a stack from\n * a shared payload, in the order that payload lists its skills, so the same\n * curation reached disk as different bytes depending on which end of a share\n * round trip wrote it. That is not merely a noisy diff: a compiled sub-agent\n * lists its dynamic skills in the order its stack entry carries them, so the two\n * ends compiled different files from identical configuration.\n */\nfunction canonicalizeStackOrder(\n stack: Record<string, Record<string, unknown>>,\n catalog: CompileCatalog\n): Record<string, Record<string, unknown>> {\n const byDeclaration = byCategoryDeclarationOrder(catalog)\n const withCategoriesInOrder = Object.entries(stack).map(\n ([agent, categories]) =>\n [agent, withKeysOrderedBy(categories, byDeclaration)] as const\n )\n\n return withKeysOrderedBy(\n Object.fromEntries(withCategoriesInOrder),\n compareNamesInCodeUnitOrder\n )\n}\n\n/** The specifier both emitted config roots import their types from. */\nconst CONFIG_TYPES_SPECIFIER = \"./config-types\"\n\n/** The annotation the emitted `stack` declaration carries. */\nconst STACK_TYPE = \"Partial<Record<ProjectAgentName, StackAgentConfig>>\"\n\n/** Where a top-level `const <name>: <type> = …` declaration puts its value. */\nfunction declarationPosition(name: string, type: string): LinePosition {\n return { indent: 0, prefix: `const ${name}: ${type} = `, suffix: \"\" }\n}\n\n/**\n * One `const <name>: <type> = <value>` declaration, and the blank line the\n * writer puts before it. Both together, because every declaration is separated\n * from the last and the emitted pair's readers key on that blank line.\n */\nfunction declaration(name: string, type: string, value: unknown): string[] {\n return [\"\", renderValueLine(value, declarationPosition(name, type))]\n}\n\n/** The same, for an array whose entries carry comments or written-out source. */\nfunction entryDeclaration(\n name: string,\n type: string,\n entries: readonly ArrayEntry[]\n): string[] {\n return [\"\", renderArrayLine(entries, declarationPosition(name, type))]\n}\n\n/** Where one property of the `export default` table of contents sits. */\nfunction exportFieldPosition(key: string): LinePosition {\n return {\n indent: INDENT_STEP,\n prefix: `${renderKey(key)}: `,\n suffix: \",\",\n }\n}\n\n/** One scalar field as a line of the `export default` table of contents. */\nfunction renderScalarField(key: string, value: unknown): string {\n return renderValueLine(value, exportFieldPosition(key))\n}\n\ntype ConfigArrays = {\n skills: unknown[]\n agents: unknown[]\n stack: Record<string, unknown> | undefined\n selectedDomains: unknown[]\n}\n\n/** The four extracted array/stack fields of a cleaned config, defaulted for emission. */\nfunction extractConfigArrays(cleaned: Record<string, unknown>): ConfigArrays {\n // Boundary cast: cleaned comes from JSON.parse(JSON.stringify(...)) so arrays are plain JSON\n // values. The `??` runs BEFORE the cast on purpose — `cleaned` is a Record of `unknown`, and\n // casting first would tell the checker the value is present when the round-trip drops any key\n // whose value was undefined.\n return {\n skills: (cleaned.skills ?? []) as unknown[],\n agents: (cleaned.agents ?? []) as unknown[],\n stack: cleaned.stack as Record<string, unknown> | undefined,\n selectedDomains: (cleaned.selectedDomains ?? []) as unknown[],\n }\n}\n\n/**\n * Shared pre-emission cleanup: JSON round-trip (drops undefined values), optional\n * `projects` removal (project configs never emit the global tracking list),\n * stack compaction (strip flag-less assignments to bare strings while preserving\n * SkillAssignment[] arrays), and canonical key ordering at all three levels the\n * emitted bytes expose — the top-level fields, the stack's own keys, and each\n * entry inside the `skills`, `agents` and stack-assignment arrays. Every level\n * is ordered here rather than by its producer, so the bytes are decided by the\n * config's values alone.\n */\nfunction cleanForEmission(\n config: ProjectConfig,\n catalog: CompileCatalog,\n options: { dropProjects: boolean }\n): Record<string, unknown> {\n // Boundary cast: `JSON.parse` is typed `any`, and round-tripping an object always\n // yields one — dropping its undefined-valued keys is exactly why this is here.\n const cleaned = JSON.parse(JSON.stringify(config)) as Record<string, unknown>\n if (options.dropProjects) {\n delete cleaned.projects\n }\n if (cleaned.stack) {\n // Boundary cast: cleaned comes from JSON.parse(JSON.stringify(...)), so the stack\n // is a plain JSON record of agent -> category -> assignment arrays\n const compacted = compactStackAssignments(\n cleaned.stack as Record<string, Record<string, unknown[]>>,\n catalog\n )\n cleaned.stack = canonicalizeStackOrder(compacted, catalog)\n }\n return canonicalizeFieldOrder(withEntriesInSchemaOrder(cleaned))\n}\n\n/**\n * Generates a TypeScript config file source from a ProjectConfig object.\n * The typed named variables (skills, agents, stack, selectedDomains) are declared\n * first, with the export default below them acting as a table of contents that\n * refers to each by name.\n *\n * The catalogue is a parameter and never a module this file reaches: the bytes\n * depend on which categories are exclusive and on the order the catalogue\n * declares them, so a renderer reading a singleton would answer differently in\n * the CLI (which merges the machine's local skills in) and in the editor.\n */\nexport function generateConfigSource(\n config: ProjectConfig,\n catalog: CompileCatalog,\n options?: ConfigSourceOptions\n): string {\n if (options?.isProjectConfig) {\n return generateProjectConfig(config, catalog, options)\n }\n\n return generateStandaloneConfig(\n cleanForEmission(config, catalog, { dropProjects: false })\n )\n}\n\n/**\n * The project emission the options name — inlining the global config's entries,\n * or importing and spreading them.\n *\n * Those are the only two, so naming neither is refused rather than answered.\n * Falling through to the standalone writer answered a project request with a\n * GLOBAL-shaped file: `dropProjects` is false there, so the emitted config\n * carries the global `projects` tracking array, which a project root must never\n * hold. Nothing in the CLI reaches this today, but `generateConfigSource` is a\n * public export of this package and the caller that cannot be seen from here is\n * the editor's.\n */\nfunction generateProjectConfig(\n config: ProjectConfig,\n catalog: CompileCatalog,\n options: ConfigSourceOptions\n): string {\n const cleaned = cleanForEmission(config, catalog, { dropProjects: true })\n\n if (options.globalConfig) {\n return generateProjectConfigWithInlinedGlobal(\n cleaned,\n cleanForEmission(options.globalConfig, catalog, { dropProjects: true })\n )\n }\n if (options.globalImportPath !== undefined) {\n return generateProjectConfigWithGlobalImport(\n cleaned,\n options.globalImportPath\n )\n }\n\n throw new Error(\n \"A project config needs the global config it extends: pass `globalConfig` to inline its \" +\n \"entries, or `globalImportPath` to import and spread them. Neither was given, and the \" +\n \"standalone writer this used to fall through to emits a global-shaped config carrying \" +\n \"the `projects` tracking array a project root must never hold.\"\n )\n}\n\n/**\n * Generates a project config source that imports from the global config and extends it.\n * Typed named variables are declared above the export default. The export default at\n * the bottom acts as a table of contents. Arrays (skills, agents, selectedDomains) are\n * spread with globalConfig first, then project items.\n */\nfunction generateProjectConfigWithGlobalImport(\n cleaned: Record<string, unknown>,\n globalImportPath: string\n): string {\n const importPath = `${globalImportPath}/config`\n\n const { skills, agents, stack, selectedDomains } =\n extractConfigArrays(cleaned)\n\n const hasProjectDomains = selectedDomains.length > 0\n const hasStack = stack != null && Object.keys(stack).length > 0\n\n const typeImports = buildTypeImports({\n // Always present, spread from global.\n hasSkills: true,\n hasAgents: true,\n hasStack,\n hasSelectedDomains: hasProjectDomains,\n })\n\n const lines: string[] = [\n `import globalConfig from ${quoteText(importPath)}`,\n renderTypeImportLine(typeImports, CONFIG_TYPES_SPECIFIER),\n ]\n\n lines.push(\n ...entryDeclaration(\"skills\", \"SkillConfig[]\", [\n sourceEntry(\"...globalConfig.skills\"),\n ...valueEntries(skills),\n ])\n )\n lines.push(\n ...entryDeclaration(\"agents\", \"AgentScopeConfig[]\", [\n sourceEntry(\"...globalConfig.agents\"),\n ...valueEntries(agents),\n ])\n )\n\n if (hasStack) {\n lines.push(...declaration(\"stack\", STACK_TYPE, stack))\n }\n\n if (hasProjectDomains) {\n lines.push(\n ...entryDeclaration(\"selectedDomains\", \"Domain[]\", [\n sourceEntry(\"...(globalConfig.selectedDomains ?? [])\"),\n ...valueEntries(selectedDomains),\n ])\n )\n }\n\n const scalarFields = Object.entries(cleaned)\n .filter(([key]) => !EXTRACTED_FIELDS.has(key) && key !== \"name\")\n .map(([key, value]) => renderScalarField(key, value))\n\n const exportFields: string[] = [\n ` ...globalConfig,`,\n renderScalarField(\"name\", resolveProjectName(cleaned)),\n ` skills,`,\n ` agents,`,\n ...(hasStack ? [` stack,`] : []),\n ...(hasProjectDomains ? [` selectedDomains,`] : []),\n ...scalarFields,\n ]\n\n lines.push(``)\n lines.push(`export default {`)\n lines.push(...exportFields)\n lines.push(`} satisfies ProjectConfig`)\n\n lines.push(``)\n return lines.join(\"\\n\")\n}\n\n/**\n * Generates a standalone config source with typed named variables above the export default.\n * The export default at the bottom acts as a table of contents, referencing the named variables.\n */\nfunction generateStandaloneConfig(cleaned: Record<string, unknown>): string {\n const { skills, agents, stack, selectedDomains } =\n extractConfigArrays(cleaned)\n\n const hasSkills = skills.length > 0\n const hasAgents = agents.length > 0\n const hasStack = stack != null && Object.keys(stack).length > 0\n const hasSelectedDomains = selectedDomains.length > 0\n\n const typeImports = buildTypeImports({\n hasSkills,\n hasAgents,\n hasStack,\n hasSelectedDomains,\n })\n\n const lines: string[] = [\n renderTypeImportLine(typeImports, CONFIG_TYPES_SPECIFIER),\n ]\n\n if (hasSkills) {\n lines.push(...declaration(\"skills\", \"SkillConfig[]\", skills))\n }\n\n if (hasAgents) {\n lines.push(...declaration(\"agents\", \"AgentScopeConfig[]\", agents))\n }\n\n if (hasStack) {\n lines.push(...declaration(\"stack\", STACK_TYPE, stack))\n }\n\n if (hasSelectedDomains) {\n lines.push(...declaration(\"selectedDomains\", \"Domain[]\", selectedDomains))\n }\n\n // Extracted fields reference their named variable (or an empty literal when the\n // variable was not emitted); `stack` is omitted entirely when absent.\n const renderExportField = (key: string, value: unknown): string[] => {\n if (!EXTRACTED_FIELDS.has(key)) return [renderScalarField(key, value)]\n if (key === \"skills\") return [` skills${hasSkills ? \"\" : \": []\"},`]\n if (key === \"agents\") return [` agents${hasAgents ? \"\" : \": []\"},`]\n if (key === \"stack\") return hasStack ? [` stack,`] : []\n return [` selectedDomains${hasSelectedDomains ? \"\" : \": []\"},`]\n }\n const exportFields = Object.entries(cleaned).flatMap(([key, value]) =>\n renderExportField(key, value)\n )\n\n lines.push(``)\n lines.push(`export default {`)\n lines.push(...exportFields)\n lines.push(`} satisfies ProjectConfig`)\n\n lines.push(``)\n return lines.join(\"\\n\")\n}\n\n/**\n * Builds the type import list based on which extracted fields are present.\n * ProjectConfig is always included. Other types are included only when used.\n */\nfunction buildTypeImports(flags: {\n hasSkills: boolean\n hasAgents: boolean\n hasStack: boolean\n hasSelectedDomains: boolean\n}): string[] {\n return [\n flags.hasSelectedDomains && \"Domain\",\n \"ProjectConfig\",\n flags.hasStack && \"ProjectAgentName\",\n flags.hasAgents && \"AgentScopeConfig\",\n flags.hasSkills && \"SkillConfig\",\n flags.hasStack && \"StackAgentConfig\",\n ].filter((t): t is string => Boolean(t))\n}\n\n/** Project configs never inherit \"global\" as their name from the globalConfig spread. */\nfunction resolveProjectName(cleaned: Record<string, unknown>): unknown {\n return cleaned.name && cleaned.name !== GLOBAL_CONFIG_NAME\n ? cleaned.name\n : DEFAULT_PLUGIN_NAME\n}\n\ntype InlinedGlobalPartition = {\n /** Global entries with active entries replaced by their project tombstones. */\n globalSkills: unknown[]\n globalAgents: unknown[]\n /** Active (non-excluded) project entries. */\n projectSkills: unknown[]\n projectAgents: unknown[]\n /** Project stack filtered to project-scoped agents only. */\n filteredStack: Record<string, unknown> | undefined\n /** Merged unique global + project values. */\n selectedDomains: unknown[]\n}\n\n/**\n * Pure partition of project + global entries for the inlined snapshot.\n *\n * Excluded globals are routed to the project partition by splitConfigByScope,\n * but render under \"// global\" in the output for readability. When inlining,\n * active global entries are replaced by their excluded tombstones — the\n * tombstone masks the global entry for this project; the active project entry\n * (if any) appears separately in the project section. The project stack keeps\n * only project-scoped agents: global agents' stack entries live in the global\n * config only.\n */\nfunction partitionInlinedConfigEntries(\n cleaned: Record<string, unknown>,\n cleanedGlobal: Record<string, unknown>\n): InlinedGlobalPartition {\n const project = extractConfigArrays(cleaned)\n const global = extractConfigArrays(cleanedGlobal)\n\n const isExcluded = (entry: unknown): boolean =>\n (entry as { excluded?: boolean }).excluded === true\n const idOf = (entry: unknown): string => (entry as { id: string }).id\n const nameOf = (entry: unknown): string => (entry as { name: string }).name\n\n const excludedGlobalSkills = project.skills.filter(isExcluded)\n const excludedGlobalAgents = project.agents.filter(isExcluded)\n const projectSkills = project.skills.filter((s) => !isExcluded(s))\n const projectAgents = project.agents.filter((a) => !isExcluded(a))\n\n const excludedSkillIds = new Set(excludedGlobalSkills.map(idOf))\n const excludedAgentNames = new Set(excludedGlobalAgents.map(nameOf))\n const globalSkills = [\n ...global.skills.filter((s) => !excludedSkillIds.has(idOf(s))),\n ...excludedGlobalSkills,\n ]\n const globalAgents = [\n ...global.agents.filter((a) => !excludedAgentNames.has(nameOf(a))),\n ...excludedGlobalAgents,\n ]\n\n const projectAgentNames = new Set(projectAgents.map(nameOf))\n const filteredStack: Record<string, unknown> | undefined = project.stack\n ? Object.fromEntries(\n Object.entries(project.stack).filter(([agent]) =>\n projectAgentNames.has(agent)\n )\n )\n : undefined\n\n return {\n globalSkills,\n globalAgents,\n projectSkills,\n projectAgents,\n filteredStack,\n selectedDomains: [\n ...new Set([...global.selectedDomains, ...project.selectedDomains]),\n ],\n }\n}\n\n/**\n * Every scalar the inlined snapshot emits, as ONE canonically-ordered sequence.\n * The project's value wins where it carries one, and the global supplies the\n * rest. A global block followed by a project block could not promise this: the\n * first emission writes every global scalar into the project's own file, so on\n * the next re-emit those same keys arrive from the project half instead and two\n * blocks would order them differently for values that never changed.\n */\nfunction mergeInlinedScalarFields(\n cleaned: Record<string, unknown>,\n cleanedGlobal: Record<string, unknown>\n): [string, unknown][] {\n return Object.entries(\n canonicalizeFieldOrder({ ...cleanedGlobal, ...cleaned })\n ).filter(([key]) => !EXTRACTED_FIELDS.has(key) && key !== \"name\")\n}\n\n/**\n * Generates a project config with global skills/agents inlined directly.\n * No `import globalConfig` — the output is a self-contained readable snapshot.\n * Global items appear first with a `// global` comment, followed by project items\n * with a `// project` comment (only when project items exist).\n */\nfunction generateProjectConfigWithInlinedGlobal(\n cleaned: Record<string, unknown>,\n cleanedGlobal: Record<string, unknown>\n): string {\n const partition = partitionInlinedConfigEntries(cleaned, cleanedGlobal)\n const {\n globalSkills,\n globalAgents,\n projectSkills,\n projectAgents,\n filteredStack,\n } = partition\n\n const hasGlobalSkills = globalSkills.length > 0\n const hasProjectSkills = projectSkills.length > 0\n const hasSkills = hasGlobalSkills || hasProjectSkills\n\n const hasGlobalAgents = globalAgents.length > 0\n const hasProjectAgents = projectAgents.length > 0\n const hasAgents = hasGlobalAgents || hasProjectAgents\n\n const hasStack =\n filteredStack != null && Object.keys(filteredStack).length > 0\n const hasSelectedDomains = partition.selectedDomains.length > 0\n\n const typeImports = buildTypeImports({\n hasSkills,\n hasAgents,\n hasStack,\n hasSelectedDomains,\n })\n\n const lines: string[] = [\n renderTypeImportLine(typeImports, CONFIG_TYPES_SPECIFIER),\n ]\n\n if (hasSkills) {\n lines.push(\n ...entryDeclaration(\n \"skills\",\n \"SkillConfig[]\",\n scopeSectionEntries(globalSkills, projectSkills)\n )\n )\n }\n\n if (hasAgents) {\n lines.push(\n ...entryDeclaration(\n \"agents\",\n \"AgentScopeConfig[]\",\n scopeSectionEntries(globalAgents, projectAgents)\n )\n )\n }\n\n if (hasStack) {\n lines.push(...declaration(\"stack\", STACK_TYPE, filteredStack))\n }\n\n if (hasSelectedDomains) {\n lines.push(\n ...declaration(\"selectedDomains\", \"Domain[]\", partition.selectedDomains)\n )\n }\n\n const scalarFields = mergeInlinedScalarFields(cleaned, cleanedGlobal)\n\n const exportFields: string[] = [\n renderScalarField(\"name\", resolveProjectName(cleaned)),\n ...scalarFields.map(([key, value]) => renderScalarField(key, value)),\n hasSkills ? ` skills,` : ` skills: [],`,\n hasAgents ? ` agents,` : ` agents: [],`,\n ...(hasStack ? [` stack,`] : []),\n ...(hasSelectedDomains ? [` selectedDomains,`] : []),\n ]\n\n lines.push(``)\n lines.push(`export default {`)\n lines.push(...exportFields)\n lines.push(`} satisfies ProjectConfig`)\n\n lines.push(``)\n return lines.join(\"\\n\")\n}\n\n/**\n * The two halves of an inlined array, each under the comment naming its scope.\n *\n * The comments are entries rather than lines a caller writes around the printer\n * because they are what holds the array open: a `//` line cannot be folded back\n * onto one line, so an array carrying one stays one entry per line however\n * short it is — which is the whole of what keeps these sections legible when a\n * root holds a single skill.\n */\nfunction scopeSectionEntries(\n global: unknown[],\n project: unknown[]\n): ArrayEntry[] {\n return [\n ...(global.length > 0\n ? [commentEntry(\"global\"), ...valueEntries(global)]\n : []),\n ...(project.length > 0\n ? [commentEntry(\"project\"), ...valueEntries(project)]\n : []),\n ]\n}\n\n/** True when the assignment asserts something a bare id could not say on its own. */\nfunction carriesFlags(assignment: SkillAssignment): boolean {\n return Boolean(assignment.preloaded || assignment.local || assignment.path)\n}\n\n/**\n * Structural check for a SkillAssignment object (`{ id, preloaded? }`).\n * The id's SkillId-ness is structural, not union-checked: assignments flow from\n * runtime sources whose skills may not be in the generated union.\n */\nfunction isSkillAssignment(value: unknown): value is SkillAssignment {\n if (typeof value !== \"object\" || value === null) return false\n // Boundary cast: probing an unknown object's field inside the guard\n return typeof (value as { id?: unknown }).id === \"string\"\n}\n\n/**\n * Compacts one SkillAssignment down to the smallest form that still carries its information.\n * - { id: \"...\" } and { id: \"...\", preloaded: false } → \"...\" (the id says everything)\n * - anything carrying a flag (preloaded, local, path) keeps the object form, flags intact\n *\n * The surviving object form is the third member of the entry-order class above:\n * `toStackPropertyAssignment` in `seed-to-config.ts` answers a flag-less\n * assignment with `{ ...assignment, preloaded: true }`, which appends the key at\n * the tail, while the loader's `skillAssignmentSchema` rebuilds it before\n * `local` and `path`.\n */\nfunction compactAssignment(assignment: unknown): unknown {\n if (!isSkillAssignment(assignment)) return assignment\n if (!carriesFlags(assignment)) return assignment.id\n return withKeysInSchemaOrder(assignment, CANONICAL_ASSIGNMENT_ORDER)\n}\n\n/**\n * The emitted value for one category's assignments.\n *\n * An exclusive category can only ever hold one skill, so its array wrapper carries nothing the\n * reader needs and the bare value IS the assignment. Non-exclusive categories keep their array\n * even at length one — there the wrapper is load-bearing, because a second skill may join.\n *\n * Two skills in an exclusive category means the caller built something the config cannot express.\n * Dropping the extra would write a config that does not match what was selected, and nothing\n * downstream could tell, so it fails here instead.\n */\nfunction compactCategoryAssignments(\n category: string,\n assignments: unknown[],\n catalog: CompileCatalog\n): unknown {\n const compacted = assignments.map(compactAssignment)\n if (!isExclusiveCategory(catalog, category)) return compacted\n\n if (compacted.length > 1) {\n throw new Error(\n `Category '${category}' is exclusive but holds ${compacted.length} skills: ${JSON.stringify(compacted)}`\n )\n }\n return compacted[0]\n}\n\nfunction compactCategories(\n categories: Record<string, unknown[]>,\n catalog: CompileCatalog\n): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(categories)\n .filter(\n ([, assignments]) =>\n Array.isArray(assignments) && assignments.length > 0\n )\n .map(([category, assignments]) => [\n category,\n compactCategoryAssignments(category, assignments, catalog),\n ])\n )\n}\n\nfunction compactStackAssignments(\n stack: Record<string, Record<string, unknown[]>>,\n catalog: CompileCatalog\n): Record<string, Record<string, unknown>> {\n return Object.fromEntries(\n Object.entries(stack)\n .map(\n ([agent, categories]) =>\n [agent, compactCategories(categories, catalog)] as const\n )\n .filter(([, categories]) => Object.keys(categories).length > 0)\n )\n}\n\n/**\n * Generates a blank global config source (empty arrays, no import preamble).\n */\nexport function generateBlankGlobalConfigSource(): string {\n return `import type { ProjectConfig } from ${quoteText(CONFIG_TYPES_SPECIFIER)}\n\nexport default {\n name: ${quoteText(GLOBAL_CONFIG_NAME)},\n skills: [],\n agents: [],\n selectedDomains: [],\n} satisfies ProjectConfig\\n`\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { ProjectConfig, SkillId } from \"../../types\";\nimport type { SkillConfig } from \"../../types/config\";\nimport type { AuthoritativeScope } from \"../configuration/config-merger\";\nimport { CLAUDE_SRC_DIR, CLI_INVOKE_COMMAND } from \"../../consts\";\nimport { ensureDir, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { loadProjectConfigFromDir } from \"../configuration/project-config\";\nimport { normalizeStackRecord } from \"../stacks/stacks-loader\";\nimport { isActiveAt } from \"../configuration/scope-predicates\";\nimport { splitConfigByScope } from \"../configuration/config-generator\";\n// The catalogue the renderers take as a parameter. It is the singleton this CLI seats at\n// startup, which is what `generateConfigSource` read directly before the renderers moved into\n// `@workspace/compile` and the editor became a second caller with a catalogue of its own.\nimport { matrix as activeMatrix } from \"../matrix/matrix-provider\";\nimport { generateConfigSource } from \"../configuration/config-writer\";\nimport {\n buildConfigTypesBackgroundData,\n regenerateConfigTypes,\n type ConfigTypesExtras,\n} from \"../configuration/config-types-writer\";\nimport {\n classifyGlobalChange,\n consequenceTier,\n tierPropagates,\n tierRegeneratesTypes,\n NO_CHANGES,\n type GlobalChangeSet,\n} from \"./classify.js\";\nimport { resolveGateDeps, type GateDeps, type LoadedGateDeps } from \"./deps.js\";\nimport { GlobalPairWriteViolation, withGateToken } from \"./gate-token.js\";\nimport {\n ensureBlankPair as ensureBlankPairInternal,\n writeGlobalConfigHalf,\n writeGlobalPair,\n writeGlobalTypesHalf,\n} from \"./pair-writer.js\";\nimport {\n buildProjectTypesExtras,\n mergeGlobalConfigs,\n normalizeProjectPath,\n propagateGlobalChangesToProjects,\n pruneGlobalEntriesFromRegisteredProjects,\n reconcileProjectSplitAgainstGlobal,\n resolveEffectiveGlobalConfig,\n writeProjectConfigPair,\n type PropagationResult,\n} from \"./propagate.js\";\nimport { NOTHING_RECOMPILED, recompilePropagated } from \"./recompile.js\";\nimport type { PropagatedRecompileSummary } from \"../operations/project/recompile-project-agents.js\";\n\nexport type { GateDeps } from \"./deps.js\";\nexport type { ConsequenceTier, GlobalChangeSet } from \"./classify.js\";\nexport { GlobalPairWriteViolation } from \"./gate-token.js\";\n\n/**\n * What one gated write did, for the caller to render.\n *\n * A write that propagates recompiles the propagated projects' agents itself:\n * both audited gaps in the previous contract (a project-context source\n * migration, a global uninstall) were instances of a caller forgetting to. A\n * report the caller may only log cannot go stale the same way, and per-project\n * failure isolation already lives in `recompilePropagatedProjectAgents`, so\n * internalizing the recompile adds no new failure mode.\n */\nexport type GateReport = {\n /** True when either half of the global pair was actually rewritten. */\n globalWritten: boolean;\n changes: GlobalChangeSet;\n propagated: PropagationResult;\n recompile: PropagatedRecompileSummary;\n};\n\n/**\n * The gate's public entry points are the ONLY code that mints the pair-write\n * privilege, and each one holds it across its whole consequence flow rather than\n * around the individual write.\n *\n * `pair-writer.ts` used to open the token inside each of its own functions, which\n * meant reaching that module by any route — a dynamic import, a re-export — came\n * with the privilege attached, and the runtime tripwire in `utils/fs.ts` had\n * nothing left to refuse. Moving the mint here inverts that: the private writers\n * REQUIRE a token they cannot produce, so authorization is a property of how the\n * write was ENTERED, which is exactly what the gate is meant to guarantee.\n *\n * The window is wider than the write itself — propagation and the recompile run\n * inside it too. That is accepted: everything in the window is the gate's own\n * code carrying out consequences the same entry already owes.\n *\n * Every entry below that writes or drives a write opens the token with\n * `withGateToken`, including `propagateGlobalRemoval`, which today reaches only\n * project pairs — the rule is \"a gate entry holds the privilege for its flow\",\n * not \"the ones whose current implementation happens to need it\".\n *\n * The one exception is `writeProjectPartial`. It refuses the home directory as its\n * first act and then writes a PROJECT's own config, which the tripwire never\n * guards; handing it the global-pair privilege would only blunt the refusal it\n * exists to make.\n */\n\n/** A write whose classification obliged nothing beyond the global pair. */\nconst NOTHING_PROPAGATED: PropagationResult = { updated: [], skipped: [] };\n\nfunction report(\n globalWritten: boolean,\n changes: GlobalChangeSet,\n propagated: PropagationResult = NOTHING_PROPAGATED,\n recompile: PropagatedRecompileSummary = NOTHING_RECOMPILED,\n): GateReport {\n return { globalWritten, changes, propagated, recompile };\n}\n\n/**\n * Carries out a classified global change's consequences: fan the change out to\n * every registered project, then recompile the ones it rewrote.\n *\n * `currentProjectDir` is excluded from the fan-out — its own pair is written by\n * the call that triggered this, and its agents are compiled by the command.\n */\nasync function applyConsequences(\n globalConfig: ProjectConfig,\n changes: GlobalChangeSet,\n deps: LoadedGateDeps,\n currentProjectDir?: string,\n): Promise<{ propagated: PropagationResult; recompile: PropagatedRecompileSummary }> {\n const tier = consequenceTier(changes);\n if (!tierPropagates(tier) || !globalConfig.projects?.length) {\n return { propagated: NOTHING_PROPAGATED, recompile: NOTHING_RECOMPILED };\n }\n\n const propagated = await propagateGlobalChangesToProjects(\n globalConfig,\n deps.matrix,\n deps.agents,\n currentProjectDir,\n { regenerateTypes: tierRegeneratesTypes(tier) },\n );\n if (propagated.updated.length > 0) {\n verbose(`Propagated global changes to ${propagated.updated.length} project(s)`);\n }\n\n const recompile = tierRegeneratesTypes(tier)\n ? await recompilePropagated(propagated.updated)\n : NOTHING_RECOMPILED;\n\n return { propagated, recompile };\n}\n\n/**\n * Loaders for a caller that holds no matrix of its own. Nothing is fetched\n * unless classification proves the write has consequences that read it, so a\n * registration-only mutation stays offline.\n *\n * `matrixOnly` + `skipExtraSources` are the offline policy the other config\n * readers already use: extra-source loading only annotates wizard UI tagging and\n * never changes the emitted config or types.\n */\nexport function lazyGateDeps(projectDir: string): GateDeps {\n return {\n loadMatrix: async () => {\n const { loadSkillsMatrixFromSource } = await import(\"../loading/source-loader.js\");\n const { matrix } = await loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n return matrix;\n },\n loadAgents: async () => {\n const { loadAgentDefs } = await import(\"../operations/project/load-agent-defs.js\");\n return (await loadAgentDefs()).agents;\n },\n };\n}\n\nexport type WizardWriteArgs = {\n finalConfig: ProjectConfig;\n matrix: LoadedGateDeps[\"matrix\"];\n agents: LoadedGateDeps[\"agents\"];\n projectDir: string;\n projectConfigPath: string;\n projectInstallationExists: boolean;\n /**\n * How much of what it can see this session owns, from `mergeConfigs`' own vocabulary.\n *\n * Read by the PROJECT branch only, and only to decide whether the global config is made to\n * MATCH this session or merely absorb it. The home branch writes the whole global config from\n * `finalConfig` either way, and `undefined` (init) keeps the additive default.\n */\n authoritativeScope?: AuthoritativeScope;\n};\n\n/**\n * Writes config.ts and config-types.ts split by scope.\n * When installing into a project directory:\n * - Global config/types go to ~/.claude-src/\n * - Project config/types go to {projectDir}/.claude-src/ (with import from global)\n * When installing from home directory, writes a single standalone config.\n */\nexport async function writeScopedFromWizard(args: WizardWriteArgs): Promise<GateReport> {\n return withGateToken(async () => {\n const { finalConfig, matrix, agents, projectDir, projectConfigPath } = args;\n // os.homedir() at call time, so the path agrees with getGlobalConfigImportPath(),\n // which reaches the same home through globalInstallRoot()\n const homeDir = os.homedir();\n const deps: LoadedGateDeps = { matrix, agents };\n\n if (!isHomeDirectory(projectDir)) {\n return writeFromProjectContext(args, homeDir, deps);\n }\n\n // Installing from ~/ — write directly to global config (no import preamble)\n const priorGlobal = await loadProjectConfigFromDir(homeDir);\n const changes = classifyGlobalChange(priorGlobal?.config, finalConfig);\n const globalWritten = await writeGlobalPair(finalConfig, projectConfigPath, matrix, agents);\n\n const { propagated, recompile } = await applyConsequences(finalConfig, changes, deps);\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\nasync function writeFromProjectContext(\n args: WizardWriteArgs,\n homeDir: string,\n deps: LoadedGateDeps,\n): Promise<GateReport> {\n const { finalConfig, matrix, agents, projectDir, projectConfigPath } = args;\n\n // Installing from project — split by scope for project config generation.\n const { global: globalConfig, project: projectSplitConfig } = splitConfigByScope(finalConfig);\n const globalConfigPath = getProjectConfigPath(homeDir);\n\n // Merge new global-scoped items into the existing global config.\n // - Existing items are preserved (never removed from global during project init)\n // - New global items are added\n // - If no existing global config, write the full global split\n const existingGlobal = await loadProjectConfigFromDir(homeDir);\n const effective = await resolveEffectiveGlobalConfig(\n globalConfig,\n existingGlobal?.config,\n projectDir,\n args.authoritativeScope,\n );\n const effectiveGlobalConfig = effective.config;\n\n const changes = classifyGlobalChange(existingGlobal?.config, effectiveGlobalConfig);\n\n let globalWritten = false;\n if (effective.changed) {\n await ensureDir(path.dirname(globalConfigPath));\n globalWritten = await writeGlobalPair(effectiveGlobalConfig, globalConfigPath, matrix, agents);\n verbose(`Updated global config at ${globalConfigPath}`);\n } else {\n verbose(\"Global config unchanged, skipping write\");\n }\n\n const { propagated, recompile } = await applyConsequences(\n effectiveGlobalConfig,\n changes,\n deps,\n projectDir,\n );\n\n // Reconcile the project's own entries against the global config this write inlines.\n // Without it this branch hands the raw split straight to the inlining writer, so a\n // skill/agent the project owns at project scope AND a colliding live global install\n // both land as active entries in the same project config.\n const reconciledProjectConfig = reconcileProjectSplitAgainstGlobal(\n projectSplitConfig,\n effectiveGlobalConfig,\n matrix,\n );\n\n // Write project config if the project installation already exists OR if there are project-scoped items.\n // Skip only when no existing project installation AND no project-scoped items — creating an empty\n // project config with just `import globalConfig` and `{ ...globalConfig }` is pointless.\n const hasProjectItems =\n reconciledProjectConfig.skills.length > 0 || reconciledProjectConfig.agents.length > 0;\n\n if (args.projectInstallationExists || hasProjectItems) {\n await ensureDir(path.dirname(projectConfigPath));\n await writeProjectConfigPair(\n projectDir,\n reconciledProjectConfig,\n effectiveGlobalConfig,\n matrix,\n agents,\n );\n verbose(`Updated project config at ${projectConfigPath}`);\n } else {\n verbose(\n \"Skipped project config — no existing project installation and no project-scoped items\",\n );\n }\n\n return report(globalWritten, changes, propagated, recompile);\n}\n\n/**\n * Regenerates a single scope's config-types.ts from its persisted config,\n * matching the wizard write path's writer selection exactly:\n * - global scope (home dir): standalone unions narrowed to the config's entries\n * - project scope: import-and-extend form (falls back to standalone when no\n * global config-types.ts exists)\n *\n * Writes no config half at either scope: the config on disk is the input.\n * Returns whether a file was actually rewritten (always false at project scope,\n * where the writer does not report).\n */\nexport async function writeScopeConfigTypes(\n projectDir: string,\n config: ProjectConfig,\n deps: LoadedGateDeps,\n extras?: ConfigTypesExtras,\n): Promise<boolean> {\n return withGateToken(async () => {\n if (isHomeDirectory(projectDir)) {\n return writeGlobalTypesHalf(\n config,\n getProjectConfigPath(projectDir),\n deps.matrix,\n deps.agents,\n extras,\n );\n }\n\n await regenerateConfigTypes(\n projectDir,\n Promise.resolve(buildConfigTypesBackgroundData(deps.matrix, deps.agents)),\n extras ?? buildProjectTypesExtras(config, deps.matrix),\n );\n return false;\n });\n}\n\n/**\n * Regenerates a scope's config-types.ts from the config already on disk, which\n * is the truth and is never rewritten — the documented hand-edit workflow is\n * \"edit config.ts, then compile\", so the file the user edited must survive it.\n *\n * At the home directory the types are the standalone unions narrowed to that\n * config, and the fan-out is UNCONDITIONAL: a hand edit leaves no prior state to\n * diff against, so there is nothing to classify and the only safe assumption is\n * that every registered project's inlined copy is stale. At project and\n * marketplace directories the import-and-extend writer applies and nothing is\n * propagated — a project config is nobody else's input.\n */\nexport async function reconcileTypesFromDisk(\n projectDir: string,\n config: ProjectConfig,\n deps: LoadedGateDeps,\n options?: { extras?: ConfigTypesExtras; currentProjectDir?: string },\n): Promise<GateReport> {\n return withGateToken(async () => {\n const changes = classifyGlobalChange(undefined, config);\n const globalWritten = await writeScopeConfigTypes(projectDir, config, deps, options?.extras);\n\n if (!isHomeDirectory(projectDir)) return report(false, changes);\n if (!config.projects?.length) return report(globalWritten, changes);\n\n const propagated = await propagateGlobalChangesToProjects(\n config,\n deps.matrix,\n deps.agents,\n options?.currentProjectDir,\n );\n if (propagated.updated.length > 0) {\n verbose(`Propagated global changes to ${propagated.updated.length} project(s)`);\n }\n const recompile = await recompilePropagated(propagated.updated);\n\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\n/**\n * The transforms the gate will apply to the global config on a caller's behalf.\n *\n * A closed union rather than a caller-supplied function: every variant is\n * analysable and testable on its own, and no caller-authored transform runs\n * inside the only code allowed to write the pair.\n */\nexport type GlobalMutation =\n | { kind: \"migrate-skill-sources\"; sources: ReadonlyMap<SkillId, string> }\n | { kind: \"deregister-project\"; projectDir: string }\n | { kind: \"set-source\"; source: string; fallbackName: string };\n\n/** The migrated `origin` for an active-global entry, or the entry unchanged. */\nfunction withMigratedSource(\n skill: SkillConfig,\n migratedSources: ReadonlyMap<SkillId, string>,\n): SkillConfig {\n if (!isActiveAt(skill, \"global\")) return skill;\n const origin = migratedSources.get(skill.id);\n if (origin === undefined || origin === skill.origin) return skill;\n return { ...skill, origin };\n}\n\n/**\n * Rewrites `origin` on exactly the active-global entries listed in `migratedSources`,\n * returning every other entry — including global entries this session did not migrate —\n * identical by reference.\n */\nexport function applyMigratedGlobalSources(\n globalSkills: SkillConfig[],\n migratedSources: ReadonlyMap<SkillId, string>,\n): { skills: SkillConfig[]; changed: boolean } {\n const skills = globalSkills.map((skill) => withMigratedSource(skill, migratedSources));\n return { skills, changed: skills.some((skill, index) => skill !== globalSkills[index]) };\n}\n\n/**\n * The config a partial write commits: the scalars and arrays already on disk,\n * with the required fields filled. Mirrors what the partial writer has always\n * defaulted, so a scalar mutation cannot silently empty an install.\n */\nfunction fillRequiredFields(\n partial: Partial<ProjectConfig>,\n fallbackName: string | undefined,\n): ProjectConfig {\n const name = partial.name ?? fallbackName;\n if (!name) {\n throw new Error(\n `Cannot write config: no project config found. Run \\`${CLI_INVOKE_COMMAND} init\\` first.`,\n );\n }\n return { ...partial, name, skills: partial.skills ?? [], agents: partial.agents ?? [] };\n}\n\n/** Applies a mutation to the config on disk, or null when it is a no-op. */\nfunction applyMutation(\n mutation: GlobalMutation,\n current: Partial<ProjectConfig>,\n): Partial<ProjectConfig> | null {\n switch (mutation.kind) {\n case \"migrate-skill-sources\": {\n const { skills, changed } = applyMigratedGlobalSources(\n current.skills ?? [],\n mutation.sources,\n );\n return changed ? { ...current, skills } : null;\n }\n case \"deregister-project\": {\n const projects = current.projects ?? [];\n if (projects.length === 0) return null;\n const normalized = normalizeProjectPath(mutation.projectDir);\n const filtered = projects.filter((p) => p !== normalized);\n return filtered.length === projects.length ? null : { ...current, projects: filtered };\n }\n case \"set-source\":\n return { ...current, marketplace: mutation.source };\n default: {\n const _exhaustive: never = mutation;\n return _exhaustive;\n }\n }\n}\n\n/** The name a mutation invents when the global config has none yet. */\nfunction fallbackNameFor(mutation: GlobalMutation): string | undefined {\n return mutation.kind === \"set-source\" ? mutation.fallbackName : undefined;\n}\n\n/**\n * Applies a typed transform to the global config and carries out whatever its\n * classification obliges. No variant is exempt from classification by\n * construction: a source change propagates because project configs inline the\n * global scalars, and a deregistration does not because nothing inlines the\n * registration list.\n */\nexport async function mutateGlobal(mutation: GlobalMutation, deps: GateDeps): Promise<GateReport> {\n return withGateToken(async () => {\n const homeDir = os.homedir();\n // The full loader, not the scalar one: it normalizes every stack assignment\n // back to `SkillAssignment[]`. The writer compacts an exclusive category to its\n // bare value on the way out, and re-emitting that bare form without\n // normalization drops the category — so a scalar mutation would silently strip\n // every exclusive category from the global stack.\n const loadedGlobal = await loadProjectConfigFromDir(homeDir);\n if (!loadedGlobal) return report(false, NO_CHANGES);\n\n const current = loadedGlobal.config;\n const mutated = applyMutation(mutation, current);\n if (!mutated) return report(false, NO_CHANGES);\n\n const prior = fillRequiredFields(current, fallbackNameFor(mutation));\n const next = fillRequiredFields(mutated, fallbackNameFor(mutation));\n const changes = classifyGlobalChange(prior, next);\n\n const globalWritten = await writeGlobalConfigHalf(next, getProjectConfigPath(homeDir));\n if (!next.projects?.length) return report(globalWritten, changes);\n\n const loaded = await resolveGateDeps(deps, consequenceTier(changes));\n if (!loaded) return report(globalWritten, changes);\n\n const { propagated, recompile } = await applyConsequences(next, changes, loaded);\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\n/**\n * Prunes the CLI-inlined global entries from every registered project after a\n * GLOBAL uninstall, and recompiles their agents.\n *\n * Writes no pair: the pair this would derive from has just been deleted. That is\n * the reason this is its own entry rather than a flag on a writing one — the\n * removal case must not be reachable from a code path whose job is to write.\n *\n * Call AFTER the global manifest has been removed so the regenerated project\n * types fall back to the standalone form instead of importing from the\n * now-deleted global config-types.ts.\n */\nexport async function propagateGlobalRemoval(\n preRemovalGlobalConfig: ProjectConfig,\n deps: LoadedGateDeps,\n): Promise<GateReport> {\n return withGateToken(async () => {\n const changes = classifyGlobalChange(preRemovalGlobalConfig, {\n ...preRemovalGlobalConfig,\n skills: [],\n agents: [],\n });\n\n const propagated = await pruneGlobalEntriesFromRegisteredProjects(\n preRemovalGlobalConfig,\n deps.matrix,\n deps.agents,\n );\n const recompile = await recompilePropagated(propagated.updated);\n\n return report(false, changes, propagated, recompile);\n });\n}\n\n/**\n * Creates the blank global pair when none exists. No classification and no\n * fan-out: the registration list propagation reads lives in the file that was\n * just found absent, so a pair created here has no registered projects.\n */\nexport async function ensureBlankPair(): Promise<boolean> {\n return withGateToken(() => ensureBlankPairInternal());\n}\n\nexport type WriteProjectPartialOptions = {\n /** Name to invent when the partial has none. Absent → a missing name is an error. */\n fallbackName?: string;\n};\n\n/**\n * The partial with every stack assignment normalized back to `SkillAssignment[]`.\n *\n * Every caller of this entry reads the config with the LENIENT loader\n * (`loadProjectSourceConfig`), overlays one scalar, and hands the result back.\n * That loader passes the on-disk stack through untouched, and the writer emits an\n * exclusive category in its BARE form (`\"web-framework\": \"web-framework-react\"`,\n * no array) — so on a load / re-emit round trip `compactCategories`, which keeps\n * only non-empty arrays, drops the category and the user silently loses an\n * assignment they never touched.\n *\n * Normalizing at this boundary rather than inside the writer keeps the fix on the\n * one path that can present a denormalized stack: the full loader\n * (`loadProjectConfigFromDir`) already runs `normalizeStackRecord`, so every other\n * writer input arrives normalized.\n */\nfunction withNormalizedStack(partial: Partial<ProjectConfig>): Partial<ProjectConfig> {\n if (!partial.stack) return partial;\n return { ...partial, stack: normalizeStackRecord(partial.stack) };\n}\n\n/**\n * Writes a partial config to a PROJECT's `.claude-src/config.ts`, filling\n * required defaults. Refuses the home directory: the global pair's config half\n * may never be written without its types sibling and without classification.\n */\nexport async function writeProjectPartial(\n projectDir: string,\n partial: Partial<ProjectConfig>,\n options: WriteProjectPartialOptions = {},\n): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n throw new GlobalPairWriteViolation(getProjectConfigPath(projectDir));\n }\n\n const configPath = getProjectConfigPath(projectDir);\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n await writeFile(\n configPath,\n generateConfigSource(\n fillRequiredFields(withNormalizedStack(partial), options.fallbackName),\n activeMatrix,\n ),\n );\n}\n\n/**\n * `normalizeProjectPath` is the single rule for any value compared against the\n * global config's `projects` array, so a reader that only wants to MATCH a\n * registration (never write one) gets it from here rather than reimplementing\n * `fs.realpathSync` and drifting from the rule the registrations were stored\n * under. It writes nothing, so exporting it hands out no privilege.\n */\nexport { mergeGlobalConfigs, normalizeProjectPath };\n","import { isDeepEqual } from \"remeda\";\nimport type { AgentName, ProjectConfig, SkillId } from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\n\n/**\n * The work one global config write owes, decided from what actually moved\n * between the config on disk and the config being written.\n *\n * T1 — the generated type unions or the compiled agents are derived from what\n * changed: rewrite both halves of the pair, propagate to every registered\n * project, recompile those projects' agents.\n * T2 — a scalar the unions do not encode changed. Project configs inline the\n * global scalars verbatim, so the config half propagates; no union moves,\n * so no types are regenerated and no agent is recompiled.\n * T3 — only the `projects[]` registration list changed. Nothing is propagated,\n * and the matrix / agent definitions propagation would need are never\n * loaded.\n * T4 — nothing moved. No file is touched.\n */\nexport type ConsequenceTier = \"T1\" | \"T2\" | \"T3\" | \"T4\";\n\nexport type GlobalChangeSet = {\n skills: {\n added: SkillId[];\n removed: SkillId[];\n /**\n * Ids whose `origin` moved — the field's name on `SkillConfig`; this one keeps the\n * older word. Separate from `otherChanged` because the per-skill value decides the\n * reference form a compiled agent emits\n * (`<id>:<id>` for a marketplace-sourced skill, the bare id for an ejected\n * one), so a source change that skipped the recompile leaves every\n * registered project's agents naming a reference that no longer resolves.\n */\n sourceChanged: SkillId[];\n otherChanged: SkillId[];\n };\n agents: {\n added: AgentName[];\n removed: AgentName[];\n changed: AgentName[];\n };\n stackChanged: boolean;\n selectedDomainsChanged: boolean;\n /** Names of the inlined scalar fields that moved, in config key order. */\n scalarsChanged: string[];\n projectsChanged: boolean;\n};\n\n/** The identity element of {@link GlobalChangeSet} — nothing moved, so T4. */\nexport const NO_CHANGES: GlobalChangeSet = {\n skills: { added: [], removed: [], sourceChanged: [], otherChanged: [] },\n agents: { added: [], removed: [], changed: [] },\n stackChanged: false,\n selectedDomainsChanged: false,\n scalarsChanged: [],\n projectsChanged: false,\n};\n\n/** The four fields the config writer extracts into typed named variables. */\nconst EXTRACTED_FIELDS = new Set([\"skills\", \"agents\", \"stack\", \"selectedDomains\"]);\n\n/** The registration list — bookkeeping, never emitted into a project config. */\nconst REGISTRATION_FIELD = \"projects\";\n\n/**\n * Normalizes a config the way the writer does immediately before emission: a\n * JSON round-trip, so an explicitly-`undefined` field and an absent one compare\n * equal. Without it every write that merely reconstructs an object produces\n * phantom diffs.\n */\nfunction normalize(config: ProjectConfig): Record<string, unknown> {\n // Boundary cast: `JSON.parse` is typed `any`, and round-tripping an object\n // always yields one — the whole point of the call is that the result is the\n // same record with its undefined-valued keys gone.\n return JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n}\n\n/** Field value as the writer would emit it, or undefined when absent. */\nfunction field(config: Record<string, unknown>, key: string): unknown {\n return config[key];\n}\n\nfunction skillsById(config: Record<string, unknown>): Map<SkillId, SkillConfig> {\n const skills = (config.skills ?? []) as SkillConfig[];\n return new Map(skills.map((skill) => [skill.id, skill]));\n}\n\nfunction agentsByName(config: Record<string, unknown>): Map<AgentName, AgentScopeConfig> {\n const agents = (config.agents ?? []) as AgentScopeConfig[];\n return new Map(agents.map((agent) => [agent.name, agent]));\n}\n\n/** The scalar keys either side carries, in `next`-first order with `prev` extras appended. */\nfunction scalarKeys(prev: Record<string, unknown>, next: Record<string, unknown>): string[] {\n const isScalarKey = (key: string): boolean =>\n !EXTRACTED_FIELDS.has(key) && key !== REGISTRATION_FIELD;\n const nextKeys = Object.keys(next).filter(isScalarKey);\n const extraPrevKeys = Object.keys(prev).filter(\n (key) => isScalarKey(key) && !nextKeys.includes(key),\n );\n return [...nextKeys, ...extraPrevKeys];\n}\n\nfunction diffSkills(\n prev: Record<string, unknown>,\n next: Record<string, unknown>,\n): GlobalChangeSet[\"skills\"] {\n const before = skillsById(prev);\n const after = skillsById(next);\n\n const added = [...after.keys()].filter((id) => !before.has(id));\n const removed = [...before.keys()].filter((id) => !after.has(id));\n\n const sourceChanged: SkillId[] = [];\n const otherChanged: SkillId[] = [];\n for (const [id, afterEntry] of after) {\n const beforeEntry = before.get(id);\n if (!beforeEntry || isDeepEqual(beforeEntry, afterEntry)) continue;\n if (beforeEntry.origin !== afterEntry.origin) sourceChanged.push(id);\n else otherChanged.push(id);\n }\n\n return { added, removed, sourceChanged, otherChanged };\n}\n\nfunction diffAgents(\n prev: Record<string, unknown>,\n next: Record<string, unknown>,\n): GlobalChangeSet[\"agents\"] {\n const before = agentsByName(prev);\n const after = agentsByName(next);\n\n return {\n added: [...after.keys()].filter((name) => !before.has(name)),\n removed: [...before.keys()].filter((name) => !after.has(name)),\n changed: [...after.keys()].filter((name) => {\n const beforeEntry = before.get(name);\n return beforeEntry !== undefined && !isDeepEqual(beforeEntry, after.get(name));\n }),\n };\n}\n\n/**\n * Diffs the config on disk against the config about to be written. `prev` is\n * undefined when no global config exists yet, which every field reads as a\n * change from absent.\n */\nexport function classifyGlobalChange(\n prev: ProjectConfig | undefined,\n next: ProjectConfig,\n): GlobalChangeSet {\n const before = prev ? normalize(prev) : {};\n const after = normalize(next);\n\n return {\n skills: diffSkills(before, after),\n agents: diffAgents(before, after),\n stackChanged: !isDeepEqual(field(before, \"stack\"), field(after, \"stack\")),\n selectedDomainsChanged: !isDeepEqual(\n field(before, \"selectedDomains\"),\n field(after, \"selectedDomains\"),\n ),\n scalarsChanged: scalarKeys(before, after).filter(\n (key) => !isDeepEqual(field(before, key), field(after, key)),\n ),\n projectsChanged: !isDeepEqual(\n field(before, REGISTRATION_FIELD),\n field(after, REGISTRATION_FIELD),\n ),\n };\n}\n\n/** True when something the type unions or the compiled agents derive from moved. */\nfunction movesTypesOrCompiledAgents(changes: GlobalChangeSet): boolean {\n const { skills, agents } = changes;\n return (\n skills.added.length > 0 ||\n skills.removed.length > 0 ||\n skills.sourceChanged.length > 0 ||\n skills.otherChanged.length > 0 ||\n agents.added.length > 0 ||\n agents.removed.length > 0 ||\n agents.changed.length > 0 ||\n changes.stackChanged ||\n changes.selectedDomainsChanged\n );\n}\n\n/** The work tier a change set obliges. */\nexport function consequenceTier(changes: GlobalChangeSet): ConsequenceTier {\n if (movesTypesOrCompiledAgents(changes)) return \"T1\";\n if (changes.scalarsChanged.length > 0) return \"T2\";\n if (changes.projectsChanged) return \"T3\";\n return \"T4\";\n}\n\n/** True when the tier's consequences need the matrix and agent definitions. */\nexport function tierNeedsDeps(tier: ConsequenceTier): boolean {\n return tier === \"T1\" || tier === \"T2\";\n}\n\n/** True when the tier regenerates the types half and recompiles propagated agents. */\nexport function tierRegeneratesTypes(tier: ConsequenceTier): boolean {\n return tier === \"T1\";\n}\n\n/** True when the tier fans the change out to every registered project. */\nexport function tierPropagates(tier: ConsequenceTier): boolean {\n return tier === \"T1\" || tier === \"T2\";\n}\n","import type { AgentDefinition, AgentName, MergedSkillsMatrix } from \"../../types\";\nimport { tierNeedsDeps, tierRegeneratesTypes, type ConsequenceTier } from \"./classify.js\";\n\n/** The matrix and agent definitions propagation and type generation read. */\nexport type LoadedGateDeps = {\n matrix: MergedSkillsMatrix;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n};\n\n/**\n * What a gate entry needs to carry out a write's consequences.\n *\n * The lazy form exists so a caller that cannot cheaply produce the matrix — an\n * offline uninstall, a deregistration — hands over loaders instead. Whether they\n * run is decided by classification: a registration-only or no-op write has no\n * consequences to carry out, so nothing is loaded and the write stays offline.\n */\nexport type GateDeps =\n | LoadedGateDeps\n | {\n loadMatrix: () => Promise<MergedSkillsMatrix>;\n loadAgents: () => Promise<Partial<Record<AgentName, AgentDefinition>>>;\n };\n\nfunction isLoaded(deps: GateDeps): deps is LoadedGateDeps {\n return \"matrix\" in deps;\n}\n\n/**\n * Resolves `deps` only when `tier` has consequences that read them. Returns null\n * otherwise, and the lazy loaders are never called.\n */\nexport async function resolveGateDeps(\n deps: GateDeps,\n tier: ConsequenceTier,\n): Promise<LoadedGateDeps | null> {\n if (!tierNeedsDeps(tier)) return null;\n if (isLoaded(deps)) return deps;\n\n // Agent definitions are read only where the types half is regenerated, so a\n // config-half-only tier never pays for loading them.\n const [matrix, agents] = await Promise.all([\n deps.loadMatrix(),\n tierRegeneratesTypes(tier) ? deps.loadAgents() : NO_AGENTS,\n ]);\n return { matrix, agents };\n}\n\n/** Agent definitions a tier that regenerates no types never reads. */\nconst NO_AGENTS: Promise<Partial<Record<AgentName, AgentDefinition>>> = Promise.resolve({});\n","import os from \"os\";\nimport path from \"path\";\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../../types\";\nimport { CLAUDE_SRC_DIR, STANDARD_FILES } from \"../../consts\";\nimport { ensureDir, fileExists, readFile, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport {\n generateBlankGlobalConfigSource,\n generateConfigSource,\n} from \"../configuration/config-writer\";\nimport {\n buildConfigTypesBackgroundData,\n generateBlankGlobalConfigTypesSource,\n generateConfigTypesSource,\n type ConfigTypesExtras,\n} from \"../configuration/config-types-writer\";\n// The catalogue the renderers take as a parameter. It is the singleton this CLI seats at\n// startup, which is what `generateConfigSource` read directly before the renderers moved into\n// `@workspace/compile` and the editor became a second caller with a catalogue of its own.\nimport { matrix as activeMatrix } from \"../matrix/matrix-provider\";\nimport { assertGateToken } from \"./gate-token.js\";\n\n/**\n * Nothing in this module MINTS the write privilege — every function below\n * REQUIRES it, and `writeIfChanged` is where that requirement is asserted. The\n * token is opened by the gate's public entry points in `index.ts`, each of which\n * wraps its whole consequence flow.\n *\n * That split is the point (D-309): a callee that opens the privilege on its own\n * behalf hands it to whoever reached it, so a caller that got past module\n * privacy — a dynamic import, a re-export added for convenience — arrived\n * already authorized and the runtime tripwire in `utils/fs.ts` waved it through.\n * Requiring the token instead makes reaching the private writer useless on its\n * own: the privilege belongs to the entry points, not to the writers.\n */\n\n/** Absolute paths of the two halves of the global config pair. */\nexport type GlobalPairPaths = {\n configPath: string;\n typesPath: string;\n};\n\n/**\n * Resolves the global pair's paths. `os.homedir()` at call time, so they agree\n * with every other home-dir reader and with test home mocks.\n */\nexport function globalPairPaths(): GlobalPairPaths {\n const dir = path.join(os.homedir(), CLAUDE_SRC_DIR);\n return {\n configPath: path.join(dir, STANDARD_FILES.CONFIG_TS),\n typesPath: path.join(dir, STANDARD_FILES.CONFIG_TYPES_TS),\n };\n}\n\n/** The types sibling of a config path — the two always share a directory. */\nexport function typesPathFor(configPath: string): string {\n return path.join(path.dirname(configPath), STANDARD_FILES.CONFIG_TYPES_TS);\n}\n\n/**\n * Writes `source` to `filePath` unless the file already holds exactly those\n * bytes. Both halves are derived from the same config on every write, so pair\n * coherence holds by derivation and the comparison only suppresses the mtime\n * churn a projects-only or scalar-only change would otherwise inflict on every\n * consumer watching these files. Returns true when the file was written.\n */\nasync function writeIfChanged(filePath: string, source: string): Promise<boolean> {\n assertGateToken(filePath);\n if ((await fileExists(filePath)) && (await readFile(filePath)) === source) return false;\n await writeFile(filePath, source);\n return true;\n}\n\n/**\n * Standalone (non-importing) type unions narrowed to `config`'s own entries,\n * widened by `extras` — the literals a just-created skill or agent needs before\n * it reaches the config.\n */\nfunction renderStandaloneTypes(\n config: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n extras?: ConfigTypesExtras,\n): string {\n const data = buildConfigTypesBackgroundData(matrix, agents);\n return generateConfigTypesSource(\n data.matrix,\n data.agentNames,\n data.customAgentNames,\n extras,\n config,\n );\n}\n\n/**\n * Writes the config half of the pair at `configPath`. The global config never\n * takes the project writer's import/inline options — it is the file those\n * options resolve against.\n *\n * The one renderer call left reading the singleton rather than taking a\n * catalogue: its sole caller is `mutateGlobal`, which writes this half BEFORE\n * `resolveGateDeps` runs, deliberately — a mutation with no registered projects\n * must not pay for the catalogue load. There is no catalogue in scope to pass.\n */\nexport async function writeGlobalConfigHalf(\n config: ProjectConfig,\n configPath: string,\n): Promise<boolean> {\n return writeIfChanged(configPath, generateConfigSource(config, activeMatrix));\n}\n\n/** Writes the types half of the pair beside `configPath`. */\nexport async function writeGlobalTypesHalf(\n config: ProjectConfig,\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n extras?: ConfigTypesExtras,\n): Promise<boolean> {\n return writeIfChanged(\n typesPathFor(configPath),\n renderStandaloneTypes(config, matrix, agents, extras),\n );\n}\n\n/**\n * Writes both halves from one config AND one catalogue, so they cannot disagree.\n *\n * The catalogue is the caller's `matrix` for both halves. It was the caller's for\n * the types half and the module singleton for the config half, which is the\n * disagreement this function's name says cannot happen: the two are the same\n * object on every production path today, and the whole reason the renderers take\n * a catalogue parameter is that a second caller seats a different one.\n */\nexport async function writeGlobalPair(\n config: ProjectConfig,\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): Promise<boolean> {\n const configWritten = await writeIfChanged(configPath, generateConfigSource(config, matrix));\n const typesWritten = await writeIfChanged(\n typesPathFor(configPath),\n renderStandaloneTypes(config, matrix, agents),\n );\n return configWritten || typesWritten;\n}\n\n/**\n * Creates a blank global pair at `~/.claude-src/` when none exists: `config.ts`\n * with empty arrays and `config-types.ts` with `never` unions. Returns true when\n * the files were created, false when they already existed.\n */\nexport async function ensureBlankPair(): Promise<boolean> {\n const { configPath, typesPath } = globalPairPaths();\n\n if (await fileExists(configPath)) {\n verbose(\"Global config already exists, skipping blank creation\");\n return false;\n }\n\n await ensureDir(path.dirname(configPath));\n\n await writeIfChanged(configPath, generateBlankGlobalConfigSource());\n await writeIfChanged(typesPath, generateBlankGlobalConfigTypesSource());\n\n verbose(`Created blank global config at ${path.dirname(configPath)}`);\n return true;\n}\n","import type { PropagatedRecompileSummary } from \"../operations/project/recompile-project-agents.js\";\n\n/** The summary of a fan-out that recompiled nothing, so callers render one shape. */\nexport const NOTHING_RECOMPILED: PropagatedRecompileSummary = {\n rewrittenCount: 0,\n unchangedCount: 0,\n failedCount: 0,\n warnings: [],\n};\n\n/**\n * Recompiles the agents of every project a global write propagated into.\n *\n * Imported lazily: `recompile-project-agents` lives in the operations layer,\n * which imports back into `installation`, so a static import here would form a\n * load-time cycle.\n * Per-project failure isolation lives in `recompilePropagatedProjectAgents` and\n * is unchanged by running it from inside the write.\n */\nexport async function recompilePropagated(\n projectDirs: string[],\n): Promise<PropagatedRecompileSummary> {\n if (projectDirs.length === 0) return NOTHING_RECOMPILED;\n\n const { recompilePropagatedProjectAgents } =\n await import(\"../operations/project/recompile-project-agents.js\");\n return recompilePropagatedProjectAgents(projectDirs);\n}\n","import path from \"path\";\nimport {\n buildAndMergeConfig,\n resolveInstallPaths,\n isHomeDirectory,\n} from \"../../installation/index.js\";\nimport type { SourceLoadResult } from \"../../loading/index.js\";\nimport type { AuthoritativeScope } from \"../../configuration/index.js\";\nimport {\n ensureBlankPair,\n writeScopedFromWizard,\n type GateReport,\n} from \"../../config-gate/index.js\";\nimport { loadAgentDefs, type AgentDefs } from \"./load-agent-defs.js\";\nimport { ensureDir } from \"../../../utils/fs.js\";\nimport type { ProjectConfig } from \"../../../types/index.js\";\nimport type { WizardResultV2 } from \"../../../components/wizard/wizard.js\";\n\nexport type ConfigWriteOptions = {\n wizardResult: WizardResultV2;\n sourceResult: SourceLoadResult;\n projectDir: string;\n sourceFlag?: string;\n /**\n * What {@link loadAgentDefs} answered, for a caller that has already asked it. Omitted, this\n * function asks for itself.\n *\n * It takes the WHOLE value rather than the roster inside it, so the only thing a caller can\n * hand over is what that one function produced. This used to be a bare\n * `Partial<Record<AgentName, AgentDefinition>>` — any map at all — which made \"a roster\n * different from the one the CLI would load\" a representable argument, and this function emits\n * the `AgentName` / `SelectedAgentName` unions from whatever it is given. Deleting the option\n * instead would cost `edit` a second uncached walk-and-parse of `src/agents/` per run, since\n * it needs `sourcePath` off the same value for its compile pass — one fact loaded twice, where\n * the second load is the one that can disagree.\n */\n agentDefs?: AgentDefs;\n /**\n * Authority of `cc edit`'s newConfig over absent entries:\n * `\"all\"` (global edit) drops any deselected entry, `\"owned\"` (project edit) drops deselected\n * project-owned entries only, `undefined` (init) keeps additive union-preserve.\n */\n authoritativeScope?: AuthoritativeScope;\n};\n\nexport type ConfigWriteResult = {\n config: ProjectConfig;\n configPath: string;\n wasMerged: boolean;\n existingConfigPath?: string;\n filesWritten: number;\n /**\n * What the gated write did: what moved in the global config, which registered\n * projects it fanned out to, and the recompile it drove in them. The caller\n * renders it; the work is already done.\n */\n propagation: GateReport;\n};\n\n/**\n * Builds, merges, and writes project configuration files.\n *\n * Handles the full config pipeline:\n * 1. buildAndMergeConfig() — generates config from wizard result, merges with existing\n * 2. loadAgentDefs() — the CLI's own sub-agent definitions, for config-types generation\n * 3. ensureBlankPair() — ensures the global config pair exists (when in project context)\n * 4. writeScopedFromWizard() — writes config.ts and config-types.ts split by scope,\n * fans global changes out to registered projects and recompiles their agents\n */\nexport async function writeProjectConfig(options: ConfigWriteOptions): Promise<ConfigWriteResult> {\n const { wizardResult, sourceResult, projectDir, sourceFlag } = options;\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n\n await ensureDir(path.dirname(projectPaths.configPath));\n\n // The marketplace is deliberately NOT consulted for this roster. It names the sub-agents the\n // emitted unions declare, and a marketplace-defined name in `AgentName` is one no compile pass\n // can honour: agent partials resolve through `getLocalAgentDefinitions`, which answers the\n // CLI's own root, and the generated `AGENT_NAMES` is built from that same directory. Reading\n // `sourceResult.sourcePath` here is what made `init` and `edit` emit two different files from\n // one config (owner ruling 2026-08-21).\n const { agents } = options.agentDefs ?? (await loadAgentDefs());\n\n const mergeResult = await buildAndMergeConfig(\n wizardResult,\n sourceResult,\n projectDir,\n sourceFlag,\n options.authoritativeScope,\n );\n const finalConfig = mergeResult.config;\n\n const isProjectContext = !isHomeDirectory(projectDir);\n\n if (isProjectContext) {\n await ensureBlankPair();\n }\n\n const propagation = await writeScopedFromWizard({\n finalConfig,\n matrix: sourceResult.matrix,\n agents,\n projectDir,\n projectConfigPath: projectPaths.configPath,\n projectInstallationExists: isProjectContext,\n // The same word the merger above took. It decides the config ROW there and the GLOBAL\n // config a project write commits here, and the two files disagree the moment it does not\n // reach both: a row preserved for a skill whose directory the removal diff deleted.\n ...(options.authoritativeScope !== undefined && {\n authoritativeScope: options.authoritativeScope,\n }),\n });\n\n return {\n config: finalConfig,\n configPath: projectPaths.configPath,\n wasMerged: mergeResult.merged,\n ...(mergeResult.existingConfigPath !== undefined && {\n existingConfigPath: mergeResult.existingConfigPath,\n }),\n filesWritten: isProjectContext ? 4 : 2,\n propagation,\n };\n}\n","import os from \"os\";\nimport { compileAgents, type CompilationResult } from \"./compile-agents.js\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../../installation/index.js\";\nimport type { AgentName, SkillDefinitionMap, SkillScope } from \"../../../types/index.js\";\n\nexport type CompileAllScopesOptions = {\n /** Working directory of the command — a project root, or home for global context. */\n projectDir: string;\n sourcePath: string;\n skills: SkillDefinitionMap;\n agentScopeMap: Map<AgentName, SkillScope>;\n};\n\n/**\n * Compiles agents for every scope the current context owns.\n *\n * Home context: a single pass writing to the home agents directory.\n * Project context: a global pass (from home) then a project pass, each\n * filtered to its own scope so the project pass cannot overwrite global\n * agents with zero-skill versions. Results merge in pass order.\n */\nexport async function compileAgentsAllScopes(\n options: CompileAllScopesOptions,\n): Promise<CompilationResult> {\n const { projectDir, sourcePath, skills, agentScopeMap } = options;\n const base = { sourcePath, skills, agentScopeMap };\n\n if (isHomeDirectory(projectDir)) {\n return compileAgents({\n ...base,\n projectDir,\n outputDir: resolveInstallPaths(projectDir, \"project\").agentsDir,\n });\n }\n\n const globalResult = await compileAgents({\n ...base,\n projectDir: os.homedir(),\n outputDir: resolveInstallPaths(os.homedir(), \"global\").agentsDir,\n scopeFilter: \"global\",\n });\n const projectResult = await compileAgents({\n ...base,\n projectDir,\n outputDir: resolveInstallPaths(projectDir, \"project\").agentsDir,\n scopeFilter: \"project\",\n });\n return mergeCompilationResults(globalResult, projectResult);\n}\n\nfunction mergeCompilationResults(...results: CompilationResult[]): CompilationResult {\n return {\n compiled: results.flatMap((r) => r.compiled),\n rewritten: results.flatMap((r) => r.rewritten),\n failed: results.flatMap((r) => r.failed),\n warnings: results.flatMap((r) => r.warnings),\n };\n}\n"],"mappings":"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","names":["matrix","isExclusiveCategory","os","path","isDeepEqual","EXTRACTED_FIELDS","matrix","matrix","recompilePropagatedProjectAgents","loadSkillsMatrixFromSource","matrix","loadAgentDefs","os","path","ensureBlankPair","path","path","ensureBlankPair","os","os"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/agents/list-compiled-agents.ts","../src/cli/lib/agents/agent-provenance.ts","../../compile/src/agent-source.ts","../src/cli/lib/agents/agent-fetcher.ts","../src/cli/lib/agents/agent-recompiler.ts","../src/cli/lib/agents/write-compiled-agents.ts","../src/cli/lib/compiler.ts","../src/cli/lib/agents/agent-plugin-compiler.ts"],"sourcesContent":["import path from \"path\";\nimport { partition } from \"remeda\";\nimport { glob, readFileOptional, remove } from \"../../utils/fs\";\nimport { isAgentName } from \"../../utils/type-guards\";\nimport { hasProvenanceMarker } from \"./agent-provenance\";\nimport type { AgentName } from \"../../types\";\n\n/** Compiled-agent basenames in a directory, split by whether this CLI compiled them. */\nexport type AgentProvenanceSplit = {\n /** Files carrying the provenance marker — provably written by this CLI. */\n marked: string[];\n /** Everything else in the directory, the user's own agents among them. */\n unmarked: string[];\n};\n\n/** Lists compiled-agent markdown filenames (e.g. \"web-developer.md\") in a directory. */\nexport async function listAgentMdFiles(agentsDir: string): Promise<string[]> {\n return glob(\"*.md\", agentsDir);\n}\n\n/**\n * Splits the agent files in a directory by the provenance marker each compiled agent carries.\n *\n * This is the only thing that identifies this CLI's own output once the configuration naming\n * it is gone, so the split errs one way by construction: a file that cannot be read yields no\n * marker and lands in `unmarked`, because \"cannot prove it is ours\" and \"is not ours\" call for\n * the same answer — leave it alone.\n */\nexport async function splitAgentsByProvenance(agentsDir: string): Promise<AgentProvenanceSplit> {\n const files = await listAgentMdFiles(agentsDir);\n const classified = await Promise.all(files.map((file) => readAgentProvenance(agentsDir, file)));\n const [marked, unmarked] = partition(classified, (agent) => agent.compiledHere);\n\n return { marked: marked.map(agentName), unmarked: unmarked.map(agentName) };\n}\n\ntype ClassifiedAgent = { name: string; compiledHere: boolean };\n\nasync function readAgentProvenance(agentsDir: string, file: string): Promise<ClassifiedAgent> {\n const content = await readFileOptional(path.join(agentsDir, file));\n return { name: path.basename(file, \".md\"), compiledHere: hasProvenanceMarker(content) };\n}\n\nfunction agentName(agent: ClassifiedAgent): string {\n return agent.name;\n}\n\n/** Lists compiled-agent names (filenames without the `.md` extension) in a directory. */\nexport async function listCompiledAgentNames(agentsDir: string): Promise<AgentName[]> {\n const files = await listAgentMdFiles(agentsDir);\n // Boundary cast: compiled .md filenames are agent names by convention; custom\n // agents from marketplace stacks may not be members of the AgentName union.\n return files.map((f) => path.basename(f, \".md\") as AgentName);\n}\n\n/**\n * Removes stale CLI-compiled agent files from `agentsDir`: deletes any `.md`\n * whose basename is a built-in CLI agent name (`isAgentName`) that is NOT in\n * `keep`. The built-in-name check protects hand-authored agents (whose basename\n * is not a built-in name) — it is never the removal criterion. Only call this\n * when `keep` is the COMPLETE set of agents that should live in `agentsDir`.\n */\nexport async function pruneStaleCompiledAgents(\n agentsDir: string,\n keep: ReadonlySet<AgentName>,\n): Promise<void> {\n // A non-built-in basename is a hand-authored agent — always preserved.\n const isStaleCompiledAgent = (file: string): boolean => {\n const name = path.basename(file, \".md\");\n return isAgentName(name) && !keep.has(name);\n };\n\n const files = await listAgentMdFiles(agentsDir);\n await Promise.all(\n files.filter(isStaleCompiledAgent).map((file) => remove(path.join(agentsDir, file))),\n );\n}\n","import path from \"path\";\nimport { z } from \"zod\";\n\nimport { PROJECT_ROOT, STANDARD_FILES } from \"../../consts\";\nimport { readFile } from \"../../utils/fs\";\n\n/** The one field the marker needs from this CLI's own manifest. */\nconst ownPackageJsonSchema = z.object({ version: z.string().min(1) });\n\n/**\n * The provenance marker every compiled agent carries lives in `@workspace/compile/agent-source`,\n * beside the renderer that stamps it — the editor's output preview draws the same first body line\n * and must not compute it a second way. What stays here is the half that reads this CLI's own\n * manifest, which a browser has no equivalent of.\n */\nexport {\n hasProvenanceMarker,\n provenanceMarker,\n stampProvenanceMarker,\n} from \"@workspace/compile/agent-source\";\n\nlet ownVersion: Promise<string> | undefined;\n\n/**\n * This CLI's own published version, read once per process from the package manifest beside\n * the code — the same `PROJECT_ROOT` the bundled agent partials and templates resolve from,\n * so the version in a marker is the version of the compiler that wrote it.\n */\nexport function cliVersion(): Promise<string> {\n ownVersion ??= readOwnVersion();\n return ownVersion;\n}\n\nasync function readOwnVersion(): Promise<string> {\n const manifestPath = path.join(PROJECT_ROOT, STANDARD_FILES.PACKAGE_JSON);\n const raw: unknown = JSON.parse(await readFile(manifestPath));\n\n const parsed = ownPackageJsonSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Could not read this CLI's own version from ${manifestPath}`);\n }\n return parsed.data.version;\n}\n","import type { Liquid } from \"liquidjs\"\n\nimport { diagnostics } from \"./diagnostics.js\"\nimport { DEFAULT_PLUGIN_NAME, EJECT_SOURCE } from \"./paths.js\"\nimport type {\n AgentConfig,\n CompiledAgentData,\n PluginSkillRef,\n Skill,\n} from \"./types.js\"\n\n/**\n * Everything that turns a resolved sub-agent into the markdown an install writes,\n * with two things left behind in the CLI because they read the machine: the five\n * `readFile`s that fetch an agent's partials off disk, and `cliVersion()`, which\n * reads the CLI's own manifest. Both arrive here as data — {@link AgentFiles} and\n * the `version` argument of {@link renderAgent} — which is what lets a browser\n * render the same bytes from the vendored corpus.\n */\n\n/** Pattern matching Liquid template delimiters that could enable template injection */\nconst LIQUID_SYNTAX_PATTERN = /\\{\\{|\\}\\}|\\{%|%\\}/g\n\n/**\n * Strips Liquid template syntax (`{{`, `}}`, `{%`, `%}`) from a string value.\n * Prevents template injection when user-controlled data is passed to the Liquid engine.\n *\n * @param value - Input string that may contain Liquid syntax\n * @param fieldName - Name of the field (for warning messages)\n * @returns Sanitized string with Liquid delimiters removed\n */\nexport function sanitizeLiquidSyntax<T extends string>(\n value: T,\n fieldName: string\n): T {\n if (!LIQUID_SYNTAX_PATTERN.test(value)) return value\n LIQUID_SYNTAX_PATTERN.lastIndex = 0\n const sanitized = value.replace(LIQUID_SYNTAX_PATTERN, \"\")\n diagnostics().warn(\n `Stripped Liquid template syntax from '${fieldName}' — possible template injection attempt`\n )\n // Boundary cast: .replace() widens the branded string T; stripping characters keeps it in T's domain\n return sanitized as T\n}\n\nfunction sanitizeStringArray(values: string[], fieldName: string): string[] {\n return values.map((v) => sanitizeLiquidSyntax(v, fieldName))\n}\n\nfunction sanitizeSkills(skills: Skill[]): Skill[] {\n return skills.map((s) => ({\n ...s,\n id: sanitizeLiquidSyntax(s.id, \"skill.id\"),\n description: sanitizeLiquidSyntax(s.description, \"skill.description\"),\n usage: sanitizeLiquidSyntax(s.usage, \"skill.usage\"),\n ...(s.pluginRef !== undefined && {\n pluginRef: sanitizeLiquidSyntax(s.pluginRef, \"skill.pluginRef\"),\n }),\n }))\n}\n\n/**\n * Sanitizes user-controlled metadata fields in compiled agent data to prevent\n * Liquid template injection. Strips `{{`, `}}`, `{%`, `%}` from agent\n * metadata and skill metadata before template rendering.\n *\n * Content fields (identity, playbook, output, criticalRequirementsTop,\n * criticalReminders) are passed through unchanged — LiquidJS does not\n * re-evaluate template syntax inside variable values, so double-curlies\n * in content (e.g. GitHub Actions `${{ secrets.X }}`) are safe.\n */\nexport function sanitizeCompiledAgentData(\n data: CompiledAgentData\n): CompiledAgentData {\n const sanitizedAgent: AgentConfig = {\n ...data.agent,\n name: sanitizeLiquidSyntax(data.agent.name, \"agent.name\"),\n title: sanitizeLiquidSyntax(data.agent.title, \"agent.title\"),\n description: sanitizeLiquidSyntax(\n data.agent.description,\n \"agent.description\"\n ),\n tools: sanitizeStringArray(data.agent.tools, \"agent.tools\"),\n ...(data.agent.disallowedTools !== undefined && {\n disallowedTools: sanitizeStringArray(\n data.agent.disallowedTools,\n \"agent.disallowedTools\"\n ),\n }),\n ...(data.agent.model !== undefined && {\n model: sanitizeLiquidSyntax(data.agent.model, \"agent.model\"),\n }),\n ...(data.agent.effort !== undefined && {\n effort: sanitizeLiquidSyntax(data.agent.effort, \"agent.effort\"),\n }),\n ...(data.agent.permissionMode !== undefined && {\n permissionMode: sanitizeLiquidSyntax(\n data.agent.permissionMode,\n \"agent.permissionMode\"\n ),\n }),\n }\n\n const sanitizedSkills = sanitizeSkills(data.skills)\n const sanitizedPreloaded = sanitizeSkills(data.preloadedSkills)\n const sanitizedDynamic = sanitizeSkills(data.dynamicSkills)\n const sanitizedPreloadedIds = data.preloadedSkillIds.map((id) =>\n sanitizeLiquidSyntax(id, \"preloadedSkillId\")\n )\n\n return {\n agent: sanitizedAgent,\n identity: data.identity,\n playbook: data.playbook,\n output: data.output,\n criticalRequirementsTop: data.criticalRequirementsTop,\n criticalReminders: data.criticalReminders,\n skills: sanitizedSkills,\n preloadedSkills: sanitizedPreloaded,\n dynamicSkills: sanitizedDynamic,\n preloadedSkillIds: sanitizedPreloadedIds,\n }\n}\n\n/**\n * The tool that loads a skill.\n *\n * A sub-agent's `tools:` frontmatter is an ALLOWLIST: an agent that declares one\n * gets exactly what it names, where an agent that omits the key inherits every\n * tool the session has. Every agent compiled here declares one, and no\n * `metadata.yaml` names this — so every agent this product had ever written was\n * unable to invoke a skill, while being instructed in the strongest terms the\n * template can manage to do exactly that.\n *\n * The `skills:` key does not close that gap, which is the non-obvious half and\n * the reason the defect survived: it preloads skill content into the agent's\n * startup context and grants no tool, so a compiled agent can list skills, carry\n * the activation protocol, and still have no way to load one.\n *\n * Granted to every agent rather than only to those with dynamic skills. Skills\n * are this product's atom: an agent has to be able to reach one a user adds\n * after it was compiled, and one its own playbook names in prose. It is a\n * read-only capability — it loads instructions and grants no write access — so\n * the deliberately read-only researchers take it on the same terms.\n */\nconst SKILL_TOOL = \"Skill\"\n\n/**\n * The same definition with {@link SKILL_TOOL} among its tools exactly once.\n *\n * Idempotent and order-stable: a definition already naming it is returned\n * unchanged, by identity, and everything else keeps its declared order with the\n * grant appended. Both halves are about the next compile — a second entry, or a\n * reordered list, would diff the frontmatter of every agent on disk.\n */\nfunction withSkillTool(agent: AgentConfig): AgentConfig {\n if (agent.tools.includes(SKILL_TOOL)) return agent\n return { ...agent, tools: [...agent.tools, SKILL_TOOL] }\n}\n\n/** The five markdown partials a sub-agent is assembled from, however they were fetched. */\nexport type AgentFiles = Pick<\n CompiledAgentData,\n | \"identity\"\n | \"playbook\"\n | \"output\"\n | \"criticalRequirementsTop\"\n | \"criticalReminders\"\n>\n\n/**\n * The template context for one sub-agent.\n *\n * The single assembly point for both front doors — the CLI's write path and the\n * editor's output preview — which is why {@link withSkillTool} is applied here\n * rather than in the eighteen `metadata.yaml` files: a user-authored agent gets\n * the grant on the same terms as a shipped one.\n *\n * The preloaded/dynamic split PRESERVES the order `agent.skills` arrives in, and\n * that order is `config.ts`'s stack key order — so the emitted rows of the\n * sub-agent's skill-activation table are decided by the config writer's\n * canonicalisation rather than by anything here.\n */\nexport function buildAgentTemplateContext(\n name: string,\n agent: AgentConfig,\n files: AgentFiles,\n mapSkill: (skill: Skill) => Skill = (skill) => skill\n): CompiledAgentData {\n const skills = agent.skills.map(mapSkill)\n const preloadedSkills = skills.filter((s) => s.preloaded)\n const dynamicSkills = skills.filter((s) => !s.preloaded)\n const preloadedSkillIds = preloadedSkills.map((s) => s.pluginRef ?? s.id)\n\n diagnostics().verbose(\n `Skills for ${name}: ${preloadedSkills.length} preloaded, ${dynamicSkills.length} dynamic`\n )\n\n return {\n agent: withSkillTool(agent),\n ...files,\n skills,\n preloadedSkills,\n dynamicSkills,\n preloadedSkillIds,\n }\n}\n\n/**\n * The per-skill pluginRef decision. A skill renders as `${id}:${id}` only\n * when it has an explicit non-eject source on its SkillReference — i.e. it was\n * installed from a marketplace. `undefined` source (user-authored local skills\n * with no SkillConfig entry) and `\"eject\"` both fall through to bare id.\n */\nexport function pluginRefFor(skill: Skill): { pluginRef?: PluginSkillRef } {\n if (skill.source === undefined || skill.source === EJECT_SOURCE) return {}\n return { pluginRef: `${skill.id}:${skill.id}` as const }\n}\n\n/**\n * The provenance marker every compiled agent carries: an HTML comment on the first line\n * after the frontmatter, naming the generator, its version, and the fact that the file is\n * rewritten rather than edited.\n *\n * **A body comment, deliberately not a frontmatter field.** Claude Code documents sixteen\n * supported frontmatter keys and says nothing about how it treats an unknown one, so a\n * stricter release could reject every agent this CLI has ever written. The body is free-form\n * by contract, which makes a marker there safe, greppable, versioned, and the do-not-edit\n * notice at the same time.\n *\n * The version is informational — {@link hasProvenanceMarker} matches on the marker's SHAPE,\n * so an agent compiled by any release is recognised by any other. Matching the exact text\n * would sweep only the agents the running version happened to write.\n */\nconst MARKER_OPEN = `<!-- Generated by ${DEFAULT_PLUGIN_NAME} v`\nconst MARKER_NOTICE = \" — do not edit; compile rewrites this file\"\nconst MARKER_CLOSE = \" -->\"\n\nconst FRONTMATTER_FENCE = \"---\"\n\nexport function provenanceMarker(version: string): string {\n return `${MARKER_OPEN}${version}${MARKER_NOTICE}${MARKER_CLOSE}`\n}\n\n/** Whether a line is a marker this CLI wrote, at any version and under any wording. */\nfunction isProvenanceMarker(line: string): boolean {\n return line.startsWith(MARKER_OPEN) && line.endsWith(MARKER_CLOSE)\n}\n\n/**\n * The index of the first body line: past the closing frontmatter fence when there is one,\n * and the top of the file when there is not — a template override may render no frontmatter,\n * and the marker still needs a defined home.\n */\nfunction bodyStartIndex(lines: readonly string[]): number {\n if (lines[0] !== FRONTMATTER_FENCE) return 0\n const closingFence = lines.indexOf(FRONTMATTER_FENCE, 1)\n if (closingFence === -1) return 0\n return closingFence + 1\n}\n\n/**\n * Whether this CLI compiled the agent file this content came from.\n *\n * The marker's POSITION is part of the claim: an agent that merely quotes the line further\n * down (a prompt about this very feature, say) is the user's, and a sweep reading that as\n * provenance would delete a file nothing here wrote.\n */\nexport function hasProvenanceMarker(content: string): boolean {\n const lines = content.split(\"\\n\")\n const firstBodyLine = lines[bodyStartIndex(lines)]\n return firstBodyLine !== undefined && isProvenanceMarker(firstBodyLine)\n}\n\n/**\n * The same content carrying exactly one provenance marker, on the first line after the\n * frontmatter.\n *\n * Idempotent by replacement rather than by insertion: content that already carries a marker\n * has that line rewritten, so stamping twice at one version is a fixed point and a version\n * bump moves the line instead of stacking a second one beside it.\n */\nexport function stampProvenanceMarker(\n content: string,\n version: string\n): string {\n const lines = content.split(\"\\n\")\n const bodyStart = bodyStartIndex(lines)\n const replacedLines = hasProvenanceMarker(content) ? 1 : 0\n\n return [\n ...lines.slice(0, bodyStart),\n provenanceMarker(version),\n ...lines.slice(bodyStart + replacedLines),\n ].join(\"\\n\")\n}\n\n/** The template every compiled sub-agent is rendered from, by name rather than by path. */\nconst AGENT_TEMPLATE = \"agent\"\n\n/**\n * Renders the agent template and stamps the result with the provenance marker.\n *\n * Every compile entry point renders through here, so there is no path that writes a compiled\n * agent this CLI cannot later recognise as its own — which is what `uninstall` reads back\n * when the configuration naming the agents is gone. The stamp replaces rather than inserts,\n * so a template that emits the marker itself still produces exactly one.\n *\n * `version` is an argument because the CLI reads it from its own `package.json` and a browser\n * has no manifest to read; the editor passes `CORPUS_CLI_VERSION`, the release the corpus was\n * vendored at.\n */\nexport async function renderAgent(\n engine: Liquid,\n data: CompiledAgentData,\n version: string\n): Promise<string> {\n // Boundary cast: liquidjs types renderFile as `Promise<any>` because a template\n // can render to any value. The agent template renders a markdown file, and both\n // callers have declared `Promise<string>` since they were written.\n const rendered = (await engine.renderFile(\n AGENT_TEMPLATE,\n sanitizeCompiledAgentData(data)\n )) as string\n return stampProvenanceMarker(rendered, version)\n}\n","import path from \"path\";\nimport { directoryExists } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { PROJECT_ROOT, DIRS } from \"../../consts\";\nimport { fetchFromSource, type FetchOptions } from \"../loading\";\nimport { loadProjectSourceConfig } from \"../configuration\";\nimport type { AgentSourcePaths } from \"../../types\";\n\nexport async function getAgentDefinitions(remoteSource?: string): Promise<AgentSourcePaths> {\n if (remoteSource) {\n return fetchAgentDefinitionsFromRemote(remoteSource);\n }\n return getLocalAgentDefinitions();\n}\n\nexport async function getLocalAgentDefinitions(): Promise<AgentSourcePaths> {\n const agentsDir = path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(agentsDir))) {\n throw new Error(\n `Agent partials not found at '${agentsDir}'. Ensure the CLI is properly installed.`,\n );\n }\n\n verbose(`Agent partials loaded from CLI: ${agentsDir}`);\n\n return {\n agentsDir,\n sourcePath: PROJECT_ROOT,\n };\n}\n\nexport async function fetchAgentDefinitionsFromRemote(\n source: string,\n options: FetchOptions & { agentsDir?: string } = {},\n): Promise<AgentSourcePaths> {\n verbose(`Fetching agent partials from remote: ${source}`);\n\n const result = await fetchFromSource(source, { subdir: \"\" });\n\n // ABORT on an unreadable config. It names the directory the fetched repository keeps its agent\n // partials in; defaulting past it compiles agents from whatever happens to sit at `DIRS.agents`,\n // or reports partials missing from a repository that has them.\n const sourceProjectConfig = options.agentsDir\n ? undefined\n : await loadProjectSourceConfig(result.path);\n if (sourceProjectConfig?.agentsDir) {\n verbose(`Using agentsDir from source config: ${sourceProjectConfig.agentsDir}`);\n }\n const agentsDirRelPath = options.agentsDir ?? sourceProjectConfig?.agentsDir ?? DIRS.agents;\n\n const agentsDir = path.join(result.path, agentsDirRelPath);\n\n if (!(await directoryExists(agentsDir))) {\n throw new Error(`Agent partials not found at '${agentsDir}'`);\n }\n\n verbose(`Agent partials fetched from: ${result.path}`);\n\n return {\n agentsDir,\n sourcePath: result.path,\n };\n}\n","import { partition } from \"remeda\";\nimport { writeCompiledAgentsByScope, type AgentWriteOutcome } from \"./write-compiled-agents\";\nimport { listCompiledAgentNames } from \"./list-compiled-agents\";\nimport path from \"path\";\n\nimport { getErrorMessage } from \"../../utils/errors\";\nimport type {\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n ProjectConfig,\n SkillDefinitionMap,\n SkillScope,\n} from \"../../types\";\n\nimport { buildCompileAgents } from \"../installation/local-installer\";\nimport { ensureDir } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedFromEntries, typedKeys } from \"../../utils/typed-object\";\nimport { createLiquidEngine } from \"../compiler\";\nimport { loadProjectConfig, effectivelyExcludedSkillIds } from \"../configuration\";\nimport { loadAllAgents, loadProjectAgents } from \"../loading\";\nimport { getPluginAgentsDir } from \"../plugins\";\nimport { discoverAllPluginSkills } from \"../plugins/plugin-discovery\";\nimport { resolveAgents } from \"../resolver\";\n\nexport type RecompileAgentsOptions = {\n pluginDir: string;\n sourcePath: string;\n agents?: AgentName[];\n skills?: SkillDefinitionMap;\n projectDir?: string;\n outputDir?: string;\n /** When provided, routes agents by scope: global agents to ~/.claude/agents/, project agents to outputDir */\n agentScopeMap?: Map<AgentName, SkillScope>;\n};\n\nexport type RecompileAgentsResult = {\n compiled: AgentName[];\n /**\n * The subset of `compiled` whose file this pass actually wrote. `compiled` is\n * every agent that came through the pass with a correct file at the end of it;\n * `rewritten` is the ones whose content moved, so `compiled minus rewritten` is\n * the count a summary reports as unchanged.\n */\n rewritten: AgentName[];\n failed: AgentName[];\n warnings: string[];\n};\n\nasync function getExistingAgentNames(pluginDir: string): Promise<AgentName[]> {\n return listCompiledAgentNames(getPluginAgentsDir(pluginDir));\n}\n\ntype ResolveAgentNamesParams = {\n specifiedAgents?: AgentName[];\n projectConfig: ProjectConfig | null;\n allAgents: Partial<Record<AgentName, AgentDefinition>>;\n outputDir?: string;\n pluginDir: string;\n};\n\nasync function resolveAgentNames(params: ResolveAgentNamesParams): Promise<AgentName[]> {\n const { specifiedAgents, projectConfig, allAgents, outputDir, pluginDir } = params;\n\n if (specifiedAgents) {\n return specifiedAgents;\n }\n\n // A present config is authoritative over its agent roster — even when empty.\n // `agents: []` means \"no agents\", so it must NOT fall through to the\n // all-agents branch below; that branch exists only for the config-LESS case.\n if (projectConfig) {\n const agentNames = projectConfig.agents.map((a) => a.name);\n verbose(`Using agents from config: ${agentNames.join(\", \")}`);\n return agentNames;\n }\n\n if (outputDir) {\n const names = typedKeys<AgentName>(allAgents);\n verbose(`Using all available agents from source: ${names.join(\", \")}`);\n return names;\n }\n\n return getExistingAgentNames(pluginDir);\n}\n\n/** Splits write outcomes into the recompile result; logs each success at verbose level. */\nfunction buildRecompileResult(\n outcomes: AgentWriteOutcome[],\n priorWarnings: string[],\n): RecompileAgentsResult {\n const [succeeded, failedOutcomes] = partition(\n outcomes,\n (outcome): outcome is Extract<AgentWriteOutcome, { ok: true }> => outcome.ok,\n );\n succeeded.forEach((outcome) =>\n verbose(\n ` ${outcome.rewritten ? \"Rewrote\" : \"Unchanged\"}: ${outcome.name} (${outcome.scope} -> ${outcome.targetDir})`,\n ),\n );\n return {\n compiled: succeeded.map((outcome) => outcome.name),\n rewritten: succeeded.filter((outcome) => outcome.rewritten).map((outcome) => outcome.name),\n failed: failedOutcomes.map((outcome) => outcome.name),\n warnings: [\n ...priorWarnings,\n ...failedOutcomes.map(\n (outcome) => `Failed to compile ${outcome.name}: ${getErrorMessage(outcome.error)}`,\n ),\n ],\n };\n}\n\nexport function filterExcludedEntries(config: ProjectConfig): ProjectConfig {\n const excludedIds = effectivelyExcludedSkillIds(config.skills);\n const activeSkills = config.skills.filter((s) => !s.excluded);\n const activeAgents = config.agents.filter((a) => !a.excluded);\n\n // Also remove excluded skill refs from stack assignments. A config with no stack keeps\n // none — the key stays absent rather than becoming an explicit `undefined`.\n const filteredStack =\n config.stack === undefined\n ? {}\n : {\n stack: Object.fromEntries(\n typedEntries(config.stack).map(([agentName, agentStack]) => [\n agentName,\n Object.fromEntries(\n typedEntries(agentStack).map(([category, assignments]) => [\n category,\n assignments.filter((a) => !excludedIds.has(a.id)),\n ]),\n ),\n ]),\n ),\n };\n\n return { ...config, skills: activeSkills, agents: activeAgents, ...filteredStack };\n}\n\nexport async function recompileAgents(\n options: RecompileAgentsOptions,\n): Promise<RecompileAgentsResult> {\n const { pluginDir, sourcePath, skills: providedSkills, projectDir, outputDir } = options;\n\n const configDir = projectDir ?? pluginDir;\n const loadedConfig = await loadProjectConfig(configDir);\n const projectConfig = loadedConfig?.config ?? null;\n\n // Filter excluded entries once at the entry point — callees receive clean data\n const filteredConfig = projectConfig ? filterExcludedEntries(projectConfig) : null;\n\n const builtinAgents = await loadAllAgents(sourcePath);\n const projectAgents = projectDir ? await loadProjectAgents(projectDir) : {};\n\n // Priority: project agents > built-in agents\n const allAgents: Partial<Record<AgentName, AgentDefinition>> = {\n ...builtinAgents,\n ...projectAgents,\n };\n\n const agentNames = await resolveAgentNames({\n ...(options.agents !== undefined && { specifiedAgents: options.agents }),\n projectConfig: filteredConfig,\n allAgents,\n ...(outputDir !== undefined && { outputDir }),\n pluginDir,\n });\n\n if (agentNames.length === 0) {\n return { compiled: [], rewritten: [], failed: [], warnings: [\"No agents found to recompile\"] };\n }\n\n verbose(`Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`);\n\n // When skills are not provided, discover from all plugin directories.\n const pluginSkills: SkillDefinitionMap =\n providedSkills ?? (await discoverAllPluginSkills(projectDir ?? pluginDir));\n\n const allConfigAgents = filteredConfig ? buildCompileAgents(filteredConfig, allAgents) : {};\n\n // Restrict to only the agents we're compiling (agentNames).\n // buildCompileAgents returns entries for ALL agents in the config, but when\n // scopeFilter is active, we only want the agents matching that scope.\n // Without this filter, a project pass would compile global agents without\n // their stack (since the project config omits global agent stack entries)\n // and overwrite correctly compiled global agent files.\n const [knownAgents, missingAgents] = partition(agentNames, (name) =>\n Boolean(allConfigAgents[name] || allAgents[name]),\n );\n const missingWarnings = missingAgents.map(\n (name) => `Agent \"${name}\" not found in source definitions`,\n );\n const configAgents = typedFromEntries<AgentName, CompileAgentConfig>(\n knownAgents.map((name) => [name, allConfigAgents[name] ?? {}]),\n );\n\n const compileConfig: CompileConfig = {\n name: filteredConfig?.name || path.basename(pluginDir),\n description: filteredConfig?.description || \"Recompiled plugin\",\n agents: configAgents,\n };\n\n const engine = await createLiquidEngine(projectDir);\n const resolvedAgents = await resolveAgents(allAgents, pluginSkills, compileConfig, sourcePath);\n\n const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);\n await ensureDir(agentsDir);\n\n const outcomes = await writeCompiledAgentsByScope({\n resolvedAgents,\n sourcePath,\n engine,\n projectAgentsDir: agentsDir,\n ...(options.agentScopeMap !== undefined && { agentScopeMap: options.agentScopeMap }),\n });\n return buildRecompileResult(outcomes, missingWarnings);\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { Liquid } from \"liquidjs\";\nimport { compileAgentForPlugin } from \"../compiler.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { writeFile, fileExists, readFile } from \"../../utils/fs.js\";\nimport { typedEntries } from \"../../utils/typed-object.js\";\nimport type { AgentConfig, AgentName, SkillScope } from \"../../types/index.js\";\n\nexport type AgentWriteOutcome =\n | {\n name: AgentName;\n ok: true;\n scope: SkillScope;\n targetDir: string;\n /**\n * Whether this pass actually wrote the file. False means the compiled output\n * matched what was already on disk, so nothing was written — which is what\n * lets a recompile summary tell a real one from a no-op instead of counting\n * the roster it walked.\n */\n rewritten: boolean;\n }\n | { name: AgentName; ok: false; error: unknown };\n\n/**\n * Whether the target already holds exactly this content, making a write a no-op.\n *\n * Skipping that write is what gives \"unchanged\" a meaning a caller can check: an\n * agent reported unchanged keeps its mtime, and an mtime is the only trace a\n * rewrite-with-identical-bytes leaves anywhere.\n */\nasync function holdsExactly(filePath: string, content: string): Promise<boolean> {\n return (await fileExists(filePath)) && (await readFile(filePath)) === content;\n}\n\n/**\n * Where an agent goes when `agentScopeMap` has nothing to say about it — either because the caller\n * passed no map at all (`agents-inc update` recompiles that way) or because this agent is not in\n * the one it passed (a hand-authored agent under `.claude/agents/` has no config row).\n *\n * This is a ROUTING answer, not a selection default: `\"project\"` here means \"the directory the\n * caller named in `projectAgentsDir`\", which for an unrouted write is the only defensible target.\n * It is deliberately NOT `DEFAULT_SELECTION_OPTIONS.scope` from `@workspace/matrix` — that constant\n * says what an untouched *pick* installs as, and adopting it here would relocate the agents of every\n * caller that never asked for global routing into the user's `~/.claude/agents`.\n */\nconst UNROUTED_AGENT_SCOPE: SkillScope = \"project\";\n\n/**\n * Compiles each resolved agent and writes it to its scope's agents directory:\n * global agents to `~/.claude/agents/`, project agents to `projectAgentsDir`.\n * Per-agent failures are collected as outcomes — callers own the policy\n * (recompile reports and continues; install hard-errors).\n *\n * Neither directory is created up front. `writeFile` makes a target's parent on\n * the way past, so a directory appears exactly when an agent routes into it —\n * which is what keeps a wholly project-scoped pass from leaving an empty\n * `~/.claude/agents/` behind in a home that has no global install.\n */\nexport async function writeCompiledAgentsByScope(params: {\n resolvedAgents: Partial<Record<AgentName, AgentConfig>>;\n sourcePath: string;\n engine: Liquid;\n projectAgentsDir: string;\n agentScopeMap?: Map<AgentName, SkillScope>;\n}): Promise<AgentWriteOutcome[]> {\n const globalAgentsDir = resolveInstallPaths(os.homedir(), \"global\").agentsDir;\n\n const outcomes: AgentWriteOutcome[] = [];\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(params.resolvedAgents)) {\n try {\n const output = await compileAgentForPlugin(name, agent, params.sourcePath, params.engine);\n const scope = params.agentScopeMap?.get(name) ?? UNROUTED_AGENT_SCOPE;\n const targetDir = scope === \"global\" ? globalAgentsDir : params.projectAgentsDir;\n const targetPath = path.join(targetDir, `${name}.md`);\n const rewritten = !(await holdsExactly(targetPath, output));\n if (rewritten) await writeFile(targetPath, output);\n outcomes.push({ name, ok: true, scope, targetDir, rewritten });\n } catch (error) {\n outcomes.push({ name, ok: false, error });\n }\n }\n return outcomes;\n}\n","import { Liquid } from \"liquidjs\";\nimport path from \"path\";\nimport {\n buildAgentTemplateContext,\n pluginRefFor,\n renderAgent,\n type AgentFiles,\n} from \"@workspace/compile/agent-source\";\nimport { readFile, readFileOptional, directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n DIRS,\n PROJECT_ROOT,\n STANDARD_FILES,\n STANDARD_DIRS,\n} from \"../consts\";\nimport { cliVersion } from \"./agents/agent-provenance\";\nimport \"./compile-seat.js\";\nimport type { AgentConfig, AgentName } from \"../types\";\n\n/**\n * What survives here is the half of a compile that reads the machine: the five `readFile`s that\n * fetch an agent's partials off disk, and the layered template roots a project can override. The\n * rendering itself — the template context, the injection sanitiser and the provenance stamp — is\n * `@workspace/compile/agent-source`, so the editor's output preview draws the bytes this writes\n * rather than a second implementation of them.\n */\nexport {\n buildAgentTemplateContext,\n sanitizeCompiledAgentData,\n sanitizeLiquidSyntax,\n} from \"@workspace/compile/agent-source\";\n\nasync function readAgentFiles(\n name: AgentName,\n agent: AgentConfig,\n projectRoot: string,\n): Promise<AgentFiles> {\n const agentSourceRoot = agent.sourceRoot || projectRoot;\n const agentBaseDir = agent.agentBaseDir || DIRS.agents;\n const agentDir = path.join(agentSourceRoot, agentBaseDir, agent.path || name);\n\n const identity = await readFile(path.join(agentDir, STANDARD_FILES.IDENTITY_MD));\n const playbook = await readFile(path.join(agentDir, STANDARD_FILES.PLAYBOOK_MD));\n const criticalRequirementsTop = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REQUIREMENTS_MD),\n \"\",\n );\n const criticalReminders = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REMINDERS_MD),\n \"\",\n );\n\n const agentPath = agent.path || name;\n const parts = agentPath.split(\"/\");\n const category = parts[0] || name;\n const categoryDir = path.join(agentSourceRoot, agentBaseDir, category);\n\n let output = await readFileOptional(path.join(agentDir, STANDARD_FILES.OUTPUT_MD), \"\");\n if (!output) {\n output = await readFileOptional(path.join(categoryDir, STANDARD_FILES.OUTPUT_MD), \"\");\n }\n\n return { identity, playbook, output, criticalRequirementsTop, criticalReminders };\n}\n\n/**\n * Creates a Liquid template engine with a layered template root hierarchy.\n *\n * Template resolution order (first match wins):\n * 1. Project-local templates: `{projectDir}/.claude-src/agents/_templates/`\n * 2. Legacy templates: `{projectDir}/.claude/templates/`\n * 3. Built-in templates: `{PROJECT_ROOT}/src/agents/_templates/`\n *\n * The browser-side twin is `createEngineFromTemplates` in `@workspace/compile/engine`, which\n * builds the same engine over the vendored corpus instead of over directories. Every option\n * below is duplicated there, because a render that resolved filters or variables differently\n * would produce a different file from the same data.\n *\n * @param projectDir - Optional project directory for local template overrides\n * @returns Configured Liquid engine with `.liquid` extension and strict filters\n */\nexport async function createLiquidEngine(projectDir?: string): Promise<Liquid> {\n const roots: string[] = [];\n\n if (projectDir) {\n const srcTemplatesDir = path.join(\n projectDir,\n CLAUDE_SRC_DIR,\n STANDARD_DIRS.AGENTS,\n path.basename(DIRS.templates),\n );\n if (await directoryExists(srcTemplatesDir)) {\n roots.push(srcTemplatesDir);\n verbose(`Using local templates from: ${srcTemplatesDir}`);\n }\n\n const legacyTemplatesDir = path.join(projectDir, CLAUDE_DIR, STANDARD_DIRS.TEMPLATES);\n if (await directoryExists(legacyTemplatesDir)) {\n roots.push(legacyTemplatesDir);\n verbose(`Using legacy templates from: ${legacyTemplatesDir}`);\n }\n }\n\n roots.push(path.join(PROJECT_ROOT, DIRS.templates));\n\n return new Liquid({\n root: roots,\n extname: \".liquid\",\n strictVariables: false,\n strictFilters: true,\n });\n}\n\nexport async function compileAgentForPlugin(\n name: AgentName,\n agent: AgentConfig,\n fallbackRoot: string,\n engine: Liquid,\n): Promise<string> {\n verbose(`Compiling agent: ${name}`);\n\n const files = await readAgentFiles(name, agent, fallbackRoot);\n\n // Per-skill pluginRef attachment. Each skill's own `source` decides\n // whether it renders as `${id}:${id}` (plugin-installed) or bare id (ejected).\n // This correctly handles mixed-mode agents where some skills are plugin and\n // others are ejected. Missing `source` (user-authored local skills with no\n // SkillConfig entry) falls through to bare id — the expected case, not a\n // silent fallback.\n const data = buildAgentTemplateContext(name, agent, files, (skill) => ({\n ...skill,\n ...pluginRefFor(skill),\n }));\n\n return renderAgent(engine, data, await cliVersion());\n}\n","import path from \"path\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { readFile, ensureDir, copy } from \"../../utils/fs\";\nimport { log, verbose, warn } from \"../../utils/logger\";\nimport {\n generateAgentPluginManifest,\n writePluginManifest,\n getPluginManifestPath,\n} from \"../plugins\";\nimport { listAgentMdFiles } from \"./list-compiled-agents\";\nimport { computeStringHash, determinePluginVersion, writeContentHash } from \"../versioning\";\nimport { extractFrontmatter } from \"../../utils/frontmatter\";\nimport type { AgentFrontmatter, PluginManifest } from \"../../types\";\nimport { agentFrontmatterValidationSchema, formatZodIssues } from \"../schemas\";\n\nexport type AgentPluginOptions = {\n agentPath: string;\n outputDir: string;\n};\n\nexport type CompiledAgentPlugin = {\n pluginPath: string;\n manifest: PluginManifest;\n agentName: string;\n};\n\nfunction parseAgentFrontmatter(\n content: string,\n filePath: string,\n): Pick<AgentFrontmatter, \"name\" | \"description\"> | null {\n const raw = extractFrontmatter(content);\n if (!raw) {\n return null;\n }\n\n const result = agentFrontmatterValidationSchema.safeParse(raw);\n if (!result.success) {\n warn(`Invalid agent frontmatter in ${filePath}: ${formatZodIssues(result.error.issues)}`);\n return null;\n }\n\n return { name: result.data.name, description: result.data.description };\n}\n\nexport async function compileAgentPlugin(\n options: AgentPluginOptions,\n): Promise<CompiledAgentPlugin> {\n const { agentPath, outputDir } = options;\n const fileName = path.basename(agentPath);\n\n const content = await readFile(agentPath);\n const frontmatter = parseAgentFrontmatter(content, agentPath);\n\n if (!frontmatter) {\n throw new Error(\n `Agent '${fileName}' has invalid or missing YAML frontmatter. ` +\n `Required fields: 'name' and 'description'. File: ${agentPath}`,\n );\n }\n\n const agentName = frontmatter.name;\n\n verbose(`Compiling agent plugin: ${agentName} from ${agentPath}`);\n\n const pluginDir = path.join(outputDir, `agent-${agentName}`);\n const agentsDir = path.join(pluginDir, \"agents\");\n\n await ensureDir(pluginDir);\n await ensureDir(agentsDir);\n\n const newHash = computeStringHash(content);\n const { version, contentHash } = await determinePluginVersion(\n newHash,\n pluginDir,\n getPluginManifestPath,\n );\n\n const manifest = generateAgentPluginManifest({\n agentName,\n description: frontmatter.description,\n version,\n });\n\n await writePluginManifest(pluginDir, manifest);\n\n await writeContentHash(pluginDir, contentHash, getPluginManifestPath);\n\n verbose(` Wrote plugin.json for ${agentName} (v${version})`);\n\n await copy(agentPath, path.join(agentsDir, `${agentName}.md`));\n verbose(` Copied agent ${fileName} -> agents/${agentName}.md`);\n\n return {\n pluginPath: pluginDir,\n manifest,\n agentName,\n };\n}\n\nexport async function compileAllAgentPlugins(\n agentsDir: string,\n outputDir: string,\n): Promise<CompiledAgentPlugin[]> {\n const results: CompiledAgentPlugin[] = [];\n\n const agentMdFiles = await listAgentMdFiles(agentsDir);\n\n for (const agentFile of agentMdFiles) {\n const agentPath = path.join(agentsDir, agentFile);\n\n try {\n const result = await compileAgentPlugin({\n agentPath,\n outputDir,\n });\n results.push(result);\n log(` [OK] agent-${result.agentName}`);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n warn(`Failed to compile agent from '${agentFile}': ${errorMessage}`);\n }\n }\n\n return results;\n}\n\nexport function printAgentCompilationSummary(results: CompiledAgentPlugin[]): void {\n log(`\\nCompiled ${results.length} agent plugins:`);\n for (const result of results) {\n log(` - agent-${result.agentName} (v${result.manifest.version})`);\n }\n}\n"],"mappings":"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","names":["path","path","path","path","partition","path","path","path","path","path","partition","agentName","path","path","path","agentName"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/operations/project/remove-compiled-agents.ts","../src/cli/lib/operations/project/compile-agents.ts","../src/cli/lib/operations/skills/discover-skills.ts","../src/cli/lib/operations/skills/copy-local-skills.ts","../src/cli/lib/operations/skills/uninstall-plugin-skills.ts","../src/cli/lib/operations/project/recompile-project-agents.ts"],"sourcesContent":["import path from \"path\";\nimport { pruneStaleCompiledAgents } from \"../../agents/list-compiled-agents.js\";\nimport { getErrorMessage } from \"../../../utils/errors.js\";\nimport { remove, removeDirIfEmpty } from \"../../../utils/fs.js\";\nimport type { AgentName } from \"../../../types/index.js\";\n\nconst AGENT_FILE_EXTENSION = \".md\";\n\nexport type RemoveCompiledAgentsOptions = {\n /** The scope's `.claude/agents/` directory holding the compiled files. */\n agentsDir: string;\n agents: readonly AgentName[];\n};\n\nexport type PruneCompiledAgentsOptions = {\n agentsDir: string;\n /**\n * The COMPLETE set of agents that belong in `agentsDir` — every other\n * CLI-compiled agent there is stale. Only an authoritative pass can say this.\n */\n keep: ReadonlySet<AgentName>;\n};\n\nexport type RemoveCompiledAgentsResult = {\n /** Agents whose compiled file this call disposed of; an absent file counts. */\n removed: AgentName[];\n /** Agents whose file survived an error, for the caller to report. */\n failed: Array<{ name: AgentName; error: string }>;\n};\n\ntype RemovalOutcome = { name: AgentName; ok: true } | { name: AgentName; ok: false; error: string };\n\n/**\n * Deletes the named agents' compiled `.md` files from `agentsDir`, then takes the\n * directory itself when nothing at all is left in it — the shape `deleteLocalSkill`\n * models for skills.\n *\n * A scope's `.claude/agents/` is an artefact of what it holds, so the removal that\n * empties it owns the tidy and no caller has to remember. An agent with no file on\n * disk is nothing to do rather than an error.\n */\nexport async function removeCompiledAgents(\n options: RemoveCompiledAgentsOptions,\n): Promise<RemoveCompiledAgentsResult> {\n const outcomes = await Promise.all(\n options.agents.map((name) => removeCompiledAgentFile(options.agentsDir, name)),\n );\n await tidyEmptiedAgentsDir(options.agentsDir);\n\n return {\n removed: outcomes.flatMap((outcome) => (outcome.ok ? [outcome.name] : [])),\n failed: outcomes.flatMap((outcome) =>\n outcome.ok ? [] : [{ name: outcome.name, error: outcome.error }],\n ),\n };\n}\n\n/**\n * Deletes every CLI-compiled agent in `agentsDir` outside `keep`, then takes the\n * directory on the same terms as `removeCompiledAgents`.\n *\n * Hand-authored agents are preserved by `pruneStaleCompiledAgents`'s `isAgentName`\n * predicate, so a directory this leaves empty is one nothing at all remains in.\n */\nexport async function pruneCompiledAgents(options: PruneCompiledAgentsOptions): Promise<void> {\n await pruneStaleCompiledAgents(options.agentsDir, options.keep);\n await tidyEmptiedAgentsDir(options.agentsDir);\n}\n\nasync function removeCompiledAgentFile(\n agentsDir: string,\n name: AgentName,\n): Promise<RemovalOutcome> {\n try {\n await remove(path.join(agentsDir, `${name}${AGENT_FILE_EXTENSION}`));\n return { name, ok: true };\n } catch (error) {\n return { name, ok: false, error: getErrorMessage(error) };\n }\n}\n\n/**\n * Emptiness is FILESYSTEM emptiness, never roster emptiness: a hand-authored agent\n * or any user-owned file keeps the directory alive whatever a config says. The\n * agents directory only — `.claude/` above it is uninstall's decision, not a\n * removal path's.\n */\nasync function tidyEmptiedAgentsDir(agentsDir: string): Promise<void> {\n await removeDirIfEmpty(agentsDir);\n}\n","import { pruneCompiledAgents } from \"./remove-compiled-agents.js\";\nimport { recompileAgents } from \"../../agents/index.js\";\nimport { loadProjectConfigFromDir } from \"../../configuration/index.js\";\nimport { buildAgentScopeMap } from \"../../installation/index.js\";\nimport type { AgentName, SkillDefinitionMap, SkillScope } from \"../../../types/index.js\";\n\nexport type CompileAgentsOptions = {\n projectDir: string;\n sourcePath: string;\n pluginDir?: string;\n skills?: SkillDefinitionMap;\n agentScopeMap?: Map<AgentName, SkillScope>;\n agents?: AgentName[];\n /** When set, loads config and filters agents to only those matching this scope. */\n scopeFilter?: SkillScope;\n outputDir?: string;\n};\n\nexport type CompilationResult = {\n compiled: AgentName[];\n /**\n * The subset of `compiled` whose file this pass actually wrote. A pass whose\n * `rewritten` is empty changed nothing on disk, which is exactly what the\n * recompile summary reports and what the count it replaced could not say.\n */\n rewritten: AgentName[];\n failed: AgentName[];\n warnings: string[];\n};\n\n/**\n * Compiles agent markdown files from templates + skill content.\n *\n * Thin wrapper around recompileAgents() that standardizes options.\n * The caller invokes this once (edit, update) or twice with scopeFilter (compile).\n */\nexport async function compileAgents(options: CompileAgentsOptions): Promise<CompilationResult> {\n let resolvedAgents = options.agents;\n let resolvedAgentScopeMap = options.agentScopeMap;\n\n if (options.scopeFilter) {\n const loadedConfig = await loadProjectConfigFromDir(options.projectDir);\n\n // Auto-build agentScopeMap from config if not provided\n if (!resolvedAgentScopeMap && loadedConfig?.config) {\n resolvedAgentScopeMap = buildAgentScopeMap(loadedConfig.config);\n }\n\n const filteredAgents = loadedConfig?.config.agents\n .filter((a) => !a.excluded && a.scope === options.scopeFilter)\n .map((a) => a.name);\n\n if (resolvedAgents && filteredAgents) {\n const filterSet = new Set(filteredAgents);\n resolvedAgents = resolvedAgents.filter((a) => filterSet.has(a));\n } else if (filteredAgents) {\n resolvedAgents = filteredAgents;\n }\n }\n\n const recompileResult = await recompileAgents({\n pluginDir: options.pluginDir ?? options.projectDir,\n sourcePath: options.sourcePath,\n ...(resolvedAgents !== undefined && { agents: resolvedAgents }),\n ...(options.skills !== undefined && { skills: options.skills }),\n projectDir: options.projectDir,\n ...(options.outputDir !== undefined && { outputDir: options.outputDir }),\n ...(resolvedAgentScopeMap !== undefined && { agentScopeMap: resolvedAgentScopeMap }),\n });\n\n await pruneStaleAgentsForPass(options, recompileResult);\n\n return {\n compiled: recompileResult.compiled,\n rewritten: recompileResult.rewritten,\n failed: recompileResult.failed,\n warnings: recompileResult.warnings,\n };\n}\n\n/**\n * Compiled-agent writes are additive, so a deselected or stale agent's `.md`\n * lingers after recompile. An authoritative, scope-UNfiltered pass owns its\n * entire `outputDir` (its resolved roster is the full set for that directory),\n * so it prunes built-in agents no longer compiled there. A scope-FILTERED pass\n * (the hasBoth two-pass compile, or the registered-project recompile)\n * sees only one scope's agents and must never delete another scope's files, so\n * it skips pruning. Removing the stale files and tidying the directory they\n * emptied is one operation's job, not this pass's.\n */\nasync function pruneStaleAgentsForPass(\n options: CompileAgentsOptions,\n recompileResult: CompilationResult,\n): Promise<void> {\n if (options.scopeFilter || !options.outputDir) return;\n\n const compiledForDir = new Set<AgentName>([\n ...recompileResult.compiled,\n ...recompileResult.failed,\n ]);\n await pruneCompiledAgents({ agentsDir: options.outputDir, keep: compiledForDir });\n}\n","import path from \"path\";\nimport { discoverAllPluginSkills } from \"../../plugins/index.js\";\nimport { isHomeDirectory } from \"../../installation/is-home-directory.js\";\n// loadSkillsFromDir lives in loading/ (a leaf) so both this module and\n// plugins/plugin-discovery can share it without an operations↔plugins cycle.\nimport { loadSkillsFromDir, type LoadedSkills } from \"../../loading/index.js\";\nimport { verbose } from \"../../../utils/logger.js\";\nimport { globalInstallRoot, LOCAL_SKILLS_PATH } from \"../../../consts.js\";\nimport { typedEntries, typedKeys } from \"../../../utils/typed-object.js\";\nimport type { UnusableSkillMetadata } from \"../../loading/index.js\";\nimport type { SkillDefinition, SkillDefinitionMap, SkillId } from \"../../../types/index.js\";\n\nexport type DiscoveredSkills = {\n allSkills: SkillDefinitionMap;\n totalSkillCount: number;\n pluginSkillCount: number;\n localSkillCount: number;\n globalPluginSkillCount: number;\n globalLocalSkillCount: number;\n /**\n * Installed skills whose metadata.yaml exists but describes no skill, from either\n * scope. Nothing was loaded for them; `compile` refuses the run over any entry\n * here rather than compile agents around a skill its metadata does not describe.\n */\n unusableMetadata: UnusableSkillMetadata[];\n};\n\n/** The result of a local-skill scan that was not performed. */\nconst NO_LOCAL_SKILLS: LoadedSkills = { skills: {}, unusableMetadata: [] };\n\n/**\n * Discovers local (non-plugin) skills from `<rootDir>/.claude/skills/`. Used for\n * both the project root and the global install root.\n */\nexport async function discoverLocalProjectSkills(rootDir: string): Promise<LoadedSkills> {\n const localSkillsDir = path.join(rootDir, LOCAL_SKILLS_PATH);\n return loadSkillsFromDir(localSkillsDir, {\n pathPrefix: LOCAL_SKILLS_PATH,\n requireMetadata: true,\n });\n}\n\n/** Merges skill maps — later sources take precedence over earlier ones. */\nexport function mergeSkills(...skillSources: SkillDefinitionMap[]): SkillDefinitionMap {\n const merged: SkillDefinitionMap = {};\n\n for (const source of skillSources) {\n for (const [id, skill] of typedEntries<SkillId, SkillDefinition | undefined>(source)) {\n if (skill) {\n merged[id] = skill;\n }\n }\n }\n\n return merged;\n}\n\n/**\n * Discovers all installed skills for a project directory using 4-way merge:\n * 1. Global plugins (from ~/.claude/plugins/)\n * 2. Global local (from ~/.claude/skills/)\n * 3. Project plugins (from <projectDir>/.claude/plugins/)\n * 4. Project local (from <projectDir>/.claude/skills/)\n *\n * Pure function — no user-facing logging. Callers add their own log messages.\n * Uses verbose() for diagnostic output only.\n */\nexport async function discoverInstalledSkills(projectDir: string): Promise<DiscoveredSkills> {\n const isGlobalProject = isHomeDirectory(projectDir);\n\n // 1. Global plugins\n const globalPluginSkills = isGlobalProject\n ? {}\n : await discoverAllPluginSkills(globalInstallRoot());\n const globalPluginSkillCount = typedKeys<SkillId>(globalPluginSkills).length;\n if (globalPluginSkillCount > 0) {\n verbose(` Found ${globalPluginSkillCount} skills from global plugins`);\n }\n\n // 2. Global local skills\n const globalLocal = isGlobalProject\n ? NO_LOCAL_SKILLS\n : await discoverLocalProjectSkills(globalInstallRoot());\n const globalLocalSkillCount = typedKeys<SkillId>(globalLocal.skills).length;\n if (globalLocalSkillCount > 0) {\n verbose(` Found ${globalLocalSkillCount} global local skills from ~/.claude/skills/`);\n }\n\n // 3. Project plugins\n const pluginSkills = await discoverAllPluginSkills(projectDir);\n const pluginSkillCount = typedKeys<SkillId>(pluginSkills).length;\n verbose(` Found ${pluginSkillCount} skills from installed plugins`);\n\n // 4. Project local skills\n const local = await discoverLocalProjectSkills(projectDir);\n const localSkillCount = typedKeys<SkillId>(local.skills).length;\n verbose(` Found ${localSkillCount} local skills from .claude/skills/`);\n\n // Merge: global first, project second — project wins on conflict\n const allSkills = mergeSkills(globalPluginSkills, globalLocal.skills, pluginSkills, local.skills);\n const totalSkillCount = typedKeys<SkillId>(allSkills).length;\n\n return {\n allSkills,\n totalSkillCount,\n pluginSkillCount: globalPluginSkillCount + pluginSkillCount,\n localSkillCount: globalLocalSkillCount + localSkillCount,\n globalPluginSkillCount,\n globalLocalSkillCount,\n unusableMetadata: [...globalLocal.unusableMetadata, ...local.unusableMetadata],\n };\n}\n","import { resolveInstallPaths } from \"../../installation/index.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../../skills/index.js\";\nimport { ensureDir } from \"../../../utils/fs.js\";\nimport type { SkillConfig } from \"../../../types/config.js\";\nimport type { SourceLoadResult } from \"../../loading/source-loader.js\";\n\nexport type SkillCopyResult = {\n projectCopied: CopiedSkill[];\n globalCopied: CopiedSkill[];\n totalCopied: number;\n};\n\n/** Copies one scope's local skills into its skills directory. */\nasync function copyScopedLocalSkills(\n scopeSkills: SkillConfig[],\n skillsDir: string,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill[]> {\n if (scopeSkills.length === 0) return [];\n\n await ensureDir(skillsDir);\n\n return copySkillsToLocalFlattened(\n scopeSkills.map((s) => s.id),\n skillsDir,\n sourceResult,\n );\n}\n\n/**\n * Copies local-source skills to their scope-appropriate directories.\n *\n * Splits skills by scope (project vs global), resolves install paths,\n * ensures directories exist, and copies from source.\n */\nexport async function copyLocalSkills(\n skills: SkillConfig[],\n projectDir: string,\n sourceResult: SourceLoadResult,\n): Promise<SkillCopyResult> {\n const projectLocalSkills = skills.filter((s) => s.scope !== \"global\");\n const globalLocalSkills = skills.filter((s) => s.scope === \"global\");\n\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n const globalPaths = resolveInstallPaths(projectDir, \"global\");\n\n const projectCopied = await copyScopedLocalSkills(\n projectLocalSkills,\n projectPaths.skillsDir,\n sourceResult,\n );\n const globalCopied = await copyScopedLocalSkills(\n globalLocalSkills,\n globalPaths.skillsDir,\n sourceResult,\n );\n\n return {\n projectCopied,\n globalCopied,\n totalCopied: projectCopied.length + globalCopied.length,\n };\n}\n","import { claudePluginUninstall } from \"../../../utils/exec.js\";\nimport { buildMarketplacePluginRef, toClaudePluginScope } from \"../../plugins/index.js\";\nimport { getErrorMessage } from \"../../../utils/errors.js\";\nimport type { SkillId } from \"../../../types/index.js\";\nimport type { SkillConfig } from \"../../../types/config.js\";\n\nexport type PluginUninstallResult = {\n uninstalled: SkillId[];\n failed: Array<{ id: SkillId; error: string }>;\n};\n\n/**\n * Uninstalls skill plugins via the Claude CLI, using scope from old config.\n *\n * Each plugin reference is qualified as `{skillId}@{marketplace}` to match\n * the form used at install time — bare skill IDs will not match the registry.\n */\nexport async function uninstallPluginSkills(\n skillIds: SkillId[],\n oldSkills: SkillConfig[],\n marketplace: string,\n projectDir: string,\n): Promise<PluginUninstallResult> {\n const uninstalled: SkillId[] = [];\n const failed: PluginUninstallResult[\"failed\"] = [];\n\n for (const skillId of skillIds) {\n const oldSkill = oldSkills.find((s) => s.id === skillId);\n const pluginScope = toClaudePluginScope(oldSkill?.scope);\n const pluginRef = buildMarketplacePluginRef(skillId, marketplace);\n try {\n await claudePluginUninstall(pluginRef, pluginScope, projectDir);\n uninstalled.push(skillId);\n } catch (error) {\n failed.push({ id: skillId, error: getErrorMessage(error) });\n }\n }\n\n return { uninstalled, failed };\n}\n","import { compileAgents, type CompilationResult } from \"./compile-agents.js\";\nimport { loadAgentDefs } from \"./load-agent-defs.js\";\nimport { discoverInstalledSkills } from \"../skills/index.js\";\nimport { resolveInstallPaths } from \"../../installation/index.js\";\nimport { getErrorMessage } from \"../../../utils/errors.js\";\n\n/**\n * Recompiles the PROJECT-scoped agents of a registered project after a global\n * config change was propagated into that project's `config.ts`.\n *\n * Propagation (`propagateGlobalChangesToProjects`) rewrites a registered\n * project's `config.ts` / `config-types.ts` but never touches its compiled\n * `.claude/agents/*.md`, so the compiled agents keep emitting whatever skill\n * reference form the OLD global data dictated. Run this per propagated project,\n * after propagation, to bring the compiled artifacts back in step.\n *\n * Scope: project only. The global agents were already recompiled by the\n * triggering operation's own pass; repeating a global pass per project would\n * rewrite `~/.claude/agents` once per registered project for no gain.\n *\n * `skills` is passed explicitly: without it `recompileAgents` falls back to\n * `discoverAllPluginSkills`, which sees plugin skills only and would silently\n * strip every global-local and project-local skill from the compiled agents.\n *\n * Agent partials always come from the CLI itself (`getLocalAgentDefinitions`\n * returns `sourcePath: PROJECT_ROOT`), so no per-project marketplace source\n * resolution is needed.\n */\nexport async function recompileRegisteredProjectAgents(\n projectDir: string,\n): Promise<CompilationResult> {\n const { allSkills } = await discoverInstalledSkills(projectDir);\n const { sourcePath } = await loadAgentDefs();\n\n return compileAgents({\n projectDir,\n sourcePath,\n skills: allSkills,\n scopeFilter: \"project\",\n outputDir: resolveInstallPaths(projectDir, \"project\").agentsDir,\n });\n}\n\nexport type PropagatedRecompileSummary = {\n /** Projects where at least one compiled agent's content actually moved. */\n rewrittenCount: number;\n /**\n * Projects the fan-out reached whose agents all came back byte-identical. They\n * were visited and left alone, which is a different fact from being recompiled\n * and the one the old single count could not tell apart.\n */\n unchangedCount: number;\n failedCount: number;\n /** Per-project warnings in processing order — the caller surfaces them via warn(). */\n warnings: string[];\n};\n\n/**\n * Runs {@link recompileRegisteredProjectAgents} over every propagated project,\n * isolating per-project failures: one project's unreadable config or broken\n * template must not abort the loop or leave the remaining projects stale.\n * Projects are processed sequentially so the collected warnings keep a\n * deterministic per-project order.\n */\nexport async function recompilePropagatedProjectAgents(\n projectDirs: string[],\n): Promise<PropagatedRecompileSummary> {\n let rewrittenCount = 0;\n let unchangedCount = 0;\n let failedCount = 0;\n const warnings: string[] = [];\n\n for (const dir of projectDirs) {\n try {\n const result = await recompileRegisteredProjectAgents(dir);\n if (result.failed.length > 0) {\n failedCount++;\n warnings.push(...result.warnings);\n continue;\n }\n if (result.rewritten.length > 0) rewrittenCount++;\n else unchangedCount++;\n } catch (error) {\n failedCount++;\n warnings.push(`Could not recompile agents in ${dir}: ${getErrorMessage(error)}`);\n }\n }\n\n return { rewrittenCount, unchangedCount, failedCount, warnings };\n}\n"],"mappings":"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","names":["path","path"]}
|