agents-inc 0.164.0 → 0.166.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +8 -9
  3. package/dist/{chunk-X4SSJZLY.js → chunk-25MPBIK3.js} +12 -261
  4. package/dist/chunk-25MPBIK3.js.map +1 -0
  5. package/dist/{chunk-LT5GXEB2.js → chunk-2VUYFTUB.js} +8 -7
  6. package/dist/chunk-2VUYFTUB.js.map +1 -0
  7. package/dist/chunk-4AAOOAIN.js +49 -0
  8. package/dist/chunk-4AAOOAIN.js.map +1 -0
  9. package/dist/{chunk-ARYNOWKF.js → chunk-4NDBUJHK.js} +8 -8
  10. package/dist/{chunk-S63LXWMC.js → chunk-6L75SQZU.js} +2 -2
  11. package/dist/{chunk-7REKOTKG.js → chunk-6LF4CQBY.js} +3 -3
  12. package/dist/{chunk-K5ITEA3I.js → chunk-7JNJ52CD.js} +34 -17
  13. package/dist/chunk-7JNJ52CD.js.map +1 -0
  14. package/dist/{chunk-XPDVAJDH.js → chunk-A4KDXNOT.js} +3519 -1568
  15. package/dist/chunk-A4KDXNOT.js.map +1 -0
  16. package/dist/{chunk-XHPWTL4I.js → chunk-DAIEQJIF.js} +3 -3
  17. package/dist/{chunk-UITEKY2R.js → chunk-ENGYJCTF.js} +28 -4
  18. package/dist/chunk-ENGYJCTF.js.map +1 -0
  19. package/dist/{chunk-G2JJ5BO5.js → chunk-G4JK7WVO.js} +336 -140
  20. package/dist/chunk-G4JK7WVO.js.map +1 -0
  21. package/dist/{chunk-X37UYIE3.js → chunk-G6UREQ4V.js} +436 -739
  22. package/dist/chunk-G6UREQ4V.js.map +1 -0
  23. package/dist/chunk-GE3WKJ6Q.js +375 -0
  24. package/dist/chunk-GE3WKJ6Q.js.map +1 -0
  25. package/dist/{chunk-RGYDFBCT.js → chunk-HHIYT3PI.js} +5 -5
  26. package/dist/{chunk-2CQNPLVF.js → chunk-HWEKHVLE.js} +63 -42
  27. package/dist/chunk-HWEKHVLE.js.map +1 -0
  28. package/dist/{chunk-XVAQG2CV.js → chunk-JOEA52NR.js} +10 -8
  29. package/dist/chunk-JOEA52NR.js.map +1 -0
  30. package/dist/{chunk-3WVH2CTK.js → chunk-JQRJQ4SS.js} +15 -8
  31. package/dist/chunk-JQRJQ4SS.js.map +1 -0
  32. package/dist/{chunk-DSL66I4N.js → chunk-LFWLEDUG.js} +6 -6
  33. package/dist/{chunk-B3Y3QMWI.js → chunk-MAWNVT2C.js} +4 -4
  34. package/dist/{chunk-Q4IRRVXK.js → chunk-MPTNC32T.js} +3 -3
  35. package/dist/chunk-NBXXFIIW.js +73 -0
  36. package/dist/chunk-NBXXFIIW.js.map +1 -0
  37. package/dist/{chunk-B6FSLXYN.js → chunk-PMJWD27C.js} +3 -3
  38. package/dist/{chunk-XATLUKXK.js → chunk-PNB3524H.js} +6 -6
  39. package/dist/chunk-PXWG7KFO.js +39 -0
  40. package/dist/chunk-PXWG7KFO.js.map +1 -0
  41. package/dist/{chunk-4VL3CEOS.js → chunk-QHDPLLK6.js} +3 -3
  42. package/dist/{chunk-AOTCIUGX.js → chunk-RAHSOJQ2.js} +2 -2
  43. package/dist/{chunk-PHCPUQVR.js → chunk-RZDXDMT6.js} +2 -2
  44. package/dist/{chunk-6MV4JOCL.js → chunk-SAYZWCH6.js} +2 -2
  45. package/dist/{chunk-URXIQE7I.js → chunk-SCOQ34YM.js} +2 -2
  46. package/dist/{chunk-NQXO4LR3.js → chunk-SXVHSOTH.js} +16 -11
  47. package/dist/chunk-SXVHSOTH.js.map +1 -0
  48. package/dist/{chunk-QZX7SYKU.js → chunk-T6UWJAB3.js} +2 -2
  49. package/dist/{chunk-ZVXGW2IC.js → chunk-TODCQFRB.js} +4 -6
  50. package/dist/chunk-TODCQFRB.js.map +1 -0
  51. package/dist/{chunk-YRS3QZP2.js → chunk-TTY6DPJN.js} +3 -3
  52. package/dist/{chunk-QGUP3QJF.js → chunk-TZ2YJJKK.js} +22 -18
  53. package/dist/{chunk-QGUP3QJF.js.map → chunk-TZ2YJJKK.js.map} +1 -1
  54. package/dist/chunk-V3I7VQ7N.js +356 -0
  55. package/dist/chunk-V3I7VQ7N.js.map +1 -0
  56. package/dist/{chunk-AVK2HEKB.js → chunk-V5WXIM2F.js} +2 -6
  57. package/dist/{chunk-AVK2HEKB.js.map → chunk-V5WXIM2F.js.map} +1 -1
  58. package/dist/{chunk-NKGYKOB7.js → chunk-VAPTVR3J.js} +7 -8
  59. package/dist/chunk-VAPTVR3J.js.map +1 -0
  60. package/dist/chunk-VRXX4D6K.js +31 -0
  61. package/dist/chunk-VRXX4D6K.js.map +1 -0
  62. package/dist/{chunk-ABAZMMG4.js → chunk-WVUDLKIO.js} +2 -2
  63. package/dist/{chunk-ECURHW3T.js → chunk-WWIFNPJG.js} +13 -12
  64. package/dist/chunk-WWIFNPJG.js.map +1 -0
  65. package/dist/{chunk-J27W6TXS.js → chunk-XQHZPINL.js} +8 -4
  66. package/dist/chunk-XQHZPINL.js.map +1 -0
  67. package/dist/{chunk-V5GLL2JB.js → chunk-XZEVWPX6.js} +7 -7
  68. package/dist/chunk-Y3VIRVVE.js +932 -0
  69. package/dist/chunk-Y3VIRVVE.js.map +1 -0
  70. package/dist/{chunk-NTF4UXGK.js → chunk-Y47EV74W.js} +73 -30
  71. package/dist/chunk-Y47EV74W.js.map +1 -0
  72. package/dist/chunk-ZR4YPKXQ.js +159 -0
  73. package/dist/chunk-ZR4YPKXQ.js.map +1 -0
  74. package/dist/chunk-ZXKBERQU.js +250 -0
  75. package/dist/chunk-ZXKBERQU.js.map +1 -0
  76. package/dist/commands/build/marketplace.js +17 -17
  77. package/dist/commands/build/marketplace.js.map +1 -1
  78. package/dist/commands/build/plugins.js +11 -9
  79. package/dist/commands/build/plugins.js.map +1 -1
  80. package/dist/commands/compile.js +105 -27
  81. package/dist/commands/compile.js.map +1 -1
  82. package/dist/commands/doctor.js +309 -171
  83. package/dist/commands/doctor.js.map +1 -1
  84. package/dist/commands/edit.js +503 -314
  85. package/dist/commands/edit.js.map +1 -1
  86. package/dist/commands/eject.js +40 -23
  87. package/dist/commands/eject.js.map +1 -1
  88. package/dist/commands/init.js +44 -40
  89. package/dist/commands/list.js +44 -10
  90. package/dist/commands/list.js.map +1 -1
  91. package/dist/commands/new/marketplace.js +13 -10
  92. package/dist/commands/new/marketplace.js.map +1 -1
  93. package/dist/commands/search.js +12 -10
  94. package/dist/commands/search.js.map +1 -1
  95. package/dist/commands/share.js +102 -15
  96. package/dist/commands/share.js.map +1 -1
  97. package/dist/commands/uninstall.js +231 -103
  98. package/dist/commands/uninstall.js.map +1 -1
  99. package/dist/commands/update.js +49 -20
  100. package/dist/commands/update.js.map +1 -1
  101. package/dist/components/common/prompt-confirm.js +1 -1
  102. package/dist/components/common/removal-plan-confirm.js +2 -2
  103. package/dist/components/common/select-list.js +3 -3
  104. package/dist/components/common/spinner.js +6 -3
  105. package/dist/components/wizard/category-grid.js +5 -5
  106. package/dist/components/wizard/checkbox-grid.js +4 -4
  107. package/dist/components/wizard/domain-selection.js +9 -9
  108. package/dist/components/wizard/run-wizard-session.js +29 -29
  109. package/dist/components/wizard/scroll-affordance.js +2 -2
  110. package/dist/components/wizard/skill-agent-summary.js +5 -5
  111. package/dist/components/wizard/source-grid.js +6 -6
  112. package/dist/components/wizard/stack-selection.js +8 -8
  113. package/dist/components/wizard/step-agents.js +8 -8
  114. package/dist/components/wizard/step-build.js +8 -8
  115. package/dist/components/wizard/step-confirm.js +9 -9
  116. package/dist/components/wizard/step-sources.js +9 -9
  117. package/dist/components/wizard/step-stack.js +9 -9
  118. package/dist/components/wizard/summary-panel.js +8 -8
  119. package/dist/components/wizard/toast.js +2 -2
  120. package/dist/components/wizard/wizard-layout.js +12 -12
  121. package/dist/components/wizard/wizard-tabs.js +2 -2
  122. package/dist/components/wizard/wizard.js +27 -27
  123. package/dist/hooks/init.js +69 -43
  124. package/dist/hooks/init.js.map +1 -1
  125. package/dist/load-agent-defs-3C27ENC7.js +14 -0
  126. package/dist/recompile-project-agents-DGNBCU3N.js +18 -0
  127. package/dist/{source-loader-GRBVNRAW.js → source-loader-7KZ3MD5O.js} +6 -4
  128. package/dist/src/agents/_templates/agent-body.liquid +55 -0
  129. package/dist/src/agents/_templates/agent.liquid +1 -55
  130. package/dist/src/agents/meta/agent-summoner/output.md +1 -1
  131. package/dist/src/agents/meta/agent-summoner/playbook.md +15 -7
  132. package/dist/stores/wizard-store.js +4 -4
  133. package/package.json +10 -9
  134. package/src/agents/_templates/agent-body.liquid +55 -0
  135. package/src/agents/_templates/agent.liquid +1 -55
  136. package/src/agents/meta/agent-summoner/output.md +1 -1
  137. package/src/agents/meta/agent-summoner/playbook.md +15 -7
  138. package/src/schemas/project-config.schema.json +1 -1
  139. package/src/schemas/project-source-config.schema.json +1 -1
  140. package/dist/chunk-2CQNPLVF.js.map +0 -1
  141. package/dist/chunk-3WVH2CTK.js.map +0 -1
  142. package/dist/chunk-7ANJQLPJ.js +0 -35
  143. package/dist/chunk-7ANJQLPJ.js.map +0 -1
  144. package/dist/chunk-ECURHW3T.js.map +0 -1
  145. package/dist/chunk-FLW25ORT.js +0 -130
  146. package/dist/chunk-FLW25ORT.js.map +0 -1
  147. package/dist/chunk-G2JJ5BO5.js.map +0 -1
  148. package/dist/chunk-J27W6TXS.js.map +0 -1
  149. package/dist/chunk-JCPANDNR.js +0 -35
  150. package/dist/chunk-JCPANDNR.js.map +0 -1
  151. package/dist/chunk-JIERYE6B.js +0 -480
  152. package/dist/chunk-JIERYE6B.js.map +0 -1
  153. package/dist/chunk-JU4ZGJ7A.js +0 -668
  154. package/dist/chunk-JU4ZGJ7A.js.map +0 -1
  155. package/dist/chunk-K5ITEA3I.js.map +0 -1
  156. package/dist/chunk-LT5GXEB2.js.map +0 -1
  157. package/dist/chunk-NKGYKOB7.js.map +0 -1
  158. package/dist/chunk-NQXO4LR3.js.map +0 -1
  159. package/dist/chunk-NTF4UXGK.js.map +0 -1
  160. package/dist/chunk-UITEKY2R.js.map +0 -1
  161. package/dist/chunk-X37UYIE3.js.map +0 -1
  162. package/dist/chunk-X4SSJZLY.js.map +0 -1
  163. package/dist/chunk-XPDVAJDH.js.map +0 -1
  164. package/dist/chunk-XVAQG2CV.js.map +0 -1
  165. package/dist/chunk-ZBPEFQ4G.js +0 -12
  166. package/dist/chunk-ZBPEFQ4G.js.map +0 -1
  167. package/dist/chunk-ZVXGW2IC.js.map +0 -1
  168. package/dist/load-agent-defs-7IM3GBEQ.js +0 -13
  169. package/dist/recompile-project-agents-VR4NLGOU.js +0 -17
  170. /package/dist/{chunk-ARYNOWKF.js.map → chunk-4NDBUJHK.js.map} +0 -0
  171. /package/dist/{chunk-S63LXWMC.js.map → chunk-6L75SQZU.js.map} +0 -0
  172. /package/dist/{chunk-7REKOTKG.js.map → chunk-6LF4CQBY.js.map} +0 -0
  173. /package/dist/{chunk-XHPWTL4I.js.map → chunk-DAIEQJIF.js.map} +0 -0
  174. /package/dist/{chunk-RGYDFBCT.js.map → chunk-HHIYT3PI.js.map} +0 -0
  175. /package/dist/{chunk-DSL66I4N.js.map → chunk-LFWLEDUG.js.map} +0 -0
  176. /package/dist/{chunk-B3Y3QMWI.js.map → chunk-MAWNVT2C.js.map} +0 -0
  177. /package/dist/{chunk-Q4IRRVXK.js.map → chunk-MPTNC32T.js.map} +0 -0
  178. /package/dist/{chunk-B6FSLXYN.js.map → chunk-PMJWD27C.js.map} +0 -0
  179. /package/dist/{chunk-XATLUKXK.js.map → chunk-PNB3524H.js.map} +0 -0
  180. /package/dist/{chunk-4VL3CEOS.js.map → chunk-QHDPLLK6.js.map} +0 -0
  181. /package/dist/{chunk-AOTCIUGX.js.map → chunk-RAHSOJQ2.js.map} +0 -0
  182. /package/dist/{chunk-PHCPUQVR.js.map → chunk-RZDXDMT6.js.map} +0 -0
  183. /package/dist/{chunk-6MV4JOCL.js.map → chunk-SAYZWCH6.js.map} +0 -0
  184. /package/dist/{chunk-URXIQE7I.js.map → chunk-SCOQ34YM.js.map} +0 -0
  185. /package/dist/{chunk-QZX7SYKU.js.map → chunk-T6UWJAB3.js.map} +0 -0
  186. /package/dist/{chunk-YRS3QZP2.js.map → chunk-TTY6DPJN.js.map} +0 -0
  187. /package/dist/{chunk-ABAZMMG4.js.map → chunk-WVUDLKIO.js.map} +0 -0
  188. /package/dist/{chunk-V5GLL2JB.js.map → chunk-XZEVWPX6.js.map} +0 -0
  189. /package/dist/{load-agent-defs-7IM3GBEQ.js.map → load-agent-defs-3C27ENC7.js.map} +0 -0
  190. /package/dist/{recompile-project-agents-VR4NLGOU.js.map → recompile-project-agents-DGNBCU3N.js.map} +0 -0
  191. /package/dist/{source-loader-GRBVNRAW.js.map → source-loader-7KZ3MD5O.js.map} +0 -0
@@ -2,18 +2,16 @@
2
2
  import {
3
3
  compileAgents,
4
4
  withCatalogueSeatedFor
5
- } from "./chunk-2CQNPLVF.js";
5
+ } from "./chunk-HWEKHVLE.js";
6
6
  import {
7
7
  loadAgentDefs
8
- } from "./chunk-B6FSLXYN.js";
8
+ } from "./chunk-PMJWD27C.js";
9
9
  import {
10
10
  ConfigLoadError,
11
11
  GlobalPairWriteViolation,
12
- INDENT_STEP,
13
12
  assertGateToken,
14
13
  buildAndMergeConfig,
15
14
  buildConfigTypesBackgroundData,
16
- commentEntry,
17
15
  deriveCategories,
18
16
  deriveDomains,
19
17
  detectGlobalInstallation,
@@ -24,50 +22,48 @@ import {
24
22
  enableBuffering,
25
23
  ensureDir,
26
24
  fileExists,
25
+ generateBlankGlobalConfigSource,
27
26
  generateBlankGlobalConfigTypesSource,
27
+ generateConfigSource,
28
28
  generateConfigTypesSource,
29
29
  getErrorMessage,
30
+ getInstalledConfigPath,
30
31
  getProjectConfigPath,
31
32
  isHomeDirectory,
32
- isKeyedRecord,
33
+ loadInstalledConfig,
33
34
  loadProjectConfig,
34
35
  loadProjectConfigFromDir,
35
36
  loadSkillsMatrixFromSource,
36
37
  mergeConfigs,
37
38
  normalizeStackRecord,
38
- quoteText,
39
+ providerInUse,
39
40
  readFile,
40
41
  regenerateConfigTypes,
41
- renderArrayLine,
42
- renderKey,
43
- renderTypeImportLine,
44
- renderValueLine,
45
42
  resolveInstallPaths,
46
- sourceEntry,
43
+ sourceFolderInUse,
47
44
  splitConfigByScope,
48
- valueEntries,
45
+ typedEntries as typedEntries2,
49
46
  verbose,
47
+ warn,
50
48
  withGateToken,
51
49
  writeFile
52
- } from "./chunk-XPDVAJDH.js";
50
+ } from "./chunk-A4KDXNOT.js";
53
51
  import {
54
52
  matrix,
55
53
  typedEntries,
56
54
  typedKeys
57
- } from "./chunk-AVK2HEKB.js";
55
+ } from "./chunk-V5WXIM2F.js";
58
56
  import {
59
- CLAUDE_SRC_DIR,
60
57
  CLI_INVOKE_COMMAND,
61
- DEFAULT_PLUGIN_NAME,
62
58
  GLOBAL_CONFIG_NAME,
63
59
  LOCAL_PSEUDO_CATEGORY,
60
+ PROVIDERS,
64
61
  STANDARD_FILES,
65
62
  activeProjectAgentNames,
66
- byCategoryDeclarationOrder,
67
63
  isActiveAt,
68
- isExclusiveCategory,
69
- isGlobalTombstone
70
- } from "./chunk-UITEKY2R.js";
64
+ isGlobalTombstone,
65
+ skillDomain
66
+ } from "./chunk-ENGYJCTF.js";
71
67
 
72
68
  // src/cli/lib/operations/source/load-source.ts
73
69
  async function loadSource(options) {
@@ -95,6 +91,11 @@ async function loadSource(options) {
95
91
  }
96
92
  return { sourceResult, startupMessages };
97
93
  }
94
+ function sayCapturedWarnings(messages) {
95
+ for (const { level, text } of messages) {
96
+ if (level === "warn") warn(text);
97
+ }
98
+ }
98
99
 
99
100
  // src/cli/lib/operations/project/detect-project.ts
100
101
  async function detectProject(projectDir) {
@@ -124,459 +125,189 @@ async function detectBothInstallations(projectDir) {
124
125
  return { global, project, hasBoth: !!global && !!project };
125
126
  }
126
127
 
127
- // src/cli/lib/config-gate/propagate.ts
128
- import fs from "fs";
129
- import { isDeepEqual, unique } from "remeda";
128
+ // src/cli/lib/config-gate/index.ts
129
+ import os2 from "os";
130
+ import path2 from "path";
130
131
 
131
- // ../compile/src/config-source.ts
132
- var EXTRACTED_FIELDS = /* @__PURE__ */ new Set([
133
- "skills",
134
- "agents",
135
- "stack",
136
- "selectedDomains"
137
- ]);
138
- var CANONICAL_FIELD_ORDER = [
139
- "name",
140
- "description",
141
- "agents",
142
- "skills",
143
- "author",
144
- "selectedDomains",
145
- "stack",
146
- "marketplace",
147
- "marketplaceName",
148
- "agentsSource",
149
- "projects"
150
- ];
151
- var CANONICAL_SKILL_ENTRY_ORDER = [
152
- "id",
153
- "scope",
154
- "origin",
155
- "excluded"
156
- ];
157
- var CANONICAL_AGENT_ENTRY_ORDER = [
158
- "name",
159
- "scope",
160
- "model",
161
- "effort",
162
- "excluded"
163
- ];
164
- var CANONICAL_ASSIGNMENT_ORDER = [
165
- "id",
166
- "preloaded",
167
- "local",
168
- "path"
169
- ];
170
- function withKeysInSchemaOrder(record, schemaOrder) {
171
- const named = new Set(schemaOrder);
172
- const inSchemaOrder = schemaOrder.filter((key) => key in record).map((key) => [key, record[key]]);
173
- const passthrough = Object.entries(record).filter(([key]) => !named.has(key));
174
- return Object.fromEntries([...inSchemaOrder, ...passthrough]);
175
- }
176
- function canonicalizeFieldOrder(cleaned) {
177
- return withKeysInSchemaOrder(cleaned, CANONICAL_FIELD_ORDER);
178
- }
179
- function withEntriesInSchemaOrder(cleaned) {
180
- const reordered = { ...cleaned };
181
- if (Array.isArray(reordered.skills)) {
182
- reordered.skills = entriesInSchemaOrder(
183
- reordered.skills,
184
- CANONICAL_SKILL_ENTRY_ORDER
185
- );
186
- }
187
- if (Array.isArray(reordered.agents)) {
188
- reordered.agents = entriesInSchemaOrder(
189
- reordered.agents,
190
- CANONICAL_AGENT_ENTRY_ORDER
191
- );
192
- }
193
- return reordered;
132
+ // src/cli/lib/config-gate/classify.ts
133
+ import { isDeepEqual } from "remeda";
134
+ var NO_CHANGES = {
135
+ skills: { added: [], removed: [], sourceChanged: [], otherChanged: [] },
136
+ agents: { added: [], removed: [], changed: [] },
137
+ stackChanged: false,
138
+ selectedDomainsChanged: false,
139
+ scalarsChanged: [],
140
+ projectsChanged: false
141
+ };
142
+ var EXTRACTED_FIELDS = /* @__PURE__ */ new Set(["skills", "agents", "stack", "selectedDomains"]);
143
+ var REGISTRATION_FIELD = "projects";
144
+ function normalize(config) {
145
+ return JSON.parse(JSON.stringify(config));
194
146
  }
195
- function entriesInSchemaOrder(entries, schemaOrder) {
196
- return entries.map(
197
- (entry) => isKeyedRecord(entry) ? withKeysInSchemaOrder(entry, schemaOrder) : entry
198
- );
147
+ function field(config, key) {
148
+ return config[key];
199
149
  }
200
- function withKeysOrderedBy(record, compareKeys) {
201
- return Object.fromEntries(
202
- Object.entries(record).sort(([a], [b]) => compareKeys(a, b))
203
- );
150
+ function skillsById(config) {
151
+ const skills = config.skills ?? [];
152
+ return new Map(skills.map((skill) => [skill.id, skill]));
204
153
  }
205
- function compareNamesInCodeUnitOrder(a, b) {
206
- if (a === b) return 0;
207
- return a < b ? -1 : 1;
154
+ function agentsByName(config) {
155
+ const agents = config.agents ?? [];
156
+ return new Map(agents.map((agent) => [agent.name, agent]));
208
157
  }
209
- function canonicalizeStackOrder(stack, catalog) {
210
- const byDeclaration = byCategoryDeclarationOrder(catalog);
211
- const withCategoriesInOrder = Object.entries(stack).map(
212
- ([agent, categories]) => [agent, withKeysOrderedBy(categories, byDeclaration)]
213
- );
214
- return withKeysOrderedBy(
215
- Object.fromEntries(withCategoriesInOrder),
216
- compareNamesInCodeUnitOrder
158
+ function scalarKeys(prev, next) {
159
+ const isScalarKey = (key) => !EXTRACTED_FIELDS.has(key) && key !== REGISTRATION_FIELD;
160
+ const nextKeys = Object.keys(next).filter(isScalarKey);
161
+ const extraPrevKeys = Object.keys(prev).filter(
162
+ (key) => isScalarKey(key) && !nextKeys.includes(key)
217
163
  );
164
+ return [...nextKeys, ...extraPrevKeys];
218
165
  }
219
- var CONFIG_TYPES_SPECIFIER = "./config-types";
220
- var STACK_TYPE = "Partial<Record<ProjectAgentName, StackAgentConfig>>";
221
- function declarationPosition(name, type) {
222
- return { indent: 0, prefix: `const ${name}: ${type} = `, suffix: "" };
223
- }
224
- function declaration(name, type, value) {
225
- return ["", renderValueLine(value, declarationPosition(name, type))];
226
- }
227
- function entryDeclaration(name, type, entries) {
228
- return ["", renderArrayLine(entries, declarationPosition(name, type))];
166
+ function diffSkills(prev, next) {
167
+ const before = skillsById(prev);
168
+ const after = skillsById(next);
169
+ const added = [...after.keys()].filter((id) => !before.has(id));
170
+ const removed = [...before.keys()].filter((id) => !after.has(id));
171
+ const sourceChanged = [];
172
+ const otherChanged = [];
173
+ for (const [id, afterEntry] of after) {
174
+ const beforeEntry = before.get(id);
175
+ if (!beforeEntry || isDeepEqual(beforeEntry, afterEntry)) continue;
176
+ if (beforeEntry.origin !== afterEntry.origin) sourceChanged.push(id);
177
+ else otherChanged.push(id);
178
+ }
179
+ return { added, removed, sourceChanged, otherChanged };
229
180
  }
230
- function exportFieldPosition(key) {
181
+ function diffAgents(prev, next) {
182
+ const before = agentsByName(prev);
183
+ const after = agentsByName(next);
231
184
  return {
232
- indent: INDENT_STEP,
233
- prefix: `${renderKey(key)}: `,
234
- suffix: ","
185
+ added: [...after.keys()].filter((name) => !before.has(name)),
186
+ removed: [...before.keys()].filter((name) => !after.has(name)),
187
+ changed: [...after.keys()].filter((name) => {
188
+ const beforeEntry = before.get(name);
189
+ return beforeEntry !== void 0 && !isDeepEqual(beforeEntry, after.get(name));
190
+ })
235
191
  };
236
192
  }
237
- function renderScalarField(key, value) {
238
- return renderValueLine(value, exportFieldPosition(key));
239
- }
240
- function extractConfigArrays(cleaned) {
193
+ function classifyGlobalChange(prev, next) {
194
+ const before = prev ? normalize(prev) : {};
195
+ const after = normalize(next);
196
+ const moved = (key) => !isDeepEqual(field(before, key), field(after, key));
241
197
  return {
242
- skills: cleaned.skills ?? [],
243
- agents: cleaned.agents ?? [],
244
- stack: cleaned.stack,
245
- selectedDomains: cleaned.selectedDomains ?? []
198
+ skills: diffSkills(before, after),
199
+ agents: diffAgents(before, after),
200
+ stackChanged: moved("stack"),
201
+ selectedDomainsChanged: moved("selectedDomains"),
202
+ scalarsChanged: scalarKeys(before, after).filter(moved),
203
+ projectsChanged: moved(REGISTRATION_FIELD)
246
204
  };
247
205
  }
248
- function cleanForEmission(config, catalog, options) {
249
- const cleaned = JSON.parse(JSON.stringify(config));
250
- if (options.dropProjects) {
251
- delete cleaned.projects;
252
- }
253
- if (cleaned.stack) {
254
- const compacted = compactStackAssignments(
255
- cleaned.stack,
256
- catalog
257
- );
258
- cleaned.stack = canonicalizeStackOrder(compacted, catalog);
259
- }
260
- return canonicalizeFieldOrder(withEntriesInSchemaOrder(cleaned));
206
+ function movesTypesOrCompiledAgents(changes) {
207
+ const { skills, agents } = changes;
208
+ return skills.added.length > 0 || skills.removed.length > 0 || skills.sourceChanged.length > 0 || skills.otherChanged.length > 0 || agents.added.length > 0 || agents.removed.length > 0 || agents.changed.length > 0 || changes.stackChanged || changes.selectedDomainsChanged;
261
209
  }
262
- function generateConfigSource(config, catalog, options) {
263
- if (options?.isProjectConfig) {
264
- return generateProjectConfig(config, catalog, options);
265
- }
266
- return generateStandaloneConfig(
267
- cleanForEmission(config, catalog, { dropProjects: false })
268
- );
210
+ function consequenceTier(changes) {
211
+ if (movesTypesOrCompiledAgents(changes)) return "T1";
212
+ if (changes.scalarsChanged.length > 0) return "T2";
213
+ if (changes.projectsChanged) return "T3";
214
+ return "T4";
269
215
  }
270
- function generateProjectConfig(config, catalog, options) {
271
- const cleaned = cleanForEmission(config, catalog, { dropProjects: true });
272
- if (options.globalConfig) {
273
- return generateProjectConfigWithInlinedGlobal(
274
- cleaned,
275
- cleanForEmission(options.globalConfig, catalog, { dropProjects: true })
276
- );
277
- }
278
- if (options.globalImportPath !== void 0) {
279
- return generateProjectConfigWithGlobalImport(
280
- cleaned,
281
- options.globalImportPath
282
- );
283
- }
284
- throw new Error(
285
- "A project config needs the global config it extends: pass `globalConfig` to inline its entries, or `globalImportPath` to import and spread them. Neither was given, and the standalone writer this used to fall through to emits a global-shaped config carrying the `projects` tracking array a project root must never hold."
286
- );
216
+ function tierNeedsDeps(tier) {
217
+ return tier === "T1" || tier === "T2";
287
218
  }
288
- function generateProjectConfigWithGlobalImport(cleaned, globalImportPath) {
289
- const importPath = `${globalImportPath}/config`;
290
- const { skills, agents, stack, selectedDomains } = extractConfigArrays(cleaned);
291
- const hasProjectDomains = selectedDomains.length > 0;
292
- const hasStack = stack != null && Object.keys(stack).length > 0;
293
- const typeImports = buildTypeImports({
294
- // Always present, spread from global.
295
- hasSkills: true,
296
- hasAgents: true,
297
- hasStack,
298
- hasSelectedDomains: hasProjectDomains
299
- });
300
- const lines = [
301
- `import globalConfig from ${quoteText(importPath)}`,
302
- renderTypeImportLine(typeImports, CONFIG_TYPES_SPECIFIER)
303
- ];
304
- lines.push(
305
- ...entryDeclaration("skills", "SkillConfig[]", [
306
- sourceEntry("...globalConfig.skills"),
307
- ...valueEntries(skills)
308
- ])
309
- );
310
- lines.push(
311
- ...entryDeclaration("agents", "AgentScopeConfig[]", [
312
- sourceEntry("...globalConfig.agents"),
313
- ...valueEntries(agents)
314
- ])
315
- );
316
- if (hasStack) {
317
- lines.push(...declaration("stack", STACK_TYPE, stack));
318
- }
319
- if (hasProjectDomains) {
320
- lines.push(
321
- ...entryDeclaration("selectedDomains", "Domain[]", [
322
- sourceEntry("...(globalConfig.selectedDomains ?? [])"),
323
- ...valueEntries(selectedDomains)
324
- ])
325
- );
326
- }
327
- const scalarFields = Object.entries(cleaned).filter(([key]) => !EXTRACTED_FIELDS.has(key) && key !== "name").map(([key, value]) => renderScalarField(key, value));
328
- const exportFields = [
329
- ` ...globalConfig,`,
330
- renderScalarField("name", resolveProjectName(cleaned)),
331
- ` skills,`,
332
- ` agents,`,
333
- ...hasStack ? [` stack,`] : [],
334
- ...hasProjectDomains ? [` selectedDomains,`] : [],
335
- ...scalarFields
336
- ];
337
- lines.push(``);
338
- lines.push(`export default {`);
339
- lines.push(...exportFields);
340
- lines.push(`} satisfies ProjectConfig`);
341
- lines.push(``);
342
- return lines.join("\n");
343
- }
344
- function generateStandaloneConfig(cleaned) {
345
- const { skills, agents, stack, selectedDomains } = extractConfigArrays(cleaned);
346
- const hasSkills = skills.length > 0;
347
- const hasAgents = agents.length > 0;
348
- const hasStack = stack != null && Object.keys(stack).length > 0;
349
- const hasSelectedDomains = selectedDomains.length > 0;
350
- const typeImports = buildTypeImports({
351
- hasSkills,
352
- hasAgents,
353
- hasStack,
354
- hasSelectedDomains
355
- });
356
- const lines = [
357
- renderTypeImportLine(typeImports, CONFIG_TYPES_SPECIFIER)
358
- ];
359
- if (hasSkills) {
360
- lines.push(...declaration("skills", "SkillConfig[]", skills));
361
- }
362
- if (hasAgents) {
363
- lines.push(...declaration("agents", "AgentScopeConfig[]", agents));
364
- }
365
- if (hasStack) {
366
- lines.push(...declaration("stack", STACK_TYPE, stack));
367
- }
368
- if (hasSelectedDomains) {
369
- lines.push(...declaration("selectedDomains", "Domain[]", selectedDomains));
370
- }
371
- const renderExportField = (key, value) => {
372
- if (!EXTRACTED_FIELDS.has(key)) return [renderScalarField(key, value)];
373
- if (key === "skills") return [` skills${hasSkills ? "" : ": []"},`];
374
- if (key === "agents") return [` agents${hasAgents ? "" : ": []"},`];
375
- if (key === "stack") return hasStack ? [` stack,`] : [];
376
- return [` selectedDomains${hasSelectedDomains ? "" : ": []"},`];
377
- };
378
- const exportFields = Object.entries(cleaned).flatMap(
379
- ([key, value]) => renderExportField(key, value)
380
- );
381
- lines.push(``);
382
- lines.push(`export default {`);
383
- lines.push(...exportFields);
384
- lines.push(`} satisfies ProjectConfig`);
385
- lines.push(``);
386
- return lines.join("\n");
387
- }
388
- function buildTypeImports(flags) {
389
- return [
390
- flags.hasSelectedDomains && "Domain",
391
- "ProjectConfig",
392
- flags.hasStack && "ProjectAgentName",
393
- flags.hasAgents && "AgentScopeConfig",
394
- flags.hasSkills && "SkillConfig",
395
- flags.hasStack && "StackAgentConfig"
396
- ].filter((t) => Boolean(t));
397
- }
398
- function resolveProjectName(cleaned) {
399
- return cleaned.name && cleaned.name !== GLOBAL_CONFIG_NAME ? cleaned.name : DEFAULT_PLUGIN_NAME;
400
- }
401
- function partitionInlinedConfigEntries(cleaned, cleanedGlobal) {
402
- const project = extractConfigArrays(cleaned);
403
- const global = extractConfigArrays(cleanedGlobal);
404
- const isExcluded = (entry) => entry.excluded === true;
405
- const idOf = (entry) => entry.id;
406
- const nameOf = (entry) => entry.name;
407
- const excludedGlobalSkills = project.skills.filter(isExcluded);
408
- const excludedGlobalAgents = project.agents.filter(isExcluded);
409
- const projectSkills = project.skills.filter((s) => !isExcluded(s));
410
- const projectAgents = project.agents.filter((a) => !isExcluded(a));
411
- const excludedSkillIds = new Set(excludedGlobalSkills.map(idOf));
412
- const excludedAgentNames = new Set(excludedGlobalAgents.map(nameOf));
413
- const globalSkills = [
414
- ...global.skills.filter((s) => !excludedSkillIds.has(idOf(s))),
415
- ...excludedGlobalSkills
416
- ];
417
- const globalAgents = [
418
- ...global.agents.filter((a) => !excludedAgentNames.has(nameOf(a))),
419
- ...excludedGlobalAgents
420
- ];
421
- const projectAgentNames = new Set(projectAgents.map(nameOf));
422
- const filteredStack = project.stack ? Object.fromEntries(
423
- Object.entries(project.stack).filter(
424
- ([agent]) => projectAgentNames.has(agent)
425
- )
426
- ) : void 0;
219
+ function tierRegeneratesTypes(tier) {
220
+ return tier === "T1";
221
+ }
222
+ function tierPropagates(tier) {
223
+ return tier === "T1" || tier === "T2";
224
+ }
225
+
226
+ // src/cli/lib/config-gate/deps.ts
227
+ function isLoaded(deps) {
228
+ return "matrix" in deps;
229
+ }
230
+ async function resolveGateDeps(deps, tier) {
231
+ if (!tierNeedsDeps(tier)) return null;
232
+ if (isLoaded(deps)) return deps;
233
+ const [matrix2, agents] = await Promise.all([
234
+ deps.loadMatrix(),
235
+ tierRegeneratesTypes(tier) ? deps.loadAgents() : NO_AGENTS
236
+ ]);
237
+ return { matrix: matrix2, agents };
238
+ }
239
+ var NO_AGENTS = Promise.resolve({});
240
+
241
+ // src/cli/lib/config-gate/pair-writer.ts
242
+ import os from "os";
243
+ import path from "path";
244
+ function globalPairPaths(provider) {
245
+ const dir = sourceFolderInUse(os.homedir(), provider).dir;
427
246
  return {
428
- globalSkills,
429
- globalAgents,
430
- projectSkills,
431
- projectAgents,
432
- filteredStack,
433
- selectedDomains: [
434
- .../* @__PURE__ */ new Set([...global.selectedDomains, ...project.selectedDomains])
435
- ]
247
+ configPath: path.join(dir, STANDARD_FILES.CONFIG_TS),
248
+ typesPath: path.join(dir, STANDARD_FILES.CONFIG_TYPES_TS)
436
249
  };
437
250
  }
438
- function mergeInlinedScalarFields(cleaned, cleanedGlobal) {
439
- return Object.entries(
440
- canonicalizeFieldOrder({ ...cleanedGlobal, ...cleaned })
441
- ).filter(([key]) => !EXTRACTED_FIELDS.has(key) && key !== "name");
442
- }
443
- function generateProjectConfigWithInlinedGlobal(cleaned, cleanedGlobal) {
444
- const partition = partitionInlinedConfigEntries(cleaned, cleanedGlobal);
445
- const {
446
- globalSkills,
447
- globalAgents,
448
- projectSkills,
449
- projectAgents,
450
- filteredStack
451
- } = partition;
452
- const hasGlobalSkills = globalSkills.length > 0;
453
- const hasProjectSkills = projectSkills.length > 0;
454
- const hasSkills = hasGlobalSkills || hasProjectSkills;
455
- const hasGlobalAgents = globalAgents.length > 0;
456
- const hasProjectAgents = projectAgents.length > 0;
457
- const hasAgents = hasGlobalAgents || hasProjectAgents;
458
- const hasStack = filteredStack != null && Object.keys(filteredStack).length > 0;
459
- const hasSelectedDomains = partition.selectedDomains.length > 0;
460
- const typeImports = buildTypeImports({
461
- hasSkills,
462
- hasAgents,
463
- hasStack,
464
- hasSelectedDomains
465
- });
466
- const lines = [
467
- renderTypeImportLine(typeImports, CONFIG_TYPES_SPECIFIER)
468
- ];
469
- if (hasSkills) {
470
- lines.push(
471
- ...entryDeclaration(
472
- "skills",
473
- "SkillConfig[]",
474
- scopeSectionEntries(globalSkills, projectSkills)
475
- )
476
- );
477
- }
478
- if (hasAgents) {
479
- lines.push(
480
- ...entryDeclaration(
481
- "agents",
482
- "AgentScopeConfig[]",
483
- scopeSectionEntries(globalAgents, projectAgents)
484
- )
485
- );
486
- }
487
- if (hasStack) {
488
- lines.push(...declaration("stack", STACK_TYPE, filteredStack));
489
- }
490
- if (hasSelectedDomains) {
491
- lines.push(
492
- ...declaration("selectedDomains", "Domain[]", partition.selectedDomains)
493
- );
494
- }
495
- const scalarFields = mergeInlinedScalarFields(cleaned, cleanedGlobal);
496
- const exportFields = [
497
- renderScalarField("name", resolveProjectName(cleaned)),
498
- ...scalarFields.map(([key, value]) => renderScalarField(key, value)),
499
- hasSkills ? ` skills,` : ` skills: [],`,
500
- hasAgents ? ` agents,` : ` agents: [],`,
501
- ...hasStack ? [` stack,`] : [],
502
- ...hasSelectedDomains ? [` selectedDomains,`] : []
503
- ];
504
- lines.push(``);
505
- lines.push(`export default {`);
506
- lines.push(...exportFields);
507
- lines.push(`} satisfies ProjectConfig`);
508
- lines.push(``);
509
- return lines.join("\n");
510
- }
511
- function scopeSectionEntries(global, project) {
512
- return [
513
- ...global.length > 0 ? [commentEntry("global"), ...valueEntries(global)] : [],
514
- ...project.length > 0 ? [commentEntry("project"), ...valueEntries(project)] : []
515
- ];
251
+ function typesPathFor(configPath) {
252
+ return path.join(path.dirname(configPath), STANDARD_FILES.CONFIG_TYPES_TS);
516
253
  }
517
- function carriesFlags(assignment) {
518
- return Boolean(assignment.preloaded || assignment.local || assignment.path);
254
+ async function writeIfChanged(filePath, source) {
255
+ assertGateToken(filePath);
256
+ if (await fileExists(filePath) && await readFile(filePath) === source) return false;
257
+ await writeFile(filePath, source);
258
+ return true;
519
259
  }
520
- function isSkillAssignment(value) {
521
- if (typeof value !== "object" || value === null) return false;
522
- return typeof value.id === "string";
260
+ function renderStandaloneTypes(config, matrix2, agents, extras) {
261
+ const data = buildConfigTypesBackgroundData(matrix2, agents);
262
+ return generateConfigTypesSource(
263
+ data.matrix,
264
+ data.agentNames,
265
+ data.customAgentNames,
266
+ extras,
267
+ config
268
+ );
523
269
  }
524
- function compactAssignment(assignment) {
525
- if (!isSkillAssignment(assignment)) return assignment;
526
- if (!carriesFlags(assignment)) return assignment.id;
527
- return withKeysInSchemaOrder(assignment, CANONICAL_ASSIGNMENT_ORDER);
270
+ async function writeGlobalConfigHalf(config, configPath) {
271
+ return writeIfChanged(configPath, generateConfigSource(config, matrix));
528
272
  }
529
- function compactCategoryAssignments(category, assignments, catalog) {
530
- const compacted = assignments.map(compactAssignment);
531
- if (!isExclusiveCategory(catalog, category)) return compacted;
532
- if (compacted.length > 1) {
533
- throw new Error(
534
- `Category '${category}' is exclusive but holds ${compacted.length} skills: ${JSON.stringify(compacted)}`
535
- );
536
- }
537
- return compacted[0];
538
- }
539
- function compactCategories(categories, catalog) {
540
- return Object.fromEntries(
541
- Object.entries(categories).filter(
542
- ([, assignments]) => Array.isArray(assignments) && assignments.length > 0
543
- ).map(([category, assignments]) => [
544
- category,
545
- compactCategoryAssignments(category, assignments, catalog)
546
- ])
273
+ async function writeGlobalTypesHalf(config, configPath, matrix2, agents, extras) {
274
+ return writeIfChanged(
275
+ typesPathFor(configPath),
276
+ renderStandaloneTypes(config, matrix2, agents, extras)
547
277
  );
548
278
  }
549
- function compactStackAssignments(stack, catalog) {
550
- return Object.fromEntries(
551
- Object.entries(stack).map(
552
- ([agent, categories]) => [agent, compactCategories(categories, catalog)]
553
- ).filter(([, categories]) => Object.keys(categories).length > 0)
279
+ async function writeGlobalPair(config, configPath, matrix2, agents) {
280
+ const configWritten = await writeIfChanged(configPath, generateConfigSource(config, matrix2));
281
+ const typesWritten = await writeIfChanged(
282
+ typesPathFor(configPath),
283
+ renderStandaloneTypes(config, matrix2, agents)
554
284
  );
285
+ return configWritten || typesWritten;
555
286
  }
556
- function generateBlankGlobalConfigSource() {
557
- return `import type { ProjectConfig } from ${quoteText(CONFIG_TYPES_SPECIFIER)}
558
-
559
- export default {
560
- name: ${quoteText(GLOBAL_CONFIG_NAME)},
561
- skills: [],
562
- agents: [],
563
- selectedDomains: [],
564
- } satisfies ProjectConfig
565
- `;
287
+ async function ensureBlankPair(provider) {
288
+ const { configPath, typesPath } = globalPairPaths(provider);
289
+ if (await fileExists(configPath)) {
290
+ verbose("Global config already exists, skipping blank creation");
291
+ return false;
292
+ }
293
+ await ensureDir(path.dirname(configPath));
294
+ await writeIfChanged(configPath, generateBlankGlobalConfigSource());
295
+ await writeIfChanged(typesPath, generateBlankGlobalConfigTypesSource());
296
+ verbose(`Created blank global config at ${path.dirname(configPath)}`);
297
+ return true;
566
298
  }
567
299
 
568
300
  // src/cli/lib/config-gate/propagate.ts
569
- async function writeConfigFile(config, configPath, options) {
570
- const source = generateConfigSource(config, matrix, options);
571
- await writeFile(configPath, source);
572
- }
301
+ import fs from "fs";
302
+ import { isDeepEqual as isDeepEqual3, unique } from "remeda";
303
+
304
+ // ../compile/src/global-config.ts
305
+ import { isDeepEqual as isDeepEqual2 } from "remeda";
573
306
  function additiveMergeStack(existing, incoming) {
574
307
  const merged = existing ? structuredClone(existing) : {};
575
308
  if (!incoming) return { stack: merged, changed: false };
576
309
  let changed = false;
577
- for (const [agentName, incomingAgentStack] of typedEntries(
578
- incoming
579
- )) {
310
+ for (const [agentName, incomingAgentStack] of typedEntries2(incoming)) {
580
311
  if (!incomingAgentStack) continue;
581
312
  const existingAgentStack = merged[agentName];
582
313
  if (!existingAgentStack) {
@@ -592,9 +323,7 @@ function additiveMergeStack(existing, incoming) {
592
323
  }
593
324
  function mergeAgentCategories(existingAgentStack, incomingAgentStack) {
594
325
  let changed = false;
595
- for (const [category, incomingAssignments] of typedEntries(
596
- incomingAgentStack
597
- )) {
326
+ for (const [category, incomingAssignments] of typedEntries2(incomingAgentStack)) {
598
327
  if (!incomingAssignments) continue;
599
328
  const existingAssignments = existingAgentStack[category];
600
329
  if (!existingAssignments) {
@@ -602,24 +331,34 @@ function mergeAgentCategories(existingAgentStack, incomingAgentStack) {
602
331
  changed = true;
603
332
  continue;
604
333
  }
605
- const existingIds = new Set(existingAssignments.map((a) => a.id));
606
- for (const assignment of incomingAssignments) {
607
- if (!existingIds.has(assignment.id)) {
608
- existingAssignments.push({ ...assignment });
609
- existingIds.add(assignment.id);
610
- changed = true;
611
- }
334
+ if (appendMissingAssignments(existingAssignments, incomingAssignments)) {
335
+ changed = true;
612
336
  }
613
337
  }
614
338
  return changed;
615
339
  }
340
+ function appendMissingAssignments(existingAssignments, incomingAssignments) {
341
+ const existingIds = new Set(existingAssignments.map((a) => a.id));
342
+ let changed = false;
343
+ for (const assignment of incomingAssignments) {
344
+ if (existingIds.has(assignment.id)) continue;
345
+ existingAssignments.push({ ...assignment });
346
+ existingIds.add(assignment.id);
347
+ changed = true;
348
+ }
349
+ return changed;
350
+ }
616
351
  function mergeGlobalConfigs(existing, incoming) {
617
352
  const existingSkillIds = new Set(existing.skills.map((s) => s.id));
618
353
  const existingAgentNames = new Set(existing.agents.map((a) => a.name));
619
354
  const incomingActiveSkills = incoming.skills.filter((s) => !s.excluded);
620
355
  const incomingActiveAgents = incoming.agents.filter((a) => !a.excluded);
621
- const newSkills = incomingActiveSkills.filter((s) => !existingSkillIds.has(s.id));
622
- const newAgents = incomingActiveAgents.filter((a) => !existingAgentNames.has(a.name));
356
+ const newSkills = incomingActiveSkills.filter(
357
+ (s) => !existingSkillIds.has(s.id)
358
+ );
359
+ const newAgents = incomingActiveAgents.filter(
360
+ (a) => !existingAgentNames.has(a.name)
361
+ );
623
362
  const mergedSkills = [...existing.skills, ...newSkills];
624
363
  const mergedAgents = [...existing.agents, ...newAgents];
625
364
  const { stack: mergedStack, changed: stackChanged } = additiveMergeStack(
@@ -627,11 +366,13 @@ function mergeGlobalConfigs(existing, incoming) {
627
366
  incoming.stack
628
367
  );
629
368
  const mergedSelectedDomains = [
630
- .../* @__PURE__ */ new Set([...existing.selectedDomains ?? [], ...incoming.selectedDomains ?? []])
369
+ .../* @__PURE__ */ new Set([
370
+ ...existing.selectedDomains ?? [],
371
+ ...incoming.selectedDomains ?? []
372
+ ])
631
373
  ];
632
- const mergedMarketplaceName = existing.marketplaceName ?? incoming.marketplaceName;
633
- const mergedMarketplace = existing.marketplace ?? incoming.marketplace;
634
- const changed = newSkills.length > 0 || newAgents.length > 0 || stackChanged || !isDeepEqual(existing.selectedDomains ?? [], mergedSelectedDomains) || mergedMarketplaceName !== existing.marketplaceName || mergedMarketplace !== existing.marketplace;
374
+ const addsEntries = newSkills.length > 0 || newAgents.length > 0;
375
+ const changed = addsEntries || stackChanged || !isDeepEqual2(existing.selectedDomains ?? [], mergedSelectedDomains);
635
376
  return {
636
377
  config: {
637
378
  ...existing,
@@ -639,12 +380,59 @@ function mergeGlobalConfigs(existing, incoming) {
639
380
  agents: mergedAgents,
640
381
  stack: mergedStack,
641
382
  selectedDomains: mergedSelectedDomains,
642
- ...mergedMarketplaceName !== void 0 && { marketplaceName: mergedMarketplaceName },
643
- ...mergedMarketplace !== void 0 && { marketplace: mergedMarketplace }
383
+ ...marketplaceIdentityFilledFrom(existing, addsEntries ? incoming : null)
644
384
  },
645
385
  changed
646
386
  };
647
387
  }
388
+ function marketplaceIdentityFilledFrom(existing, arriving) {
389
+ const marketplaceName = existing.marketplaceName ?? arriving?.marketplaceName;
390
+ const marketplace = existing.marketplace ?? arriving?.marketplace;
391
+ return {
392
+ ...marketplaceName !== void 0 && { marketplaceName },
393
+ ...marketplace !== void 0 && { marketplace }
394
+ };
395
+ }
396
+ function addSessionToGlobal(globalSplit, existingGlobalConfig, catalog) {
397
+ const hasGlobalItems = globalSplit.skills.length > 0 || globalSplit.agents.length > 0;
398
+ if (!hasGlobalItems) {
399
+ return {
400
+ config: existingGlobalConfig ?? {
401
+ name: GLOBAL_CONFIG_NAME,
402
+ skills: [],
403
+ agents: []
404
+ },
405
+ changed: false
406
+ };
407
+ }
408
+ const arriving = withTheDomainsItAdds(
409
+ globalSplit,
410
+ existingGlobalConfig,
411
+ catalog
412
+ );
413
+ if (!existingGlobalConfig) return { config: arriving, changed: true };
414
+ return mergeGlobalConfigs(existingGlobalConfig, arriving);
415
+ }
416
+ function withTheDomainsItAdds(globalSplit, existingGlobalConfig, catalog) {
417
+ const installed = new Set(
418
+ existingGlobalConfig?.skills.map((skill) => skill.id)
419
+ );
420
+ const arrivingDomains = new Set(
421
+ globalSplit.skills.filter((skill) => !skill.excluded && !installed.has(skill.id)).map((skill) => skillDomain(catalog, skill.id))
422
+ );
423
+ return {
424
+ ...globalSplit,
425
+ selectedDomains: (globalSplit.selectedDomains ?? []).filter(
426
+ (domain) => arrivingDomains.has(domain)
427
+ )
428
+ };
429
+ }
430
+
431
+ // src/cli/lib/config-gate/propagate.ts
432
+ async function writeConfigFile(config, configPath, options) {
433
+ const source = generateConfigSource(config, matrix, options);
434
+ await writeFile(configPath, source);
435
+ }
648
436
  function normalizeProjectPath(projectDir) {
649
437
  return fs.realpathSync(projectDir);
650
438
  }
@@ -654,7 +442,7 @@ async function registerProjectPath(globalConfig, projectDir) {
654
442
  const staleChecks = await Promise.all(
655
443
  existing.map(async (p) => ({
656
444
  path: p,
657
- hasConfig: await fileExists(getProjectConfigPath(p))
445
+ hasConfig: await fileExists(getInstalledConfigPath(p))
658
446
  }))
659
447
  );
660
448
  const valid = staleChecks.filter((c) => c.hasConfig).map((c) => c.path);
@@ -688,7 +476,7 @@ function categoryOfSkill(id, matrix2) {
688
476
  if (category === void 0 || category === LOCAL_PSEUDO_CATEGORY) return void 0;
689
477
  return category;
690
478
  }
691
- function isExclusiveCategory2(category, matrix2) {
479
+ function isExclusiveCategory(category, matrix2) {
692
480
  return matrix2.categories[category]?.exclusive === true;
693
481
  }
694
482
  function activeProjectCategories(projectOwnedSkills, matrix2) {
@@ -702,7 +490,7 @@ function buildProjectCollisionTest(projectOwnedSkills, matrix2) {
702
490
  );
703
491
  const occupiedExclusiveCategories = new Set(
704
492
  [...activeProjectCategories(projectOwnedSkills, matrix2)].filter(
705
- (category) => isExclusiveCategory2(category, matrix2)
493
+ (category) => isExclusiveCategory(category, matrix2)
706
494
  )
707
495
  );
708
496
  return (id) => {
@@ -765,20 +553,25 @@ function retainReconciledStack(stack, removedGlobalSkillIds) {
765
553
  if (!stack || removedGlobalSkillIds.size === 0) return stack;
766
554
  const reconciled = {};
767
555
  for (const [agent, agentStack] of Object.entries(stack)) {
768
- const reconciledAgentStack = {};
769
- for (const [category, assignments] of typedEntries(agentStack)) {
770
- if (!assignments) continue;
771
- const kept = assignments.filter((assignment) => !removedGlobalSkillIds.has(assignment.id));
772
- if (kept.length > 0) reconciledAgentStack[category] = kept;
773
- }
556
+ const reconciledAgentStack = withoutRemovedAssignments(agentStack, removedGlobalSkillIds);
774
557
  if (typedKeys(reconciledAgentStack).length > 0) {
775
558
  reconciled[agent] = reconciledAgentStack;
776
559
  }
777
560
  }
778
561
  return reconciled;
779
562
  }
780
- async function writeProjectConfigPair(projectDir, reconciledSplit, effectiveGlobal, matrix2, agents, options = {}) {
781
- await writeConfigFile(reconciledSplit, getProjectConfigPath(projectDir), {
563
+ function withoutRemovedAssignments(agentStack, removedGlobalSkillIds) {
564
+ const reconciledAgentStack = {};
565
+ for (const [category, assignments] of typedEntries(agentStack)) {
566
+ if (!assignments) continue;
567
+ const kept = assignments.filter((assignment) => !removedGlobalSkillIds.has(assignment.id));
568
+ if (kept.length > 0) reconciledAgentStack[category] = kept;
569
+ }
570
+ return reconciledAgentStack;
571
+ }
572
+ async function writeProjectConfigPair(projectDir, provider, reconciledSplit, effectiveGlobal, matrix2, agents, options = {}) {
573
+ const configPath = refuseAWriteOutsideTheInstallation(projectDir, provider);
574
+ await writeConfigFile(reconciledSplit, configPath, {
782
575
  isProjectConfig: true,
783
576
  globalConfig: effectiveGlobal
784
577
  });
@@ -815,55 +608,103 @@ function reconcileAgainstGlobal(onDisk, globalConfig, matrix2) {
815
608
  matrix2
816
609
  );
817
610
  }
818
- async function propagateToProject(projectPath, globalConfig, agents, options) {
611
+ function refuseAWriteOutsideTheInstallation(projectDir, provider) {
612
+ const installed = providerInUse(projectDir);
613
+ const configPath = getProjectConfigPath(projectDir, provider);
614
+ if (installed !== provider) {
615
+ throw new Error(
616
+ `Refusing to write ${configPath}: ${projectDir} holds the ${installed} installation at ${sourceFolderInUse(projectDir, installed).dir}, not a ${provider} one.`
617
+ );
618
+ }
619
+ return configPath;
620
+ }
621
+ async function propagateToProject(projectPath, provider, globalConfig, agents, options) {
622
+ const existingProject = await loadInstalledConfig(projectPath);
623
+ if (!existingProject?.config) return false;
819
624
  return withCatalogueSeatedFor(projectPath, async (catalogue) => {
820
- const existingProject = await loadProjectConfigFromDir(projectPath);
821
- if (!existingProject?.config) return false;
822
625
  const projectSplit = reconcileAgainstGlobal(existingProject.config, globalConfig, catalogue);
823
- await writeProjectConfigPair(projectPath, projectSplit, globalConfig, catalogue, agents, {
824
- regenerateTypes: options.regenerateTypes ?? true
825
- });
626
+ await writeProjectConfigPair(
627
+ projectPath,
628
+ provider,
629
+ projectSplit,
630
+ globalConfig,
631
+ catalogue,
632
+ agents,
633
+ { regenerateTypes: options.regenerateTypes ?? true }
634
+ );
826
635
  return true;
827
636
  });
828
637
  }
829
- async function propagateGlobalChangesToProjects(globalConfig, agents, currentProjectDir, options = {}) {
638
+ async function propagateGlobalChangesToProjects(globalConfig, agents, provider, currentProjectDir, options = {}) {
830
639
  const projects = globalConfig.projects ?? [];
831
- if (projects.length === 0) return { updated: [], skipped: [] };
640
+ const result = {
641
+ updated: [],
642
+ unreadable: [],
643
+ gone: [],
644
+ notOurs: [],
645
+ failed: []
646
+ };
647
+ if (projects.length === 0) return result;
832
648
  const currentNormalized = currentProjectDir ? normalizeProjectPath(currentProjectDir) : null;
833
- const updated = [];
834
- const skipped = [];
835
649
  for (const projectPath of projects) {
836
650
  if (currentNormalized && projectPath === currentNormalized) continue;
837
- const projectConfigPath = getProjectConfigPath(projectPath);
838
- if (!await fileExists(projectConfigPath)) {
839
- skipped.push(projectPath);
840
- verbose(`Skipped propagation to ${projectPath} (config not found)`);
841
- continue;
842
- }
843
- try {
844
- if (await propagateToProject(projectPath, globalConfig, agents, options)) {
845
- updated.push(projectPath);
846
- verbose(`Propagated global changes to ${projectPath}`);
847
- } else {
848
- skipped.push(projectPath);
849
- }
850
- } catch (error) {
851
- skipped.push(projectPath);
852
- verbose(`Failed to propagate to ${projectPath}: ${getErrorMessage(error)}`);
651
+ const outcome = await propagateToRegisteredProject(
652
+ projectPath,
653
+ provider,
654
+ globalConfig,
655
+ agents,
656
+ options
657
+ );
658
+ result[outcome].push(projectPath);
659
+ }
660
+ return result;
661
+ }
662
+ async function propagateToRegisteredProject(projectPath, provider, globalConfig, agents, options) {
663
+ if (!await holdsAnInstallation(projectPath)) {
664
+ verbose(`Skipped propagation to ${projectPath} (nothing installed there)`);
665
+ return "gone";
666
+ }
667
+ const notOurs = await whyThisProjectIsNotOurs(projectPath, provider);
668
+ if (notOurs !== null) {
669
+ verbose(`Skipped propagation to ${projectPath} (${notOurs})`);
670
+ return "notOurs";
671
+ }
672
+ try {
673
+ if (!await propagateToProject(projectPath, provider, globalConfig, agents, options)) {
674
+ return "gone";
853
675
  }
676
+ verbose(`Propagated global changes to ${projectPath}`);
677
+ return "updated";
678
+ } catch (error) {
679
+ verbose(`Failed to propagate to ${projectPath}: ${getErrorMessage(error)}`);
680
+ return error instanceof ConfigLoadError ? "unreadable" : "failed";
681
+ }
682
+ }
683
+ async function holdsAnInstallation(projectPath) {
684
+ const configs = await Promise.all(
685
+ PROVIDERS.map((installed) => fileExists(getProjectConfigPath(projectPath, installed)))
686
+ );
687
+ return configs.includes(true);
688
+ }
689
+ async function whyThisProjectIsNotOurs(projectPath, provider) {
690
+ const notOurs = `not a ${provider} installation`;
691
+ try {
692
+ if (providerInUse(projectPath) !== provider) return notOurs;
693
+ } catch (error) {
694
+ return getErrorMessage(error);
854
695
  }
855
- return { updated, skipped };
696
+ return await fileExists(getProjectConfigPath(projectPath, provider)) ? null : notOurs;
856
697
  }
857
- async function pruneGlobalEntriesFromRegisteredProjects(globalConfig, agents) {
698
+ async function pruneGlobalEntriesFromRegisteredProjects(globalConfig, agents, provider) {
858
699
  const emptiedGlobal = {
859
700
  ...globalConfig,
860
701
  skills: [],
861
702
  agents: []
862
703
  };
863
- return propagateGlobalChangesToProjects(emptiedGlobal, agents);
704
+ return propagateGlobalChangesToProjects(emptiedGlobal, agents, provider);
864
705
  }
865
706
  async function resolveEffectiveGlobalConfig(globalSplit, existingGlobalConfig, projectDir, authority) {
866
- const merged = authority === "all" ? matchGlobalToSession(globalSplit, existingGlobalConfig) : addSessionToGlobal(globalSplit, existingGlobalConfig);
707
+ const merged = authority === "all" ? matchGlobalToSession(globalSplit, existingGlobalConfig) : addSessionToGlobal(globalSplit, existingGlobalConfig, matrix);
867
708
  const registration = await registerProjectPath(merged.config, projectDir);
868
709
  return {
869
710
  config: registration.config,
@@ -871,21 +712,10 @@ async function resolveEffectiveGlobalConfig(globalSplit, existingGlobalConfig, p
871
712
  changed: merged.changed || registration.changed
872
713
  };
873
714
  }
874
- function addSessionToGlobal(globalSplit, existingGlobalConfig) {
875
- const hasGlobalItems = globalSplit.skills.length > 0 || globalSplit.agents.length > 0;
876
- if (!hasGlobalItems) {
877
- return {
878
- config: existingGlobalConfig ?? { name: GLOBAL_CONFIG_NAME, skills: [], agents: [] },
879
- changed: false
880
- };
881
- }
882
- if (!existingGlobalConfig) return { config: globalSplit, changed: true };
883
- return mergeGlobalConfigs(existingGlobalConfig, globalSplit);
884
- }
885
715
  function matchGlobalToSession(globalSplit, existingGlobalConfig) {
886
716
  if (!existingGlobalConfig) return { config: globalSplit, changed: true };
887
717
  const config = mergeConfigs(globalSplit, existingGlobalConfig, { authoritativeScope: "all" });
888
- return { config, changed: !isDeepEqual(config, existingGlobalConfig) };
718
+ return { config, changed: !isDeepEqual3(config, existingGlobalConfig) };
889
719
  }
890
720
  function stackCategories(stack) {
891
721
  return Object.values(stack ?? {}).flatMap((agentStack) => typedKeys(agentStack ?? {}));
@@ -906,185 +736,6 @@ function buildProjectTypesExtras(finalConfig, matrix2) {
906
736
  return { extraSkillIds, extraAgentNames, extraDomains, extraCategories };
907
737
  }
908
738
 
909
- // src/cli/lib/config-gate/index.ts
910
- import os2 from "os";
911
- import path2 from "path";
912
-
913
- // src/cli/lib/config-gate/classify.ts
914
- import { isDeepEqual as isDeepEqual2 } from "remeda";
915
- var NO_CHANGES = {
916
- skills: { added: [], removed: [], sourceChanged: [], otherChanged: [] },
917
- agents: { added: [], removed: [], changed: [] },
918
- stackChanged: false,
919
- selectedDomainsChanged: false,
920
- scalarsChanged: [],
921
- projectsChanged: false
922
- };
923
- var EXTRACTED_FIELDS2 = /* @__PURE__ */ new Set(["skills", "agents", "stack", "selectedDomains"]);
924
- var REGISTRATION_FIELD = "projects";
925
- function normalize(config) {
926
- return JSON.parse(JSON.stringify(config));
927
- }
928
- function field(config, key) {
929
- return config[key];
930
- }
931
- function skillsById(config) {
932
- const skills = config.skills ?? [];
933
- return new Map(skills.map((skill) => [skill.id, skill]));
934
- }
935
- function agentsByName(config) {
936
- const agents = config.agents ?? [];
937
- return new Map(agents.map((agent) => [agent.name, agent]));
938
- }
939
- function scalarKeys(prev, next) {
940
- const isScalarKey = (key) => !EXTRACTED_FIELDS2.has(key) && key !== REGISTRATION_FIELD;
941
- const nextKeys = Object.keys(next).filter(isScalarKey);
942
- const extraPrevKeys = Object.keys(prev).filter(
943
- (key) => isScalarKey(key) && !nextKeys.includes(key)
944
- );
945
- return [...nextKeys, ...extraPrevKeys];
946
- }
947
- function diffSkills(prev, next) {
948
- const before = skillsById(prev);
949
- const after = skillsById(next);
950
- const added = [...after.keys()].filter((id) => !before.has(id));
951
- const removed = [...before.keys()].filter((id) => !after.has(id));
952
- const sourceChanged = [];
953
- const otherChanged = [];
954
- for (const [id, afterEntry] of after) {
955
- const beforeEntry = before.get(id);
956
- if (!beforeEntry || isDeepEqual2(beforeEntry, afterEntry)) continue;
957
- if (beforeEntry.origin !== afterEntry.origin) sourceChanged.push(id);
958
- else otherChanged.push(id);
959
- }
960
- return { added, removed, sourceChanged, otherChanged };
961
- }
962
- function diffAgents(prev, next) {
963
- const before = agentsByName(prev);
964
- const after = agentsByName(next);
965
- return {
966
- added: [...after.keys()].filter((name) => !before.has(name)),
967
- removed: [...before.keys()].filter((name) => !after.has(name)),
968
- changed: [...after.keys()].filter((name) => {
969
- const beforeEntry = before.get(name);
970
- return beforeEntry !== void 0 && !isDeepEqual2(beforeEntry, after.get(name));
971
- })
972
- };
973
- }
974
- function classifyGlobalChange(prev, next) {
975
- const before = prev ? normalize(prev) : {};
976
- const after = normalize(next);
977
- return {
978
- skills: diffSkills(before, after),
979
- agents: diffAgents(before, after),
980
- stackChanged: !isDeepEqual2(field(before, "stack"), field(after, "stack")),
981
- selectedDomainsChanged: !isDeepEqual2(
982
- field(before, "selectedDomains"),
983
- field(after, "selectedDomains")
984
- ),
985
- scalarsChanged: scalarKeys(before, after).filter(
986
- (key) => !isDeepEqual2(field(before, key), field(after, key))
987
- ),
988
- projectsChanged: !isDeepEqual2(
989
- field(before, REGISTRATION_FIELD),
990
- field(after, REGISTRATION_FIELD)
991
- )
992
- };
993
- }
994
- function movesTypesOrCompiledAgents(changes) {
995
- const { skills, agents } = changes;
996
- return skills.added.length > 0 || skills.removed.length > 0 || skills.sourceChanged.length > 0 || skills.otherChanged.length > 0 || agents.added.length > 0 || agents.removed.length > 0 || agents.changed.length > 0 || changes.stackChanged || changes.selectedDomainsChanged;
997
- }
998
- function consequenceTier(changes) {
999
- if (movesTypesOrCompiledAgents(changes)) return "T1";
1000
- if (changes.scalarsChanged.length > 0) return "T2";
1001
- if (changes.projectsChanged) return "T3";
1002
- return "T4";
1003
- }
1004
- function tierNeedsDeps(tier) {
1005
- return tier === "T1" || tier === "T2";
1006
- }
1007
- function tierRegeneratesTypes(tier) {
1008
- return tier === "T1";
1009
- }
1010
- function tierPropagates(tier) {
1011
- return tier === "T1" || tier === "T2";
1012
- }
1013
-
1014
- // src/cli/lib/config-gate/deps.ts
1015
- function isLoaded(deps) {
1016
- return "matrix" in deps;
1017
- }
1018
- async function resolveGateDeps(deps, tier) {
1019
- if (!tierNeedsDeps(tier)) return null;
1020
- if (isLoaded(deps)) return deps;
1021
- const [matrix2, agents] = await Promise.all([
1022
- deps.loadMatrix(),
1023
- tierRegeneratesTypes(tier) ? deps.loadAgents() : NO_AGENTS
1024
- ]);
1025
- return { matrix: matrix2, agents };
1026
- }
1027
- var NO_AGENTS = Promise.resolve({});
1028
-
1029
- // src/cli/lib/config-gate/pair-writer.ts
1030
- import os from "os";
1031
- import path from "path";
1032
- function globalPairPaths() {
1033
- const dir = path.join(os.homedir(), CLAUDE_SRC_DIR);
1034
- return {
1035
- configPath: path.join(dir, STANDARD_FILES.CONFIG_TS),
1036
- typesPath: path.join(dir, STANDARD_FILES.CONFIG_TYPES_TS)
1037
- };
1038
- }
1039
- function typesPathFor(configPath) {
1040
- return path.join(path.dirname(configPath), STANDARD_FILES.CONFIG_TYPES_TS);
1041
- }
1042
- async function writeIfChanged(filePath, source) {
1043
- assertGateToken(filePath);
1044
- if (await fileExists(filePath) && await readFile(filePath) === source) return false;
1045
- await writeFile(filePath, source);
1046
- return true;
1047
- }
1048
- function renderStandaloneTypes(config, matrix2, agents, extras) {
1049
- const data = buildConfigTypesBackgroundData(matrix2, agents);
1050
- return generateConfigTypesSource(
1051
- data.matrix,
1052
- data.agentNames,
1053
- data.customAgentNames,
1054
- extras,
1055
- config
1056
- );
1057
- }
1058
- async function writeGlobalConfigHalf(config, configPath) {
1059
- return writeIfChanged(configPath, generateConfigSource(config, matrix));
1060
- }
1061
- async function writeGlobalTypesHalf(config, configPath, matrix2, agents, extras) {
1062
- return writeIfChanged(
1063
- typesPathFor(configPath),
1064
- renderStandaloneTypes(config, matrix2, agents, extras)
1065
- );
1066
- }
1067
- async function writeGlobalPair(config, configPath, matrix2, agents) {
1068
- const configWritten = await writeIfChanged(configPath, generateConfigSource(config, matrix2));
1069
- const typesWritten = await writeIfChanged(
1070
- typesPathFor(configPath),
1071
- renderStandaloneTypes(config, matrix2, agents)
1072
- );
1073
- return configWritten || typesWritten;
1074
- }
1075
- async function ensureBlankPair() {
1076
- const { configPath, typesPath } = globalPairPaths();
1077
- if (await fileExists(configPath)) {
1078
- verbose("Global config already exists, skipping blank creation");
1079
- return false;
1080
- }
1081
- await ensureDir(path.dirname(configPath));
1082
- await writeIfChanged(configPath, generateBlankGlobalConfigSource());
1083
- await writeIfChanged(typesPath, generateBlankGlobalConfigTypesSource());
1084
- verbose(`Created blank global config at ${path.dirname(configPath)}`);
1085
- return true;
1086
- }
1087
-
1088
739
  // src/cli/lib/config-gate/recompile.ts
1089
740
  var NOTHING_RECOMPILED = {
1090
741
  rewrittenCount: 0,
@@ -1094,16 +745,25 @@ var NOTHING_RECOMPILED = {
1094
745
  };
1095
746
  async function recompilePropagated(projectDirs) {
1096
747
  if (projectDirs.length === 0) return NOTHING_RECOMPILED;
1097
- const { recompilePropagatedProjectAgents: recompilePropagatedProjectAgents2 } = await import("./recompile-project-agents-VR4NLGOU.js");
748
+ const { recompilePropagatedProjectAgents: recompilePropagatedProjectAgents2 } = await import("./recompile-project-agents-DGNBCU3N.js");
1098
749
  return recompilePropagatedProjectAgents2(projectDirs);
1099
750
  }
1100
751
 
1101
752
  // src/cli/lib/config-gate/index.ts
1102
- var NOTHING_PROPAGATED = { updated: [], skipped: [] };
753
+ var NOTHING_PROPAGATED = {
754
+ updated: [],
755
+ unreadable: [],
756
+ gone: [],
757
+ notOurs: [],
758
+ failed: []
759
+ };
760
+ function movedGlobalAgentInputs(written) {
761
+ return tierRegeneratesTypes(consequenceTier(written.changes));
762
+ }
1103
763
  function report(globalWritten, changes, propagated = NOTHING_PROPAGATED, recompile = NOTHING_RECOMPILED) {
1104
764
  return { globalWritten, changes, propagated, recompile };
1105
765
  }
1106
- async function applyConsequences(globalConfig, changes, deps, currentProjectDir) {
766
+ async function applyConsequences(globalConfig, changes, deps, provider, currentProjectDir) {
1107
767
  const tier = consequenceTier(changes);
1108
768
  if (!tierPropagates(tier) || !globalConfig.projects?.length) {
1109
769
  return { propagated: NOTHING_PROPAGATED, recompile: NOTHING_RECOMPILED };
@@ -1111,6 +771,7 @@ async function applyConsequences(globalConfig, changes, deps, currentProjectDir)
1111
771
  const propagated = await propagateGlobalChangesToProjects(
1112
772
  globalConfig,
1113
773
  deps.agents,
774
+ provider,
1114
775
  currentProjectDir,
1115
776
  { regenerateTypes: tierRegeneratesTypes(tier) }
1116
777
  );
@@ -1123,7 +784,7 @@ async function applyConsequences(globalConfig, changes, deps, currentProjectDir)
1123
784
  function lazyGateDeps(projectDir) {
1124
785
  return {
1125
786
  loadMatrix: async () => {
1126
- const { loadSkillsMatrixFromSource: loadSkillsMatrixFromSource2 } = await import("./source-loader-GRBVNRAW.js");
787
+ const { loadSkillsMatrixFromSource: loadSkillsMatrixFromSource2 } = await import("./source-loader-7KZ3MD5O.js");
1127
788
  const { matrix: matrix2 } = await loadSkillsMatrixFromSource2({
1128
789
  projectDir,
1129
790
  skipExtraSources: true,
@@ -1132,7 +793,7 @@ function lazyGateDeps(projectDir) {
1132
793
  return matrix2;
1133
794
  },
1134
795
  loadAgents: async () => {
1135
- const { loadAgentDefs: loadAgentDefs2 } = await import("./load-agent-defs-7IM3GBEQ.js");
796
+ const { loadAgentDefs: loadAgentDefs2 } = await import("./load-agent-defs-3C27ENC7.js");
1136
797
  return (await loadAgentDefs2()).agents;
1137
798
  }
1138
799
  };
@@ -1145,18 +806,20 @@ async function writeScopedFromWizard(args) {
1145
806
  if (!isHomeDirectory(projectDir)) {
1146
807
  return writeFromProjectContext(args, homeDir, deps);
1147
808
  }
1148
- const priorGlobal = await loadProjectConfigFromDir(homeDir);
809
+ const provider = providerInUse(homeDir);
810
+ const priorGlobal = await loadProjectConfigFromDir(homeDir, provider);
1149
811
  const changes = classifyGlobalChange(priorGlobal?.config, finalConfig);
1150
812
  const globalWritten = await writeGlobalPair(finalConfig, projectConfigPath, matrix2, agents);
1151
- const { propagated, recompile } = await applyConsequences(finalConfig, changes, deps);
813
+ const { propagated, recompile } = await applyConsequences(finalConfig, changes, deps, provider);
1152
814
  return report(globalWritten, changes, propagated, recompile);
1153
815
  });
1154
816
  }
1155
817
  async function writeFromProjectContext(args, homeDir, deps) {
1156
- const { finalConfig, matrix: matrix2, agents, projectDir, projectConfigPath } = args;
818
+ const { finalConfig, projectDir } = args;
1157
819
  const { global: globalConfig, project: projectSplitConfig } = splitConfigByScope(finalConfig);
1158
- const globalConfigPath = getProjectConfigPath(homeDir);
1159
- const existingGlobal = await loadProjectConfigFromDir(homeDir);
820
+ const provider = providerInUse(projectDir);
821
+ const globalConfigPath = getProjectConfigPath(homeDir, provider);
822
+ const existingGlobal = await loadProjectConfigFromDir(homeDir, provider);
1160
823
  const effective = await resolveEffectiveGlobalConfig(
1161
824
  globalConfig,
1162
825
  existingGlobal?.config,
@@ -1165,49 +828,70 @@ async function writeFromProjectContext(args, homeDir, deps) {
1165
828
  );
1166
829
  const effectiveGlobalConfig = effective.config;
1167
830
  const changes = classifyGlobalChange(existingGlobal?.config, effectiveGlobalConfig);
1168
- let globalWritten = false;
1169
- if (effective.changed) {
1170
- await ensureDir(path2.dirname(globalConfigPath));
1171
- globalWritten = await writeGlobalPair(effectiveGlobalConfig, globalConfigPath, matrix2, agents);
1172
- verbose(`Updated global config at ${globalConfigPath}`);
1173
- } else {
1174
- verbose("Global config unchanged, skipping write");
1175
- }
831
+ const globalWritten = await writeGlobalPairWhenChanged(effective, globalConfigPath, deps);
1176
832
  const { propagated, recompile } = await applyConsequences(
1177
833
  effectiveGlobalConfig,
1178
834
  changes,
1179
835
  deps,
836
+ provider,
1180
837
  projectDir
1181
838
  );
1182
839
  const reconciledProjectConfig = reconcileProjectSplitAgainstGlobal(
1183
840
  projectSplitConfig,
1184
841
  effectiveGlobalConfig,
1185
- matrix2
842
+ deps.matrix
1186
843
  );
1187
- const hasProjectItems = reconciledProjectConfig.skills.length > 0 || reconciledProjectConfig.agents.length > 0;
1188
- if (args.projectInstallationExists || hasProjectItems) {
1189
- await ensureDir(path2.dirname(projectConfigPath));
1190
- await writeProjectConfigPair(
1191
- projectDir,
1192
- reconciledProjectConfig,
1193
- effectiveGlobalConfig,
1194
- matrix2,
1195
- agents
1196
- );
1197
- verbose(`Updated project config at ${projectConfigPath}`);
1198
- } else {
844
+ await writeProjectPairWhenOwed(
845
+ args,
846
+ provider,
847
+ reconciledProjectConfig,
848
+ effectiveGlobalConfig,
849
+ deps
850
+ );
851
+ return report(globalWritten, changes, propagated, recompile);
852
+ }
853
+ async function writeGlobalPairWhenChanged(effective, globalConfigPath, deps) {
854
+ if (!effective.changed) {
855
+ verbose("Global config unchanged, skipping write");
856
+ return false;
857
+ }
858
+ await ensureDir(path2.dirname(globalConfigPath));
859
+ const written = await writeGlobalPair(
860
+ effective.config,
861
+ globalConfigPath,
862
+ deps.matrix,
863
+ deps.agents
864
+ );
865
+ verbose(`Updated global config at ${globalConfigPath}`);
866
+ return written;
867
+ }
868
+ async function writeProjectPairWhenOwed(project, provider, reconciledProjectConfig, effectiveGlobalConfig, deps) {
869
+ if (!project.projectInstallationExists && !holdsAnythingOfItsOwn(reconciledProjectConfig)) {
1199
870
  verbose(
1200
871
  "Skipped project config \u2014 no existing project installation and no project-scoped items"
1201
872
  );
873
+ return;
1202
874
  }
1203
- return report(globalWritten, changes, propagated, recompile);
875
+ await ensureDir(path2.dirname(project.projectConfigPath));
876
+ await writeProjectConfigPair(
877
+ project.projectDir,
878
+ provider,
879
+ reconciledProjectConfig,
880
+ effectiveGlobalConfig,
881
+ deps.matrix,
882
+ deps.agents
883
+ );
884
+ verbose(`Updated project config at ${project.projectConfigPath}`);
885
+ }
886
+ function holdsAnythingOfItsOwn(projectConfig) {
887
+ return projectConfig.skills.length > 0 || projectConfig.agents.length > 0;
1204
888
  }
1205
889
  async function writeScopeConfigTypes(projectDir, config, deps, extras) {
1206
890
  return withGateToken(async () => {
1207
891
  if (isHomeDirectory(projectDir)) {
1208
892
  return writeGlobalTypesHalf(
1209
893
  config,
1210
- getProjectConfigPath(projectDir),
894
+ getInstalledConfigPath(projectDir),
1211
895
  deps.matrix,
1212
896
  deps.agents,
1213
897
  extras
@@ -1230,6 +914,7 @@ async function reconcileTypesFromDisk(projectDir, config, deps, options) {
1230
914
  const propagated = await propagateGlobalChangesToProjects(
1231
915
  config,
1232
916
  deps.agents,
917
+ providerInUse(projectDir),
1233
918
  options?.currentProjectDir
1234
919
  );
1235
920
  if (propagated.updated.length > 0) {
@@ -1288,7 +973,8 @@ function fallbackNameFor(mutation) {
1288
973
  async function mutateGlobal(mutation, deps) {
1289
974
  return withGateToken(async () => {
1290
975
  const homeDir = os2.homedir();
1291
- const loadedGlobal = await loadProjectConfigFromDir(homeDir);
976
+ const provider = providerInUse(homeDir);
977
+ const loadedGlobal = await loadProjectConfigFromDir(homeDir, provider);
1292
978
  if (!loadedGlobal) return report(false, NO_CHANGES);
1293
979
  const current = loadedGlobal.config;
1294
980
  const mutated = applyMutation(mutation, current);
@@ -1296,15 +982,18 @@ async function mutateGlobal(mutation, deps) {
1296
982
  const prior = fillRequiredFields(current, fallbackNameFor(mutation));
1297
983
  const next = fillRequiredFields(mutated, fallbackNameFor(mutation));
1298
984
  const changes = classifyGlobalChange(prior, next);
1299
- const globalWritten = await writeGlobalConfigHalf(next, getProjectConfigPath(homeDir));
985
+ const globalWritten = await writeGlobalConfigHalf(
986
+ next,
987
+ getProjectConfigPath(homeDir, provider)
988
+ );
1300
989
  if (!next.projects?.length) return report(globalWritten, changes);
1301
990
  const loaded = await resolveGateDeps(deps, consequenceTier(changes));
1302
991
  if (!loaded) return report(globalWritten, changes);
1303
- const { propagated, recompile } = await applyConsequences(next, changes, loaded);
992
+ const { propagated, recompile } = await applyConsequences(next, changes, loaded, provider);
1304
993
  return report(globalWritten, changes, propagated, recompile);
1305
994
  });
1306
995
  }
1307
- async function propagateGlobalRemoval(preRemovalGlobalConfig, deps) {
996
+ async function propagateGlobalRemoval(preRemovalGlobalConfig, deps, provider) {
1308
997
  return withGateToken(async () => {
1309
998
  const changes = classifyGlobalChange(preRemovalGlobalConfig, {
1310
999
  ...preRemovalGlobalConfig,
@@ -1313,14 +1002,15 @@ async function propagateGlobalRemoval(preRemovalGlobalConfig, deps) {
1313
1002
  });
1314
1003
  const propagated = await pruneGlobalEntriesFromRegisteredProjects(
1315
1004
  preRemovalGlobalConfig,
1316
- deps.agents
1005
+ deps.agents,
1006
+ provider
1317
1007
  );
1318
1008
  const recompile = await recompilePropagated(propagated.updated);
1319
1009
  return report(false, changes, propagated, recompile);
1320
1010
  });
1321
1011
  }
1322
- async function ensureBlankPair2() {
1323
- return withGateToken(() => ensureBlankPair());
1012
+ async function ensureBlankPair2(provider) {
1013
+ return withGateToken(() => ensureBlankPair(provider));
1324
1014
  }
1325
1015
  function withNormalizedStack(partial) {
1326
1016
  if (!partial.stack) return partial;
@@ -1328,10 +1018,10 @@ function withNormalizedStack(partial) {
1328
1018
  }
1329
1019
  async function writeProjectPartial(projectDir, partial, options = {}) {
1330
1020
  if (isHomeDirectory(projectDir)) {
1331
- throw new GlobalPairWriteViolation(getProjectConfigPath(projectDir));
1021
+ throw new GlobalPairWriteViolation(getInstalledConfigPath(projectDir));
1332
1022
  }
1333
- const configPath = getProjectConfigPath(projectDir);
1334
- await ensureDir(path2.join(projectDir, CLAUDE_SRC_DIR));
1023
+ const configPath = getInstalledConfigPath(projectDir);
1024
+ await ensureDir(path2.dirname(configPath));
1335
1025
  await writeFile(
1336
1026
  configPath,
1337
1027
  generateConfigSource(
@@ -1358,7 +1048,7 @@ async function writeProjectConfig(options) {
1358
1048
  const finalConfig = mergeResult.config;
1359
1049
  const isProjectContext = !isHomeDirectory(projectDir);
1360
1050
  if (isProjectContext) {
1361
- await ensureBlankPair2();
1051
+ await ensureBlankPair2(providerInUse(projectDir));
1362
1052
  }
1363
1053
  const propagation = await writeScopedFromWizard({
1364
1054
  finalConfig,
@@ -1381,7 +1071,6 @@ async function writeProjectConfig(options) {
1381
1071
  ...mergeResult.existingConfigPath !== void 0 && {
1382
1072
  existingConfigPath: mergeResult.existingConfigPath
1383
1073
  },
1384
- filesWritten: isProjectContext ? 4 : 2,
1385
1074
  propagation
1386
1075
  };
1387
1076
  }
@@ -1404,13 +1093,19 @@ async function compileAgentsAllScopes(options) {
1404
1093
  outputDir: resolveInstallPaths(os3.homedir(), "global").agentsDir,
1405
1094
  scopeFilter: "global"
1406
1095
  });
1407
- const projectResult = await compileAgents({
1408
- ...base,
1096
+ const projectResult = await compileProjectScope(options);
1097
+ return mergeCompilationResults(globalResult, projectResult);
1098
+ }
1099
+ async function compileProjectScope(options) {
1100
+ const { projectDir, sourcePath, skills, agentScopeMap } = options;
1101
+ return compileAgents({
1102
+ sourcePath,
1103
+ skills,
1104
+ agentScopeMap,
1409
1105
  projectDir,
1410
1106
  outputDir: resolveInstallPaths(projectDir, "project").agentsDir,
1411
1107
  scopeFilter: "project"
1412
1108
  });
1413
- return mergeCompilationResults(globalResult, projectResult);
1414
1109
  }
1415
1110
  function mergeCompilationResults(...results) {
1416
1111
  return {
@@ -1423,9 +1118,10 @@ function mergeCompilationResults(...results) {
1423
1118
 
1424
1119
  export {
1425
1120
  loadSource,
1121
+ sayCapturedWarnings,
1426
1122
  detectProject,
1427
1123
  detectBothInstallations,
1428
- normalizeProjectPath,
1124
+ movedGlobalAgentInputs,
1429
1125
  lazyGateDeps,
1430
1126
  reconcileTypesFromDisk,
1431
1127
  applyMigratedGlobalSources,
@@ -1434,6 +1130,7 @@ export {
1434
1130
  ensureBlankPair2 as ensureBlankPair,
1435
1131
  writeProjectPartial,
1436
1132
  writeProjectConfig,
1437
- compileAgentsAllScopes
1133
+ compileAgentsAllScopes,
1134
+ compileProjectScope
1438
1135
  };
1439
- //# sourceMappingURL=chunk-X37UYIE3.js.map
1136
+ //# sourceMappingURL=chunk-G6UREQ4V.js.map