agents-inc 0.167.0 → 0.170.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 (200) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +18 -15
  3. package/dist/{chunk-ZR4YPKXQ.js → chunk-3G7X2WKI.js} +4 -4
  4. package/dist/{chunk-JOEA52NR.js → chunk-44TE3RKH.js} +46 -2
  5. package/dist/chunk-44TE3RKH.js.map +1 -0
  6. package/dist/{chunk-V5WXIM2F.js → chunk-52HDHJ7I.js} +11 -19
  7. package/dist/chunk-52HDHJ7I.js.map +1 -0
  8. package/dist/{chunk-V3I7VQ7N.js → chunk-6HNXYYVF.js} +39 -22
  9. package/dist/chunk-6HNXYYVF.js.map +1 -0
  10. package/dist/{chunk-MAWNVT2C.js → chunk-6ZRH5RHC.js} +10 -11
  11. package/dist/chunk-6ZRH5RHC.js.map +1 -0
  12. package/dist/{chunk-G6UREQ4V.js → chunk-7RDMTR64.js} +14 -34
  13. package/dist/chunk-7RDMTR64.js.map +1 -0
  14. package/dist/{chunk-GE3WKJ6Q.js → chunk-BMRUNMPV.js} +4 -4
  15. package/dist/{chunk-VAPTVR3J.js → chunk-CLPUWOSA.js} +4 -4
  16. package/dist/{chunk-VAPTVR3J.js.map → chunk-CLPUWOSA.js.map} +1 -1
  17. package/dist/{chunk-HWEKHVLE.js → chunk-F2BHT5C4.js} +9 -7
  18. package/dist/chunk-F2BHT5C4.js.map +1 -0
  19. package/dist/{chunk-ZXKBERQU.js → chunk-F5EBEATU.js} +2 -2
  20. package/dist/{chunk-PMJWD27C.js → chunk-HED2DAXZ.js} +3 -3
  21. package/dist/{chunk-SAYZWCH6.js → chunk-KOLDW6SF.js} +3 -3
  22. package/dist/{chunk-SAYZWCH6.js.map → chunk-KOLDW6SF.js.map} +1 -1
  23. package/dist/{chunk-A4KDXNOT.js → chunk-MQ6CGZNJ.js} +171 -522
  24. package/dist/chunk-MQ6CGZNJ.js.map +1 -0
  25. package/dist/{chunk-G4JK7WVO.js → chunk-NCWDK6L7.js} +115 -196
  26. package/dist/chunk-NCWDK6L7.js.map +1 -0
  27. package/dist/{chunk-VRXX4D6K.js → chunk-NEZ4OAOL.js} +1 -1
  28. package/dist/chunk-NEZ4OAOL.js.map +1 -0
  29. package/dist/chunk-NIHUOWE4.js +106 -0
  30. package/dist/chunk-NIHUOWE4.js.map +1 -0
  31. package/dist/{chunk-OI2H6M5I.js → chunk-NQW25DCF.js} +2 -2
  32. package/dist/chunk-NQW25DCF.js.map +1 -0
  33. package/dist/{chunk-25MPBIK3.js → chunk-OYJQUA3D.js} +3 -3
  34. package/dist/{chunk-25MPBIK3.js.map → chunk-OYJQUA3D.js.map} +1 -1
  35. package/dist/{chunk-ENGYJCTF.js → chunk-PJWGTNOX.js} +220 -254
  36. package/dist/chunk-PJWGTNOX.js.map +1 -0
  37. package/dist/{chunk-NBXXFIIW.js → chunk-RIPSGNLU.js} +3 -3
  38. package/dist/chunk-RIPSGNLU.js.map +1 -0
  39. package/dist/{chunk-Y47EV74W.js → chunk-SZYQISA2.js} +10 -13
  40. package/dist/chunk-SZYQISA2.js.map +1 -0
  41. package/dist/{chunk-TODCQFRB.js → chunk-USVBYQSQ.js} +2 -2
  42. package/dist/{chunk-Y3VIRVVE.js → chunk-V3KTSP3Q.js} +50 -42
  43. package/dist/chunk-V3KTSP3Q.js.map +1 -0
  44. package/dist/{chunk-PXWG7KFO.js → chunk-WTWMGH2C.js} +2 -2
  45. package/dist/commands/build/marketplace.js +23 -22
  46. package/dist/commands/build/marketplace.js.map +1 -1
  47. package/dist/commands/build/plugins.js +8 -9
  48. package/dist/commands/build/plugins.js.map +1 -1
  49. package/dist/commands/compile.js +19 -20
  50. package/dist/commands/compile.js.map +1 -1
  51. package/dist/commands/doctor.js +17 -18
  52. package/dist/commands/doctor.js.map +1 -1
  53. package/dist/commands/edit.js +138 -488
  54. package/dist/commands/edit.js.map +1 -1
  55. package/dist/commands/eject.js +21 -33
  56. package/dist/commands/eject.js.map +1 -1
  57. package/dist/commands/init.js +17 -45
  58. package/dist/commands/list.js +19 -17
  59. package/dist/commands/list.js.map +1 -1
  60. package/dist/commands/new/marketplace.js +11 -11
  61. package/dist/commands/new/marketplace.js.map +1 -1
  62. package/dist/commands/search.js +12 -13
  63. package/dist/commands/search.js.map +1 -1
  64. package/dist/commands/share.js +11 -12
  65. package/dist/commands/share.js.map +1 -1
  66. package/dist/commands/uninstall.js +18 -20
  67. package/dist/commands/uninstall.js.map +1 -1
  68. package/dist/commands/update.js +8 -9
  69. package/dist/commands/update.js.map +1 -1
  70. package/dist/components/common/removal-plan-confirm.js +2 -2
  71. package/dist/components/common/scroll-affordance.js +9 -0
  72. package/dist/components/common/select-list.js +2 -3
  73. package/dist/components/common/skill-agent-summary.js +11 -0
  74. package/dist/components/common/spinner.js +1 -1
  75. package/dist/{chunk-2VUYFTUB.js → components/common/summary-panel.js} +57 -31
  76. package/dist/components/common/summary-panel.js.map +1 -0
  77. package/dist/config-exports.js +1 -1
  78. package/dist/hooks/init.js +18 -46
  79. package/dist/hooks/init.js.map +1 -1
  80. package/dist/load-agent-defs-YMDWBFDP.js +14 -0
  81. package/dist/recompile-project-agents-SZ76WNTW.js +18 -0
  82. package/dist/{source-loader-7KZ3MD5O.js → source-loader-C5SQXZXI.js} +5 -5
  83. package/dist/src/agents/meta/codex-keeper/playbook.md +2 -3
  84. package/package.json +6 -4
  85. package/src/agents/meta/codex-keeper/playbook.md +2 -3
  86. package/src/schemas/project-config.schema.json +1 -1
  87. package/assets/demo.tape +0 -266
  88. package/dist/chunk-2VUYFTUB.js.map +0 -1
  89. package/dist/chunk-4NDBUJHK.js +0 -237
  90. package/dist/chunk-4NDBUJHK.js.map +0 -1
  91. package/dist/chunk-6L75SQZU.js +0 -168
  92. package/dist/chunk-6L75SQZU.js.map +0 -1
  93. package/dist/chunk-6LF4CQBY.js +0 -51
  94. package/dist/chunk-6LF4CQBY.js.map +0 -1
  95. package/dist/chunk-7JNJ52CD.js +0 -1179
  96. package/dist/chunk-7JNJ52CD.js.map +0 -1
  97. package/dist/chunk-A4KDXNOT.js.map +0 -1
  98. package/dist/chunk-DAIEQJIF.js +0 -48
  99. package/dist/chunk-DAIEQJIF.js.map +0 -1
  100. package/dist/chunk-ENGYJCTF.js.map +0 -1
  101. package/dist/chunk-G4JK7WVO.js.map +0 -1
  102. package/dist/chunk-G6UREQ4V.js.map +0 -1
  103. package/dist/chunk-HHIYT3PI.js +0 -53
  104. package/dist/chunk-HHIYT3PI.js.map +0 -1
  105. package/dist/chunk-HWEKHVLE.js.map +0 -1
  106. package/dist/chunk-JOEA52NR.js.map +0 -1
  107. package/dist/chunk-JQRJQ4SS.js +0 -118
  108. package/dist/chunk-JQRJQ4SS.js.map +0 -1
  109. package/dist/chunk-LFWLEDUG.js +0 -59
  110. package/dist/chunk-LFWLEDUG.js.map +0 -1
  111. package/dist/chunk-MAWNVT2C.js.map +0 -1
  112. package/dist/chunk-MPTNC32T.js +0 -92
  113. package/dist/chunk-MPTNC32T.js.map +0 -1
  114. package/dist/chunk-NBXXFIIW.js.map +0 -1
  115. package/dist/chunk-OI2H6M5I.js.map +0 -1
  116. package/dist/chunk-PNB3524H.js +0 -197
  117. package/dist/chunk-PNB3524H.js.map +0 -1
  118. package/dist/chunk-QHDPLLK6.js +0 -35
  119. package/dist/chunk-QHDPLLK6.js.map +0 -1
  120. package/dist/chunk-RAHSOJQ2.js +0 -25
  121. package/dist/chunk-RAHSOJQ2.js.map +0 -1
  122. package/dist/chunk-RZDXDMT6.js +0 -23
  123. package/dist/chunk-RZDXDMT6.js.map +0 -1
  124. package/dist/chunk-SCOQ34YM.js +0 -17
  125. package/dist/chunk-SCOQ34YM.js.map +0 -1
  126. package/dist/chunk-SXVHSOTH.js +0 -268
  127. package/dist/chunk-SXVHSOTH.js.map +0 -1
  128. package/dist/chunk-T6UWJAB3.js +0 -28
  129. package/dist/chunk-T6UWJAB3.js.map +0 -1
  130. package/dist/chunk-TSIU7DME.js +0 -43
  131. package/dist/chunk-TSIU7DME.js.map +0 -1
  132. package/dist/chunk-TTY6DPJN.js +0 -27
  133. package/dist/chunk-TTY6DPJN.js.map +0 -1
  134. package/dist/chunk-TZ2YJJKK.js +0 -292
  135. package/dist/chunk-TZ2YJJKK.js.map +0 -1
  136. package/dist/chunk-V3I7VQ7N.js.map +0 -1
  137. package/dist/chunk-V5WXIM2F.js.map +0 -1
  138. package/dist/chunk-VRXX4D6K.js.map +0 -1
  139. package/dist/chunk-WTJ3AY33.js +0 -31
  140. package/dist/chunk-WTJ3AY33.js.map +0 -1
  141. package/dist/chunk-WVUDLKIO.js +0 -121
  142. package/dist/chunk-WVUDLKIO.js.map +0 -1
  143. package/dist/chunk-WWIFNPJG.js +0 -317
  144. package/dist/chunk-WWIFNPJG.js.map +0 -1
  145. package/dist/chunk-XQHZPINL.js +0 -89
  146. package/dist/chunk-XQHZPINL.js.map +0 -1
  147. package/dist/chunk-XZEVWPX6.js +0 -230
  148. package/dist/chunk-XZEVWPX6.js.map +0 -1
  149. package/dist/chunk-Y3VIRVVE.js.map +0 -1
  150. package/dist/chunk-Y47EV74W.js.map +0 -1
  151. package/dist/components/wizard/category-grid.js +0 -13
  152. package/dist/components/wizard/checkbox-grid.js +0 -12
  153. package/dist/components/wizard/domain-selection.js +0 -18
  154. package/dist/components/wizard/run-wizard-session.js +0 -40
  155. package/dist/components/wizard/run-wizard-session.js.map +0 -1
  156. package/dist/components/wizard/scroll-affordance.js +0 -9
  157. package/dist/components/wizard/skill-agent-summary.js +0 -13
  158. package/dist/components/wizard/source-grid.js +0 -16
  159. package/dist/components/wizard/source-grid.js.map +0 -1
  160. package/dist/components/wizard/stack-selection.js +0 -17
  161. package/dist/components/wizard/stack-selection.js.map +0 -1
  162. package/dist/components/wizard/step-agents.js +0 -18
  163. package/dist/components/wizard/step-agents.js.map +0 -1
  164. package/dist/components/wizard/step-build.js +0 -18
  165. package/dist/components/wizard/step-build.js.map +0 -1
  166. package/dist/components/wizard/step-confirm.js +0 -18
  167. package/dist/components/wizard/step-confirm.js.map +0 -1
  168. package/dist/components/wizard/step-sources.js +0 -19
  169. package/dist/components/wizard/step-sources.js.map +0 -1
  170. package/dist/components/wizard/step-stack.js +0 -18
  171. package/dist/components/wizard/step-stack.js.map +0 -1
  172. package/dist/components/wizard/summary-panel.js +0 -17
  173. package/dist/components/wizard/summary-panel.js.map +0 -1
  174. package/dist/components/wizard/toast.js +0 -9
  175. package/dist/components/wizard/toast.js.map +0 -1
  176. package/dist/components/wizard/wizard-layout.js +0 -22
  177. package/dist/components/wizard/wizard-layout.js.map +0 -1
  178. package/dist/components/wizard/wizard-tabs.js +0 -11
  179. package/dist/components/wizard/wizard-tabs.js.map +0 -1
  180. package/dist/components/wizard/wizard.js +0 -39
  181. package/dist/components/wizard/wizard.js.map +0 -1
  182. package/dist/load-agent-defs-3C27ENC7.js +0 -14
  183. package/dist/load-agent-defs-3C27ENC7.js.map +0 -1
  184. package/dist/recompile-project-agents-DGNBCU3N.js +0 -18
  185. package/dist/recompile-project-agents-DGNBCU3N.js.map +0 -1
  186. package/dist/source-loader-7KZ3MD5O.js.map +0 -1
  187. package/dist/stores/wizard-store.js +0 -24
  188. package/dist/stores/wizard-store.js.map +0 -1
  189. /package/assets/{demo.gif → legacy-wizard.gif} +0 -0
  190. /package/dist/{chunk-ZR4YPKXQ.js.map → chunk-3G7X2WKI.js.map} +0 -0
  191. /package/dist/{chunk-GE3WKJ6Q.js.map → chunk-BMRUNMPV.js.map} +0 -0
  192. /package/dist/{chunk-ZXKBERQU.js.map → chunk-F5EBEATU.js.map} +0 -0
  193. /package/dist/{chunk-PMJWD27C.js.map → chunk-HED2DAXZ.js.map} +0 -0
  194. /package/dist/{chunk-TODCQFRB.js.map → chunk-USVBYQSQ.js.map} +0 -0
  195. /package/dist/{chunk-PXWG7KFO.js.map → chunk-WTWMGH2C.js.map} +0 -0
  196. /package/dist/components/{wizard → common}/scroll-affordance.js.map +0 -0
  197. /package/dist/components/{wizard → common}/skill-agent-summary.js.map +0 -0
  198. /package/dist/{components/wizard/category-grid.js.map → load-agent-defs-YMDWBFDP.js.map} +0 -0
  199. /package/dist/{components/wizard/checkbox-grid.js.map → recompile-project-agents-SZ76WNTW.js.map} +0 -0
  200. /package/dist/{components/wizard/domain-selection.js.map → source-loader-C5SQXZXI.js.map} +0 -0
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BUILT_IN_MATRIX,
4
- allSkills,
5
4
  getSkillById,
6
5
  initializeMatrix,
7
6
  matrix,
@@ -9,7 +8,7 @@ import {
9
8
  typedFromEntries,
10
9
  typedKeys,
11
10
  typedValues
12
- } from "./chunk-V5WXIM2F.js";
11
+ } from "./chunk-52HDHJ7I.js";
13
12
  import {
14
13
  AGENT_NAMES,
15
14
  AUTHOR_HANDLE_PATTERN,
@@ -17,6 +16,7 @@ import {
17
16
  CACHE_READABLE_PREFIX_LENGTH,
18
17
  CLAUDE_DIR,
19
18
  CLI_INVOKE_COMMAND,
19
+ CODEX_MODEL_NAMES,
20
20
  DEFAULT_BRANDING,
21
21
  DEFAULT_PLUGIN_NAME,
22
22
  DEFAULT_PUBLIC_SOURCE_NAME,
@@ -64,11 +64,11 @@ import {
64
64
  bytewise,
65
65
  cacheRoot,
66
66
  categoryDomain,
67
- createSelectionSemantics,
68
67
  diagnostics,
69
68
  editorConfigUrl,
70
69
  effectivelyExcludedSkillIds,
71
70
  globalInstallRoot,
71
+ inAnEnglishList,
72
72
  isActiveAt,
73
73
  isExclusiveCategory,
74
74
  isGlobalTombstone,
@@ -78,16 +78,17 @@ import {
78
78
  orderDomains,
79
79
  resolveAssignment,
80
80
  resolveLoadState,
81
+ seatDiagnostics,
81
82
  seatedCatalog,
82
83
  seedAgentScope,
83
84
  sourceDirName,
84
85
  validateSelection
85
- } from "./chunk-ENGYJCTF.js";
86
+ } from "./chunk-PJWGTNOX.js";
86
87
  import {
87
88
  defaultCategories,
88
89
  defaultRules,
89
90
  defaultStacks
90
- } from "./chunk-OI2H6M5I.js";
91
+ } from "./chunk-NQW25DCF.js";
91
92
 
92
93
  // src/cli/lib/loading/source-loader.ts
93
94
  import os14 from "os";
@@ -168,21 +169,33 @@ function renderAgentRoleToml(agent, body) {
168
169
  refuseBlankInstructions(agent.name, body);
169
170
  return [
170
171
  ...scalarLines(agent, body),
171
- // Last, always: every bare key after a table header belongs to that table, so a scalar
172
- // emitted below `[features]` would become `features.model` and take the file with it.
172
+ // Last: every bare key after a table header belongs to that table.
173
173
  ...shellToolTable(agent)
174
174
  ].join("\n");
175
175
  }
176
176
  var CODEX_DEVELOPER_INSTRUCTIONS_OPENER = `developer_instructions = """`;
177
177
  var CODEX_EFFORT_KEY = "model_reasoning_effort";
178
+ var PINNED_MODEL_RESTING_EFFORT = "medium";
178
179
  function scalarLines(agent, body) {
179
180
  return [
180
181
  `name = ${basicString(agent.name)}`,
181
182
  `description = ${basicString(agent.description)}`,
182
- ...agent.effort === void 0 ? [] : [`${CODEX_EFFORT_KEY} = ${basicString(agent.effort)}`],
183
+ ...modelLines(agent),
183
184
  developerInstructions(body)
184
185
  ];
185
186
  }
187
+ function modelLines(agent) {
188
+ if (agent.codexModel === void 0) {
189
+ return agent.effort === void 0 ? [] : [effortLine(agent.effort)];
190
+ }
191
+ return [
192
+ `model = ${basicString(agent.codexModel)}`,
193
+ effortLine(agent.effort ?? PINNED_MODEL_RESTING_EFFORT)
194
+ ];
195
+ }
196
+ function effortLine(effort) {
197
+ return `${CODEX_EFFORT_KEY} = ${basicString(effort)}`;
198
+ }
186
199
  function developerInstructions(body) {
187
200
  return `${CODEX_DEVELOPER_INSTRUCTIONS_OPENER}
188
201
  ${asMultilineString(body)}
@@ -259,12 +272,6 @@ function agentsLeftOutOfCodexMessage() {
259
272
  function unexpressibleOnCodexMessage() {
260
273
  return `Codex cannot express ${inAnEnglishList(UNEXPRESSIBLE_ON_CODEX)}, so the agent role files it wrote carry none of them.`;
261
274
  }
262
- function inAnEnglishList(items) {
263
- const last = items.at(-1);
264
- if (last === void 0) return "";
265
- if (items.length === 1) return last;
266
- return `${items.slice(0, -1).join(", ")} and ${last}`;
267
- }
268
275
 
269
276
  // ../compile/src/agent-source.ts
270
277
  var LIQUID_SYNTAX_PATTERN = /\{\{|\}\}|\{%|%\}/g;
@@ -862,6 +869,7 @@ async function grantOwnerWrite(target) {
862
869
  }
863
870
 
864
871
  // src/cli/utils/logger.ts
872
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
865
873
  var verboseMode = false;
866
874
  function setVerbose(enabled) {
867
875
  verboseMode = enabled;
@@ -876,6 +884,8 @@ function log(msg) {
876
884
  }
877
885
  var bufferMode = false;
878
886
  var messageBuffer = [];
887
+ var alreadySaid = /* @__PURE__ */ new Set();
888
+ var eachWarningOnce = new AsyncLocalStorage2();
879
889
  function enableBuffering() {
880
890
  bufferMode = true;
881
891
  messageBuffer = [];
@@ -890,17 +900,23 @@ function disableBuffering() {
890
900
  messageBuffer = [];
891
901
  }
892
902
  function warn(msg) {
903
+ if (isARepeatToHoldBack(msg)) return;
893
904
  if (bufferMode) {
894
905
  messageBuffer.push({ level: "warn", text: msg });
895
906
  return;
896
907
  }
908
+ alreadySaid.add(msg);
897
909
  console.warn(` Warning: ${msg}`);
898
910
  }
899
- var alreadySaid = /* @__PURE__ */ new Set();
911
+ function isARepeatToHoldBack(msg) {
912
+ if (eachWarningOnce.getStore() !== true) return false;
913
+ return alreadySaid.has(msg) || messageBuffer.some((message) => message.text === msg);
914
+ }
915
+ function sayingEachWarningOnce(body) {
916
+ return eachWarningOnce.run(true, body);
917
+ }
900
918
  function warnOnce(msg) {
901
- if (alreadySaid.has(msg)) return;
902
- alreadySaid.add(msg);
903
- warn(msg);
919
+ sayingEachWarningOnce(() => warn(msg));
904
920
  }
905
921
 
906
922
  // src/cli/lib/validate-kebab-name.ts
@@ -931,7 +947,7 @@ var ERROR_MESSAGES = {
931
947
  * What `compile` refuses with when every pass discovered zero skills. It is reached only
932
948
  * after an installation was detected, so the state it describes is a configuration with
933
949
  * nothing installed under it — the same state `doctor` reports as `config-empty` and
934
- * names `init` for, because `init` on a config that declares nothing opens the wizard
950
+ * names `init` for, because `init` on a config that declares nothing opens the editor
935
951
  * rather than the dashboard. `edit` is the wrong half of the pair here: it modifies the
936
952
  * currently installed skills, and there are none to modify.
937
953
  */
@@ -1041,7 +1057,7 @@ function scopeBlockedStackAssignment(agentNames, skillId) {
1041
1057
  }
1042
1058
  function globalScopedAgentsHint(count) {
1043
1059
  const [subject, object] = count === 1 ? ["agent is", "it"] : ["agents are", "them"];
1044
- return `${count} ${subject} global-scoped \u2014 run '${CLI_INVOKE_COMMAND} compile' from your home directory, or edit from this project, to recompile ${object}.`;
1060
+ return `${count} ${subject} global-scoped \u2014 run '${CLI_INVOKE_COMMAND} compile' from your home directory to recompile ${object}.`;
1045
1061
  }
1046
1062
  function marketplacesRefreshed(count) {
1047
1063
  return `Refreshed ${plural(count, "marketplace listing")}. Installed plugins were not changed.`;
@@ -1148,6 +1164,13 @@ function savedSkillMetadataUnusableError(entries) {
1148
1164
  METADATA_UNUSABLE_WAY_OUT
1149
1165
  ].join("\n");
1150
1166
  }
1167
+ function editorSkillMetadataUnusableError(entries) {
1168
+ return [
1169
+ metadataUnusableOpening(entries),
1170
+ `The editor opens on what these files describe, so no link is made until each one describes its skill.`,
1171
+ METADATA_UNUSABLE_WAY_OUT
1172
+ ].join("\n");
1173
+ }
1151
1174
  var SHARED_CONFIG_GREENFIELD_HINT = "installing a shared configuration is a fresh setup, not a merge";
1152
1175
  function sharedConfigDestinations(id) {
1153
1176
  return [
@@ -1213,27 +1236,14 @@ function sharedConfigNeedsTerminal(id) {
1213
1236
  function nothingInstalledToApplyTo(id) {
1214
1237
  return `No installation found. Run '${CLI_INVOKE_COMMAND} init --from ${id}' to install configuration '${id}' here.`;
1215
1238
  }
1216
- var RUNS_WITHOUT_A_TERMINAL = {
1217
- init: `'${CLI_INVOKE_COMMAND} init --from <id>' installs a configuration built in the editor without one`,
1218
- edit: `'${CLI_INVOKE_COMMAND} edit --ui' opens this installation in the editor without one`
1219
- };
1220
- function wizardNeedsTerminal(command) {
1221
- return [
1222
- `'${CLI_INVOKE_COMMAND} ${command}' opens a wizard, and there is no terminal here to open it in.`,
1223
- `Run it from a terminal \u2014 ${RUNS_WITHOUT_A_TERMINAL[command]}.`
1224
- ].join("\n");
1225
- }
1226
1239
  function uninstallNeedsTerminal() {
1227
1240
  return [
1228
1241
  "Uninstalling removes files, so it has to be confirmed \u2014 and there is no terminal here to confirm it at.",
1229
1242
  `Run '${CLI_INVOKE_COMMAND} uninstall' from a terminal, or '${CLI_INVOKE_COMMAND} uninstall --yes' to remove it without being asked.`
1230
1243
  ].join("\n");
1231
1244
  }
1232
- function editorLoadsItsOwnMarketplace(named) {
1233
- return `--marketplace '${named}' cannot be handed to the editor: the editor loads marketplaces itself. Run '${CLI_INVOKE_COMMAND} init --ui' and load it there.`;
1234
- }
1235
- function marketplaceFixedAtInstall(stored, named) {
1236
- return `This folder's installation was made from the marketplace '${stored}', and an installation's marketplace is chosen once, when it is made \u2014 so --marketplace '${named}' was not used. Run '${CLI_INVOKE_COMMAND} init' without it to open this installation, or '${CLI_INVOKE_COMMAND} uninstall' first to set this folder up from another.`;
1245
+ function addMarketplaceInTheEditor(ref, isFolder) {
1246
+ return isFolder ? `${ref} is a folder on this machine, which the editor cannot read \u2014 push it to GitHub, then add it from the editor's Marketplace button.` : `Add ${ref} from the editor's Marketplace button.`;
1237
1247
  }
1238
1248
  var SHARED_CONFIG_ARRIVALS = {
1239
1249
  PROJECT_HEADING: "Into this project:",
@@ -1249,11 +1259,18 @@ function keptAsInstalledGlobally(skillIds, agentNames) {
1249
1259
  `Change them with '${CLI_INVOKE_COMMAND} edit' from your home directory.`
1250
1260
  ].join("\n");
1251
1261
  }
1262
+ function addedToGlobalSubAgents(joined) {
1263
+ return [
1264
+ "Added to sub-agents in the global install \u2014 each keeps everything it already has, since a project run only adds to the global install:",
1265
+ ...joined.map(
1266
+ ({ agentName, skillIds }) => ` sub-agent ${agentName}: + ${skillIds.join(", ")}`
1267
+ )
1268
+ ].join("\n");
1269
+ }
1252
1270
  function authoredHereKept(skillIds) {
1253
1271
  return [
1254
1272
  "Kept \u2014 written here rather than installed, so a shared configuration never carried them:",
1255
- ...skillIds.map((id) => ` skill ${id}`),
1256
- `Remove them with '${CLI_INVOKE_COMMAND} edit'.`
1273
+ ...skillIds.map((id) => ` skill ${id}`)
1257
1274
  ].join("\n");
1258
1275
  }
1259
1276
  function unplaceableKept(skillIds) {
@@ -1266,35 +1283,30 @@ function unplaceableKept(skillIds) {
1266
1283
  function keptUnassigned(skillId, agentName, category) {
1267
1284
  return `${skillId}: kept, no longer assigned to ${agentName}'s ${category}`;
1268
1285
  }
1269
- function otherWaysPastUnreadableConfigs(count) {
1270
- return [
1271
- `Or build one at ${EDITOR_URL} and install it with '${CLI_INVOKE_COMMAND} init --from <id>'.`,
1272
- `'${CLI_INVOKE_COMMAND} doctor' reports the same ${count === 1 ? "file" : "files"}, alongside whatever else is wrong here.`
1273
- ];
1286
+ function doctorReportsTheSame(count) {
1287
+ return `'${CLI_INVOKE_COMMAND} doctor' reports the same ${count === 1 ? "file" : "files"}, alongside whatever else is wrong here.`;
1274
1288
  }
1275
1289
  function installationConfigsUnreadable(failures) {
1276
- return [
1277
- ...failures.flatMap(whoseConfigAndItsWayOut),
1278
- ...otherWaysPastUnreadableConfigs(failures.length)
1279
- ].join("\n");
1290
+ return [...failures.flatMap(whoseConfigAndItsWayOut), doctorReportsTheSame(failures.length)].join(
1291
+ "\n"
1292
+ );
1280
1293
  }
1281
1294
  function whoseConfigAndItsWayOut(failure) {
1282
1295
  return [
1283
1296
  `${scopeLabel(failure.scope)}'s config at '${failure.configPath}' could not be loaded: ${failure.reason}`,
1284
- `There is no automatic repair for this \u2014 recreate the configuration by running ${recreateConfigFrom(failure.scopeRoot)}.`
1297
+ `There is no automatic repair for this \u2014 fix the file, or recreate the configuration by running ${recreateConfigFrom(failure.scopeRoot)}.`
1285
1298
  ];
1286
1299
  }
1287
1300
  function uninstallConfigUnreadable(failure) {
1288
1301
  return `Could not read the ${failure.scope} config \u2014 plugins and compiled agents it lists may be left behind: ${failure.message}`;
1289
1302
  }
1290
1303
  function recreateConfigFrom(scopeRoot) {
1291
- return `'${CLI_INVOKE_COMMAND} uninstall', which still works on a config it cannot read, then '${CLI_INVOKE_COMMAND} init', from '${scopeRoot}'`;
1304
+ return `'${CLI_INVOKE_COMMAND} uninstall' from '${scopeRoot}', which still works on a config it cannot read, then '${CLI_INVOKE_COMMAND} init --from <id>' with an id from ${EDITOR_URL}`;
1292
1305
  }
1293
1306
  function configUnreadableError(configLoadFailure2) {
1294
1307
  return [
1295
1308
  configLoadFailure2,
1296
- `There is no automatic repair for this \u2014 recreate the configuration: '${CLI_INVOKE_COMMAND} uninstall' still works on a config it cannot read, then '${CLI_INVOKE_COMMAND} init'.`,
1297
- ...otherWaysPastUnreadableConfigs(1)
1309
+ "This is the marketplace's own config rather than an installation's, so it is fixed in the marketplace repository it comes from."
1298
1310
  ].join("\n");
1299
1311
  }
1300
1312
  function registeredProjectsUpdateFailed(reason) {
@@ -1918,17 +1930,6 @@ var CATEGORIES = [
1918
1930
  "web-ui-kit",
1919
1931
  "web-utilities"
1920
1932
  ];
1921
- var DOMAINS = [
1922
- "ai",
1923
- "api",
1924
- "cli",
1925
- "desktop",
1926
- "infra",
1927
- "meta",
1928
- "mobile",
1929
- "shared",
1930
- "web"
1931
- ];
1932
1933
  var AGENT_NAMES2 = [
1933
1934
  "agent-summoner",
1934
1935
  "ai-developer",
@@ -1954,9 +1955,6 @@ var AGENT_NAMES2 = [
1954
1955
  function isRecord(value) {
1955
1956
  return typeof value === "object" && value !== null && !Array.isArray(value);
1956
1957
  }
1957
- function isDomain(value) {
1958
- return DOMAINS.includes(value);
1959
- }
1960
1958
  function isAgentName(value) {
1961
1959
  return AGENT_NAMES2.includes(value);
1962
1960
  }
@@ -1992,6 +1990,12 @@ function formatZodErrors(error) {
1992
1990
 
1993
1991
  // src/cli/types/matrix.ts
1994
1992
  var MODEL_NAMES2 = ["sonnet", "opus", "haiku", "fable", "inherit"];
1993
+ var CODEX_MODEL_NAMES2 = [
1994
+ "gpt-6-astra",
1995
+ "gpt-5.6-sol",
1996
+ "gpt-5.6-terra",
1997
+ "gpt-5.6-luna"
1998
+ ];
1995
1999
  var EFFORT_NAMES2 = ["low", "medium", "high", "xhigh", "max"];
1996
2000
  var PERMISSION_MODES = [
1997
2001
  "default",
@@ -2006,6 +2010,7 @@ var CACHE_TTLS = ["5m", "1h"];
2006
2010
 
2007
2011
  // src/cli/lib/schemas.ts
2008
2012
  var modelNameSchema = z2.enum(MODEL_NAMES2);
2013
+ var codexModelNameSchema = z2.enum(CODEX_MODEL_NAMES2);
2009
2014
  var effortLevelSchema = z2.enum(EFFORT_NAMES2);
2010
2015
  var permissionModeSchema = z2.enum(PERMISSION_MODES);
2011
2016
  var skillSlugSchema = z2.enum(SKILL_SLUGS);
@@ -2049,7 +2054,7 @@ var skillAssignmentSchema = z2.object({
2049
2054
  path: z2.string().exactOptional()
2050
2055
  });
2051
2056
  var skillFrontmatterLoaderSchema = z2.object({
2052
- /** Lenient (any string): local/custom skills have non-builtin IDs */
2057
+ /** Lenient: local/custom skills have non-builtin IDs. */
2053
2058
  name: z2.string(),
2054
2059
  description: z2.string(),
2055
2060
  model: modelNameSchema.exactOptional()
@@ -2080,7 +2085,7 @@ var pluginManifestObjectSchema = z2.object({
2080
2085
  version: z2.string().exactOptional(),
2081
2086
  description: z2.string().exactOptional(),
2082
2087
  author: pluginAuthorSchema.exactOptional(),
2083
- /** Lenient: a plugin authored elsewhere may carry any category string or none at all */
2088
+ /** A plugin authored elsewhere may carry any category, or none. */
2084
2089
  category: z2.string().exactOptional(),
2085
2090
  keywords: z2.array(z2.string()).exactOptional(),
2086
2091
  commands: z2.union([z2.string(), z2.array(z2.string())]).exactOptional(),
@@ -2100,14 +2105,7 @@ var agentYamlConfigSchema = z2.object({
2100
2105
  disallowedTools: z2.array(z2.string()).exactOptional(),
2101
2106
  permissionMode: permissionModeSchema.exactOptional(),
2102
2107
  isolation: agentIsolationSchema.exactOptional(),
2103
- /**
2104
- * The same contract `agentFrontmatterValidationSchema` reads the compiled agent back through.
2105
- * The lenient {@link hooksRecordSchema} used to sit here, and every key its definition declares
2106
- * is optional — so a block written with its actions one level flat was stripped to `{}` with no
2107
- * error, `agent.liquid` emitted the empty definition, and the refusal arrived from the
2108
- * frontmatter reader against a compiled `.md` the user never wrote. This is the last boundary
2109
- * that still knows which `metadata.yaml` the value came from.
2110
- */
2108
+ /** Strict, like the frontmatter reader: a lenient read silently emptied malformed hooks. */
2111
2109
  hooks: strictHooksRecordSchema.exactOptional(),
2112
2110
  experimental: agentExperimentalSchema.exactOptional(),
2113
2111
  outputFormat: z2.string().exactOptional(),
@@ -2149,21 +2147,18 @@ function refuseRenamedFields(config, ctx) {
2149
2147
  }
2150
2148
  var renamedFieldGuard = z2.unknown().superRefine(refuseRenamedFields);
2151
2149
  var projectConfigFields = z2.object({
2152
- /** Project/plugin name in kebab-case */
2153
2150
  name: z2.string().exactOptional(),
2154
2151
  description: z2.string().exactOptional(),
2155
- /** Per-agent configuration with scope (e.g., [{ name: "web-developer", scope: "project" }]) */
2156
2152
  agents: z2.array(
2157
2153
  z2.object({
2158
2154
  name: z2.string(),
2159
2155
  scope: z2.enum(["project", "global"]),
2160
- /** Per-agent overrides of the agent's own metadata defaults */
2161
2156
  model: modelNameSchema.exactOptional(),
2157
+ codexModel: codexModelNameSchema.exactOptional(),
2162
2158
  effort: effortLevelSchema.exactOptional(),
2163
2159
  excluded: z2.boolean().exactOptional()
2164
2160
  })
2165
2161
  ).exactOptional(),
2166
- /** Per-skill configuration with scope and provenance */
2167
2162
  skills: z2.array(
2168
2163
  z2.object({
2169
2164
  id: z2.string(),
@@ -2172,19 +2167,15 @@ var projectConfigFields = z2.object({
2172
2167
  excluded: z2.boolean().exactOptional()
2173
2168
  })
2174
2169
  ).exactOptional(),
2175
- /** Author handle (e.g., "@vince") */
2176
2170
  author: z2.string().exactOptional(),
2177
- /** Selected domains from the wizard (persisted for edit mode restoration) */
2178
2171
  selectedDomains: z2.array(z2.string()).exactOptional(),
2179
- /** Agent-to-category-to-skill mappings from selected stack (accepts same formats as stacks.ts) */
2180
2172
  stack: z2.record(z2.string(), stackAgentConfigSchema).exactOptional(),
2181
- /** The marketplace this install reads skills from, as a path or URL (e.g., "github:my-org/skills") */
2173
+ /** A path or URL (e.g., "github:my-org/skills") */
2182
2174
  marketplace: z2.string().exactOptional(),
2183
- /** The name that marketplace's manifest gives it, which plugins are registered under */
2175
+ /** The name the marketplace's manifest gives it, which plugins are registered under */
2184
2176
  marketplaceName: z2.string().exactOptional(),
2185
- /** Separate source for agents when different from skills source */
2186
2177
  agentsSource: z2.string().exactOptional(),
2187
- /** Tracked project installation paths (global config only) */
2178
+ /** Global config only */
2188
2179
  projects: z2.array(z2.string()).exactOptional()
2189
2180
  }).passthrough();
2190
2181
  var projectConfigLoaderSchema = renamedFieldGuard.pipe(projectConfigFields);
@@ -2235,30 +2226,22 @@ var skillRulesFileSchema = z2.object({
2235
2226
  relationships: relationshipDefinitionsSchema.exactOptional()
2236
2227
  });
2237
2228
  var localRawMetadataSchema = z2.object({
2238
- /** Short name shown in the wizard grid (e.g., "my-custom-react") */
2239
2229
  displayName: z2.string(),
2240
- /** Kebab-case short key for alias resolution (e.g., "react") */
2241
2230
  slug: z2.string(),
2242
- /** One-line description for the wizard */
2243
2231
  cliDescription: z2.string().exactOptional(),
2244
- /** Category to place this skill in (e.g., "web-framework") */
2245
2232
  category: categoryPathSchema,
2246
- /** When an AI agent should invoke this skill */
2247
2233
  usageGuidance: z2.string().exactOptional(),
2248
- /** Domain this skill belongs to (e.g., "web", "api", "cli") */
2249
2234
  domain: z2.string(),
2250
2235
  /** True if this skill was created outside the CLI's built-in vocabulary */
2251
2236
  custom: z2.boolean().exactOptional()
2252
2237
  }).passthrough();
2253
2238
  var localSkillMetadataSchema = z2.object({
2254
2239
  forkedFrom: z2.object({
2255
- /** Original skill ID before forking — lenient (any string) since custom/extra-source skills have non-builtin IDs */
2240
+ /** Lenient: custom and extra-source skills have non-builtin IDs */
2256
2241
  skillId: z2.string(),
2257
2242
  /** SHA hash of the original content at fork time (for diff detection) */
2258
2243
  contentHash: z2.string(),
2259
- /** ISO date when the fork was created */
2260
2244
  date: z2.string(),
2261
- /** Source URL the skill was installed from (e.g., "github:agents-inc/skills") */
2262
2245
  source: z2.string().exactOptional(),
2263
2246
  /** Directory inside that repository, for a skill only its own bytes can install again */
2264
2247
  path: z2.string().exactOptional()
@@ -2268,9 +2251,7 @@ var stackSchema = z2.object({
2268
2251
  id: z2.string().min(1),
2269
2252
  name: z2.string().min(1),
2270
2253
  description: z2.string(),
2271
- /** Maps agent IDs to their category-to-skill assignments */
2272
2254
  agents: z2.record(z2.string(), stackAgentConfigSchema),
2273
- /** High-level philosophy guiding this stack's technology choices */
2274
2255
  philosophy: z2.string().exactOptional()
2275
2256
  });
2276
2257
  var stacksConfigSchema = z2.object({
@@ -2301,11 +2282,7 @@ var marketplaceMetadataSchema = z2.object({
2301
2282
  var MARKETPLACE_NAME_REFUSAL = "A marketplace name is kebab-case: lowercase letters, numbers and hyphens, starting with a letter (e.g. 'acme-skills'). Rename it in this manifest \u2014 Claude Code registers every plugin under it and accepts no other shape.";
2302
2283
  var marketplaceSchema = z2.object({
2303
2284
  $schema: z2.string().exactOptional(),
2304
- /**
2305
- * Kebab-case, because this name is the namespace Claude Code registers plugins under and the
2306
- * CLI piggybacks on what Claude Code accepts (owner ruling 2026-08-20). Held to the same rule
2307
- * `build marketplace` refuses to publish under, so what this CLI emits is what it can read back.
2308
- */
2285
+ /** Kebab-case: the namespace Claude Code registers plugins under (owner ruling 2026-08-20). */
2309
2286
  name: z2.string().min(1).regex(KEBAB_CASE_PATTERN, { message: MARKETPLACE_NAME_REFUSAL }),
2310
2287
  version: z2.string().min(1),
2311
2288
  description: z2.string().exactOptional(),
@@ -2319,28 +2296,22 @@ var sourceRevalidationSchema = z2.object({
2319
2296
  etag: z2.string().min(1).exactOptional()
2320
2297
  });
2321
2298
  var permissionConfigSchema = z2.object({
2322
- /** Tool names or patterns to explicitly allow */
2323
2299
  allow: z2.array(z2.string()).exactOptional(),
2324
- /** Tool names or patterns to explicitly deny */
2325
2300
  deny: z2.array(z2.string()).exactOptional()
2326
2301
  });
2327
2302
  var settingsFileSchema = z2.object({
2328
2303
  permissions: permissionConfigSchema.exactOptional()
2329
2304
  }).passthrough();
2330
2305
  var brandingConfigSchema = z2.object({
2331
- /** Custom CLI name (e.g., "Acme Dev Tools") */
2332
2306
  name: z2.string().exactOptional()
2333
2307
  });
2334
2308
  var projectSourceConfigFields = z2.object({
2335
- /** The marketplace this install reads skills from, as a path or URL */
2309
+ /** A path or URL */
2336
2310
  marketplace: z2.string().exactOptional(),
2337
- /** Author handle for this project's config */
2338
2311
  author: z2.string().exactOptional(),
2339
- /** The name that marketplace's manifest gives it, which plugins are registered under */
2312
+ /** The name the marketplace's manifest gives it, which plugins are registered under */
2340
2313
  marketplaceName: z2.string().exactOptional(),
2341
- /** Separate source for agent definitions (when different from skills) */
2342
2314
  agentsSource: z2.string().exactOptional(),
2343
- /** Branding overrides for white-labeling the CLI */
2344
2315
  branding: brandingConfigSchema.exactOptional(),
2345
2316
  /** Custom skills directory override (default: "src/skills") */
2346
2317
  skillsDir: z2.string().exactOptional(),
@@ -2406,36 +2377,23 @@ var skillFrontmatterValidationSchema = z2.object({
2406
2377
  "argument-hint": z2.string().exactOptional()
2407
2378
  }).strict();
2408
2379
  var forkedFromSchema = z2.object({
2409
- /** Original skill ID */
2410
2380
  skillId: z2.string(),
2411
- /** Version of the original at fork time */
2412
2381
  version: z2.number().int().min(1).exactOptional(),
2413
- /** Content hash of the original at fork time */
2414
2382
  contentHash: z2.string(),
2415
- /** Source URL or identifier */
2416
2383
  source: z2.string().exactOptional(),
2417
2384
  /** Directory inside that source, for a skill only its own bytes can install again */
2418
2385
  path: z2.string().exactOptional(),
2419
- /** ISO date of the fork */
2420
2386
  date: z2.string()
2421
2387
  });
2422
2388
  var CLI_DESCRIPTION_MAX_LENGTH = 60;
2423
2389
  var skillMetadataBaseSchema = z2.object({
2424
- /** Author handle — must start with @ (e.g., "@vince") */
2425
2390
  author: z2.string().regex(AUTHOR_HANDLE_PATTERN),
2426
- /** Short display name for the wizard grid (max 30 chars) */
2427
2391
  displayName: z2.string().min(1).max(30),
2428
- /** One-line description for the wizard (max 60 chars recommended; over-length is a validation warning) */
2429
2392
  cliDescription: z2.string().min(1).max(CLI_DESCRIPTION_MAX_LENGTH),
2430
- /** When an AI agent should invoke this skill (min 10 chars to ensure usefulness) */
2431
2393
  usageGuidance: z2.string().min(10),
2432
- /** 7-char hex SHA of skill content (for change detection) */
2433
2394
  contentHash: z2.string().regex(/^[a-f0-9]{7}$/).exactOptional(),
2434
- /** ISO date of last update */
2435
2395
  updated: z2.string().exactOptional(),
2436
- /** Provenance tracking when skill was forked from another */
2437
2396
  forkedFrom: forkedFromSchema.exactOptional(),
2438
- /** Domain assignment from metadata */
2439
2397
  domain: z2.string().exactOptional(),
2440
2398
  /** True if this skill was created outside the CLI's built-in vocabulary */
2441
2399
  custom: z2.boolean().exactOptional()
@@ -2445,7 +2403,6 @@ function unknownMetadataSlugRefusal(input) {
2445
2403
  return `${named} is not a slug the public catalogue carries. A published skill's slug is held to that catalogue unless the skill declares it is not from it \u2014 add '${METADATA_KEYS.CUSTOM}: true' beside it in this ${STANDARD_FILES.METADATA_YAML} and the slug is read as your marketplace's own, any kebab-case name. That declaration is how a skill outside the catalogue's vocabulary is carried; a skill the catalogue does carry names its catalogue slug and leaves it off.`;
2446
2404
  }
2447
2405
  var metadataValidationSchema = skillMetadataBaseSchema.extend({
2448
- /** Domain-prefixed category — must be a known built-in category */
2449
2406
  category: z2.enum(CATEGORIES),
2450
2407
  /**
2451
2408
  * Kebab-case short key — must be a known built-in slug, unless the file declares
@@ -2456,9 +2413,7 @@ var metadataValidationSchema = skillMetadataBaseSchema.extend({
2456
2413
  })
2457
2414
  }).strict();
2458
2415
  var customMetadataValidationSchema = skillMetadataBaseSchema.extend({
2459
- /** Any string category — custom skills may define their own categories */
2460
2416
  category: z2.string(),
2461
- /** Kebab-case short key for alias resolution, search, and relationship rules */
2462
2417
  slug: z2.string().regex(KEBAB_CASE_PATTERN).min(1).max(50)
2463
2418
  });
2464
2419
  var stackSkillAssignmentSchema = z2.object({
@@ -2467,45 +2422,31 @@ var stackSkillAssignmentSchema = z2.object({
2467
2422
  preloaded: z2.boolean().exactOptional()
2468
2423
  }).strict();
2469
2424
  var stackConfigValidationSchema = z2.object({
2470
- /** Unique stack identifier in kebab-case */
2471
2425
  id: z2.string().regex(KEBAB_CASE_PATTERN).exactOptional(),
2472
2426
  name: z2.string().min(1),
2473
2427
  version: z2.string(),
2474
2428
  author: z2.string().min(1),
2475
2429
  description: z2.string().exactOptional(),
2476
- /** ISO date when this stack was first created */
2477
2430
  created: z2.string().exactOptional(),
2478
- /** ISO date of last update */
2479
2431
  updated: z2.string().exactOptional(),
2480
- /** Primary framework this stack is designed for (e.g., "nextjs", "remix") */
2481
2432
  framework: z2.string().exactOptional(),
2482
- /** All skills used in this stack (flat list, at least one required) */
2483
2433
  skills: z2.array(stackSkillAssignmentSchema).min(1),
2484
- /** Agent IDs this stack compiles (at least one required) */
2485
2434
  agents: z2.array(z2.string().regex(KEBAB_CASE_PATTERN)).min(1),
2486
- /** Per-agent skill assignments: { agentId: { category: [skillAssignment] } } */
2487
2435
  agentSkills: z2.record(z2.string(), z2.record(z2.string(), z2.array(stackSkillAssignmentSchema))).exactOptional(),
2488
- /** High-level philosophy guiding technology choices */
2489
2436
  philosophy: z2.string().exactOptional(),
2490
- /** Guiding principles for agents using this stack */
2491
2437
  principles: z2.array(z2.string().min(1)).exactOptional(),
2492
2438
  tags: z2.array(z2.string().regex(KEBAB_CASE_PATTERN)).exactOptional(),
2493
- /** Per-skill overrides: alternative suggestions and lock status */
2494
2439
  overrides: z2.record(
2495
2440
  z2.string(),
2496
2441
  z2.object({
2497
- /** Suggested alternative skill IDs if this one is swapped */
2498
2442
  alternatives: z2.array(z2.string().min(1)).exactOptional(),
2499
- /** If true, this skill cannot be swapped by the user */
2500
2443
  locked: z2.boolean().exactOptional()
2501
2444
  }).strict()
2502
2445
  ).exactOptional(),
2503
- /** Community metrics for sorting/ranking */
2504
2446
  metrics: z2.object({
2505
2447
  upvotes: z2.number().int().min(0).exactOptional(),
2506
2448
  downloads: z2.number().int().min(0).exactOptional()
2507
2449
  }).strict().exactOptional(),
2508
- /** Lifecycle hooks triggered by file changes or commands */
2509
2450
  hooks: strictHooksRecordSchema.exactOptional()
2510
2451
  }).strict();
2511
2452
  function formatZodIssues(issues) {
@@ -2992,12 +2933,9 @@ function isLocalSource(source) {
2992
2933
  }
2993
2934
  return true;
2994
2935
  }
2995
- function isSameMarketplace(a, b, fromDir) {
2996
- if (isLocalSource(a) && isLocalSource(b)) {
2997
- return path5.resolve(fromDir, a) === path5.resolve(fromDir, b);
2998
- }
2999
- return a === b;
3000
- }
2936
+
2937
+ // src/cli/lib/compile-seat.ts
2938
+ seatDiagnostics({ warn, verbose });
3001
2939
 
3002
2940
  // ../compile/src/seed-to-config.ts
3003
2941
  import { groupBy, indexBy, omit as omit2, partition as partition2 } from "remeda";
@@ -3196,6 +3134,7 @@ var CANONICAL_AGENT_ENTRY_ORDER = [
3196
3134
  "name",
3197
3135
  "scope",
3198
3136
  "model",
3137
+ "codexModel",
3199
3138
  "effort",
3200
3139
  "excluded"
3201
3140
  ];
@@ -3329,7 +3268,6 @@ function generateProjectConfigWithGlobalImport(cleaned, globalImportPath) {
3329
3268
  const hasProjectDomains = selectedDomains.length > 0;
3330
3269
  const hasStack = stack != null && Object.keys(stack).length > 0;
3331
3270
  const typeImports = buildTypeImports({
3332
- // Always present, spread from global.
3333
3271
  hasSkills: true,
3334
3272
  hasAgents: true,
3335
3273
  hasStack,
@@ -3960,11 +3898,6 @@ var KNOWN_AGENTS = new Set(AGENT_NAMES);
3960
3898
  function sourceForSkill(skill) {
3961
3899
  return skill.availableSources?.find((s) => s.primary)?.name ?? DEFAULT_PUBLIC_SOURCE_NAME;
3962
3900
  }
3963
- function addToDomainSelections(selections, domain, category, skillId) {
3964
- const categorySelections = selections[domain] ??= {};
3965
- const skillList = categorySelections[category] ??= [];
3966
- if (!skillList.includes(skillId)) skillList.push(skillId);
3967
- }
3968
3901
  function addToAgentStack(stack, agent, category, assignment) {
3969
3902
  const agentStack = stack[agent] ??= {};
3970
3903
  const assignments = agentStack[category] ??= [];
@@ -3989,9 +3922,23 @@ function agentScopeConfig(name, entry) {
3989
3922
  name,
3990
3923
  scope: seedAgentScope(entry),
3991
3924
  ...entry?.model !== void 0 && { model: entry.model },
3925
+ ...offeredCodexModel(name, entry?.codexModel),
3992
3926
  ...entry?.effort !== void 0 && { effort: entry.effort }
3993
3927
  };
3994
3928
  }
3929
+ var OFFERED_CODEX_MODELS = new Set(CODEX_MODEL_NAMES);
3930
+ function isOfferedCodexModel(id) {
3931
+ return OFFERED_CODEX_MODELS.has(id);
3932
+ }
3933
+ function offeredCodexModel(agent, id) {
3934
+ if (id === void 0) return {};
3935
+ if (isOfferedCodexModel(id)) return { codexModel: id };
3936
+ diagnostics().warn(codexModelNotOfferedWarning(agent, id));
3937
+ return {};
3938
+ }
3939
+ function codexModelNotOfferedWarning(agent, id) {
3940
+ return `Sub-agent '${agent}' asks for Codex model '${id}', which this version of the CLI does not offer, so it runs on the session's model. Offered: ${inAnEnglishList(CODEX_MODEL_NAMES)}.`;
3941
+ }
3995
3942
  function unwritableAssignmentsError(assignments) {
3996
3943
  return [
3997
3944
  "This configuration cannot be installed: a project-scoped skill never reaches a sub-agent that rests at global scope, so these assignments have nowhere to be written:",
@@ -3999,8 +3946,8 @@ function unwritableAssignmentsError(assignments) {
3999
3946
  "Re-share it with each sub-agent above pinned to the project, or each skill above at global scope."
4000
3947
  ].join("\n");
4001
3948
  }
4002
- function seedToWizardResult(payload, catalog) {
4003
- const domainSelections = {};
3949
+ function seedToInstallSelection(payload, catalog) {
3950
+ const domains = /* @__PURE__ */ new Set();
4004
3951
  const assignedStack = {};
4005
3952
  const skills = [];
4006
3953
  const skippedSkillIds = [];
@@ -4017,11 +3964,10 @@ function seedToWizardResult(payload, catalog) {
4017
3964
  }
4018
3965
  const id = skillId;
4019
3966
  const category = skill.category;
4020
- addToDomainSelections(domainSelections, domain, category, id);
3967
+ domains.add(domain);
4021
3968
  skills.push({
4022
3969
  id,
4023
3970
  scope: entry.scope,
4024
- // "eject" is an origin in its own right; anything else names the marketplace it came from.
4025
3971
  origin: entry.install === "eject" ? EJECT_SOURCE : sourceForSkill(skill)
4026
3972
  });
4027
3973
  for (const [agentName, load] of Object.entries(entry.assignments)) {
@@ -4062,22 +4008,12 @@ function seedToWizardResult(payload, catalog) {
4062
4008
  ),
4063
4009
  assignedStack,
4064
4010
  selectedStackId: payload.stackId,
4065
- // Spread-conditional rather than passed through, because absent and present-holding-undefined
4066
- // are different files on disk: a config describing itself with no key is not one describing
4067
- // itself with an empty sentence, and the writer emits whichever key it is handed.
4011
+ // Absent and empty are different files on disk.
4068
4012
  ...payload.description !== void 0 && {
4069
4013
  description: payload.description
4070
4014
  },
4071
- domainSelections,
4072
- selectedDomains: orderDomains(typedKeys2(domainSelections)),
4073
- // Nothing was dropped from a *saved config* — the skipped ids came off the wire and are
4074
- // reported to the user directly, so there is no config removal to explain.
4075
- unresolvableSkillIds: [],
4076
- cancelled: false,
4077
- // Revalidated here rather than taken on trust from the app that built the payload. That app
4078
- // validated against ITS catalog; this one skips ids it does not know and carries its own
4079
- // relationship rules, so a configuration that was consistent where it was authored can
4080
- // arrive with a requirement genuinely unmet.
4015
+ selectedDomains: orderDomains([...domains]),
4016
+ // Revalidated: the payload was consistent against the authoring app's catalog, not this one.
4081
4017
  validation: validateSelection(
4082
4018
  skills.map((skill) => skill.id),
4083
4019
  catalog
@@ -4461,6 +4397,7 @@ export type AgentScopeConfig = {
4461
4397
  name: AgentName
4462
4398
  scope: 'project' | 'global'
4463
4399
  model?: ${formatLiteralUnion(MODEL_NAMES)}
4400
+ codexModel?: ${formatLiteralUnion(CODEX_MODEL_NAMES)}
4464
4401
  effort?: ${formatLiteralUnion(EFFORT_NAMES)}
4465
4402
  excluded?: boolean
4466
4403
  }
@@ -4495,7 +4432,7 @@ var PROJECT_CONFIG_INTERFACE_AFTER = `export interface ProjectConfig {
4495
4432
  /** Agents source path or URL (when agents come from a different source than skills) */
4496
4433
  agentsSource?: string
4497
4434
 
4498
- /** Selected domains from the wizard */
4435
+ /** Selected domains */
4499
4436
  selectedDomains?: Domain[]
4500
4437
 
4501
4438
  /** Branding overrides for white-labeling the CLI */
@@ -4612,9 +4549,8 @@ function renderStackProperty(category, skills, catalog) {
4612
4549
  function buildSkillsByCategory(skillIds, categories, catalog) {
4613
4550
  const categorySet = new Set(categories);
4614
4551
  const eligible = [...new Set(skillIds)].map((id) => ({ id, category: catalog.skills[id]?.category })).filter(
4615
- (entry) => entry.category !== void 0 && entry.category !== LOCAL_PSEUDO_CATEGORY && // Boundary cast: a catalogue skill's `category` is a Category, typed `string` on the
4616
- // narrow catalogue shape so the wire `Matrix` satisfies it too. The `has` below IS the
4617
- // runtime check the predicate rests on, so the cast only lets the probe be written.
4552
+ (entry) => entry.category !== void 0 && entry.category !== LOCAL_PSEUDO_CATEGORY && // Boundary cast: typed `string` on the narrow catalogue shape; the `has` is the runtime
4553
+ // check.
4618
4554
  categorySet.has(entry.category)
4619
4555
  );
4620
4556
  return new Map(
@@ -6123,11 +6059,10 @@ function assembleAgentConfig(agentName, definition, agentConfig, resolvedSkills)
6123
6059
  title: definition.title,
6124
6060
  description: definition.description,
6125
6061
  ...model !== void 0 && { model },
6062
+ ...agentConfig.codexModel !== void 0 && { codexModel: agentConfig.codexModel },
6126
6063
  ...effort !== void 0 && { effort },
6127
6064
  tools: definition.tools,
6128
- // Every optional frontmatter field `agent.liquid` reads. Spread conditionally rather
6129
- // than unconditionally, because the template branches on presence — an explicit
6130
- // `undefined` renders as an empty key.
6065
+ // Spread conditionally: the template branches on presence, and `undefined` renders a key.
6131
6066
  ...definition.disallowedTools !== void 0 && {
6132
6067
  disallowedTools: definition.disallowedTools
6133
6068
  },
@@ -6167,7 +6102,7 @@ function wereScopeCompatible(priorSkillScope, priorAgentScope) {
6167
6102
  return priorSkillScope !== void 0 && priorAgentScope !== void 0 && isScopePairCompatible(priorSkillScope, priorAgentScope);
6168
6103
  }
6169
6104
  function resolveStackProperty(generated, assigned) {
6170
- return generated && assigned ? assigned : generated;
6105
+ return generated === void 0 ? void 0 : assigned;
6171
6106
  }
6172
6107
  function resolveDescription(loadedStack, shared) {
6173
6108
  return loadedStack === null ? shared : loadedStack.description;
@@ -6182,22 +6117,22 @@ async function loadCuratedStack(projectDir, projectStack) {
6182
6117
  async function loadGlobalStack() {
6183
6118
  return (await loadInstalledConfig(os10.homedir()))?.config.stack;
6184
6119
  }
6185
- async function buildInstallConfig(wizardResult, sourceResult, projectDir) {
6186
- const skillIds = unique4(wizardResult.skills.map((s) => s.id));
6120
+ async function buildInstallConfig(selection, sourceResult, projectDir) {
6121
+ const skillIds = unique4(selection.skills.map((s) => s.id));
6187
6122
  verbose(
6188
- `buildInstallConfig: selectedStackId='${wizardResult.selectedStackId}', skills=[${skillIds.join(", ")}], selectedAgents=[${wizardResult.selectedAgents.join(", ")}]`
6123
+ `buildInstallConfig: selectedStackId='${selection.selectedStackId}', skills=[${skillIds.join(", ")}], selectedAgents=[${selection.selectedAgents.join(", ")}]`
6189
6124
  );
6190
- const loadedStack = await loadSelectedStack(wizardResult.selectedStackId, sourceResult);
6125
+ const loadedStack = await loadSelectedStack(selection.selectedStackId, sourceResult);
6191
6126
  const existing = await loadProjectConfig(projectDir);
6192
6127
  const existingStack = await loadCuratedStack(projectDir, existing?.config.stack);
6193
6128
  const options = generatorOptionsFor(
6194
- wizardResult,
6129
+ selection,
6195
6130
  existing?.config,
6196
6131
  stackToPreserve(loadedStack, existingStack)
6197
6132
  );
6198
6133
  const generated = generateProjectConfigFromSkills(configNameFor(projectDir), skillIds, options);
6199
- const stack = resolveStackProperty(generated.stack, wizardResult.assignedStack);
6200
- const description = resolveDescription(loadedStack, wizardResult.description);
6134
+ const stack = resolveStackProperty(generated.stack, selection.assignedStack);
6135
+ const description = resolveDescription(loadedStack, selection.description);
6201
6136
  const localConfig = {
6202
6137
  ...generated,
6203
6138
  ...stack && { stack },
@@ -6225,30 +6160,30 @@ function stackToPreserve(loadedStack, curatedStack) {
6225
6160
  if (loadedStack === null) return curatedStack;
6226
6161
  return { ...buildStackProperty(loadedStack), ...curatedStack };
6227
6162
  }
6228
- function generatorOptionsFor(wizardResult, persisted, existingStack) {
6163
+ function generatorOptionsFor(selection, persisted, existingStack) {
6229
6164
  return {
6230
- skillConfigs: wizardResult.skills,
6231
- agentConfigs: wizardResult.agentConfigs,
6165
+ skillConfigs: selection.skills,
6166
+ agentConfigs: selection.agentConfigs,
6232
6167
  existingStack,
6233
- newlyAddedSkillIds: computeNewlyAddedSkillIds(wizardResult.skills, persisted?.skills),
6168
+ newlyAddedSkillIds: computeNewlyAddedSkillIds(selection.skills, persisted?.skills),
6234
6169
  scopeEligibilityGained: computeScopeEligibilityGained(
6235
- wizardResult.skills,
6236
- wizardResult.agentConfigs,
6170
+ selection.skills,
6171
+ selection.agentConfigs,
6237
6172
  persisted?.skills,
6238
6173
  persisted?.agents
6239
6174
  ),
6240
- ...wizardResult.selectedAgents.length > 0 && {
6241
- selectedAgents: wizardResult.selectedAgents
6175
+ ...selection.selectedAgents.length > 0 && {
6176
+ selectedAgents: selection.selectedAgents
6242
6177
  }
6243
6178
  };
6244
6179
  }
6245
6180
  function stackSizeForLog(stack) {
6246
6181
  return stack ? `${Object.keys(stack).length} agents` : "UNDEFINED";
6247
6182
  }
6248
- function setConfigMetadata(config, wizardResult, sourceResult, sourceFlag) {
6183
+ function setConfigMetadata(config, selection, sourceResult, sourceFlag) {
6249
6184
  const result = { ...config };
6250
- if (wizardResult.selectedDomains.length > 0) {
6251
- result.selectedDomains = wizardResult.selectedDomains;
6185
+ if (selection.selectedDomains.length > 0) {
6186
+ result.selectedDomains = selection.selectedDomains;
6252
6187
  }
6253
6188
  if (sourceFlag) {
6254
6189
  result.marketplace = sourceFlag;
@@ -6260,10 +6195,10 @@ function setConfigMetadata(config, wizardResult, sourceResult, sourceFlag) {
6260
6195
  }
6261
6196
  return result;
6262
6197
  }
6263
- async function buildAndMergeConfig(wizardResult, sourceResult, projectDir, sourceFlag, authoritativeScope) {
6264
- const { config } = await buildInstallConfig(wizardResult, sourceResult, projectDir);
6198
+ async function buildAndMergeConfig(selection, sourceResult, projectDir, sourceFlag, authoritativeScope) {
6199
+ const { config } = await buildInstallConfig(selection, sourceResult, projectDir);
6265
6200
  verbose(`buildAndMergeConfig: before merge \u2014 stack=${stackSizeForLog(config.stack)}`);
6266
- const configWithMetadata = setConfigMetadata(config, wizardResult, sourceResult, sourceFlag);
6201
+ const configWithMetadata = setConfigMetadata(config, selection, sourceResult, sourceFlag);
6267
6202
  const result = await mergeWithExistingConfig(configWithMetadata, {
6268
6203
  projectDir,
6269
6204
  ...authoritativeScope !== void 0 && { authoritativeScope }
@@ -6292,6 +6227,7 @@ function buildCompileAgents(config, agents) {
6292
6227
  const buildAgentCompileEntry = (agentConfig) => {
6293
6228
  const tuning = {
6294
6229
  ...agentConfig.model !== void 0 && { model: agentConfig.model },
6230
+ ...agentConfig.codexModel !== void 0 && { codexModel: agentConfig.codexModel },
6295
6231
  ...agentConfig.effort !== void 0 && { effort: agentConfig.effort }
6296
6232
  };
6297
6233
  const agentStack = config.stack?.[agentConfig.name];
@@ -6996,7 +6932,7 @@ function hostAt(root) {
6996
6932
 
6997
6933
  // src/cli/lib/installation/mode-migrator.ts
6998
6934
  function ejectCopyFailureError(failedCount) {
6999
- return `Failed to copy ${failedCount} skill(s) for eject. Eject intent could not be honored. Check that the destination skills directory is writable, then run '${CLI_INVOKE_COMMAND} edit' again \u2014 or switch the affected skills back to plugin mode.`;
6935
+ return `Failed to copy ${failedCount} skill(s) for eject. Eject intent could not be honored. Check that the destination skills directory is writable, then apply the same id again with '${CLI_INVOKE_COMMAND} edit --from <id>' \u2014 or switch the affected skills back to plugin mode.`;
7000
6936
  }
7001
6937
  function detectMigrations(oldSkills, newSkills) {
7002
6938
  const oldById = new Map(oldSkills.map((s) => [s.id, s]));
@@ -7504,13 +7440,13 @@ async function loadSkillsOfPlugin({
7504
7440
  }
7505
7441
  }
7506
7442
  function mergeInPluginOrder(perPluginSkills) {
7507
- const allSkills2 = {};
7443
+ const allSkills = {};
7508
7444
  for (const pluginSkills of perPluginSkills) {
7509
7445
  for (const [id, skill] of typedEntries(pluginSkills)) {
7510
- if (skill) allSkills2[id] = skill;
7446
+ if (skill) allSkills[id] = skill;
7511
7447
  }
7512
7448
  }
7513
- return allSkills2;
7449
+ return allSkills;
7514
7450
  }
7515
7451
  async function listPluginNames(projectDir) {
7516
7452
  try {
@@ -7741,66 +7677,25 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
7741
7677
 
7742
7678
  // src/cli/lib/skills/unresolved-skill-entries.ts
7743
7679
  import path26 from "path";
7744
- async function findUnusableSavedSkillMetadata(unresolvedIds, savedSkills, projectDir) {
7745
- const classified = await classifyUnresolvedSkills(unresolvedIds, savedSkills, projectDir);
7746
- return classified.flatMap(({ fate }) => fate.kind === "unusable-metadata" ? [fate.detail] : []);
7747
- }
7748
- async function unresolvedSkillRemovalReasons(unresolvedIds, savedSkills, projectDir, sourceLabel) {
7749
- const classified = await classifyUnresolvedSkills(unresolvedIds, savedSkills, projectDir);
7750
- return new Map(
7751
- classified.flatMap(({ id, fate }) => {
7752
- const reason = removalReason(id, fate, sourceLabel);
7753
- return reason === null ? [] : [[id, reason]];
7754
- })
7680
+ async function findUnusableSavedSkillMetadata(savedSkills, projectDir) {
7681
+ const verdicts = await Promise.all(
7682
+ savedSkills.map((saved) => unusableMetadataOf(saved, projectDir))
7755
7683
  );
7684
+ return verdicts.filter((verdict) => verdict !== null);
7756
7685
  }
7757
- async function classifyUnresolvedSkills(unresolvedIds, savedSkills, projectDir) {
7758
- return Promise.all(
7759
- unresolvedIds.map(async (id) => {
7760
- const saved = savedSkills.find((entry) => entry.id === id);
7761
- return { id, fate: await classifySavedSkill(id, saved, projectDir) };
7762
- })
7763
- );
7764
- }
7765
- async function classifySavedSkill(id, saved, projectDir) {
7766
- if (saved?.origin !== EJECT_SOURCE) return { kind: "dropped-by-source" };
7767
- const skillDir = path26.join(resolveInstallPaths(projectDir, saved.scope).skillsDir, id);
7768
- if (!await directoryExists2(skillDir)) return { kind: "files-gone", skillDir };
7769
- const metadataPath = path26.join(skillDir, STANDARD_FILES.METADATA_YAML);
7770
- if (!await fileExists(metadataPath)) return { kind: "not-installed-there", skillDir };
7686
+ async function unusableMetadataOf(saved, projectDir) {
7687
+ if (!claimsLocalCopy(saved)) return null;
7688
+ const metadataPath = installedMetadataPath(saved, projectDir);
7689
+ if (!await fileExists(metadataPath)) return null;
7771
7690
  const read = await readSkillMetadata(metadataPath);
7772
- if (!read.usable) {
7773
- return {
7774
- kind: "unusable-metadata",
7775
- detail: { skillDirName: id, metadataPath, reason: read.reason }
7776
- };
7777
- }
7778
- if (!await skillMdNames(skillDir, id)) return { kind: "not-installed-there", skillDir };
7779
- return { kind: "unplaceable-category", skillDir, category: read.metadata.category };
7780
- }
7781
- async function skillMdNames(skillDir, id) {
7782
- const skillMdPath = path26.join(skillDir, STANDARD_FILES.SKILL_MD);
7783
- if (!await fileExists(skillMdPath)) return false;
7784
- const frontmatter = parseFrontmatter(await readFile(skillMdPath), skillMdPath);
7785
- return frontmatter?.name === id;
7786
- }
7787
- function removalReason(id, fate, sourceLabel) {
7788
- switch (fate.kind) {
7789
- case "dropped-by-source":
7790
- return `not present in ${sourceLabel}`;
7791
- case "files-gone":
7792
- return `skill files no longer exist at ${fate.skillDir}`;
7793
- case "not-installed-there":
7794
- return `no skill named '${id}' is installed at ${fate.skillDir}`;
7795
- case "unplaceable-category":
7796
- return `installed at ${fate.skillDir}, but its category '${fate.category}' is not one this source knows`;
7797
- case "unusable-metadata":
7798
- return null;
7799
- default: {
7800
- const exhaustive = fate;
7801
- return exhaustive;
7802
- }
7803
- }
7691
+ return read.usable ? null : { skillDirName: saved.id, metadataPath, reason: read.reason };
7692
+ }
7693
+ function claimsLocalCopy(saved) {
7694
+ return !saved.excluded && saved.origin === EJECT_SOURCE;
7695
+ }
7696
+ function installedMetadataPath(saved, projectDir) {
7697
+ const { skillsDir: skillsDir2 } = resolveInstallPaths(projectDir, saved.scope);
7698
+ return path26.join(skillsDir2, saved.id, STANDARD_FILES.METADATA_YAML);
7804
7699
  }
7805
7700
 
7806
7701
  // src/cli/lib/skills/local-skill-mover.ts
@@ -7859,10 +7754,6 @@ async function migrateLocalSkillScope(skillId, fromScope, projectDir) {
7859
7754
  }
7860
7755
  verbose(`Migrated skill '${skillId}' from ${fromScope} to ${toScope}`);
7861
7756
  }
7862
- async function foldLocalSkillIntoGlobal(projectDir, skillId) {
7863
- await deleteLocalSkill(projectDir, skillId, "global");
7864
- await migrateLocalSkillScope(skillId, "project", projectDir);
7865
- }
7866
7757
 
7867
7758
  // src/cli/lib/matrix/matrix-loader.ts
7868
7759
  import { parse as parseYaml5 } from "yaml";
@@ -8161,233 +8052,6 @@ function buildResolvedSkill(skill, _categories, relationships, slugMap) {
8161
8052
  };
8162
8053
  }
8163
8054
 
8164
- // src/cli/lib/matrix/matrix-resolver.ts
8165
- import { groupBy as groupBy4 } from "remeda";
8166
- function getLabel(skill) {
8167
- return stripTerminalControls(skill.displayName);
8168
- }
8169
- function joinWithConjunction(items, conjunction) {
8170
- if (items.length <= 1) return items[0] ?? "";
8171
- if (items.length === 2) return `${items[0]} ${conjunction} ${items[1]}`;
8172
- return `${items.slice(0, -1).join(", ")} ${conjunction} ${items[items.length - 1]}`;
8173
- }
8174
- function initializeSelectionContext(currentSelections) {
8175
- const resolvedSelections = currentSelections.map((s) => getSkillById(s).id);
8176
- const selectedSet = new Set(resolvedSelections);
8177
- return { resolvedSelections, selectedSet };
8178
- }
8179
- function toSelectionFacts(source) {
8180
- return {
8181
- skills: typedValues(source.skills).map((skill) => ({
8182
- id: skill.id,
8183
- categoryId: skill.category,
8184
- conflictsWith: skill.conflictsWith.map((relation) => relation.skillId),
8185
- discourages: skill.discourages.map((relation) => ({
8186
- skillId: relation.skillId,
8187
- // The one author string that leaves this module without being re-rendered: the shared
8188
- // semantics carry it through and `getCellState` hands the verdict back whole, so a
8189
- // discouraged cell prints exactly what was put in here. Made inert on the way in, which
8190
- // is the only point on that route this package owns.
8191
- reason: stripTerminalControls(relation.reason)
8192
- })),
8193
- requires: skill.requires.map((requirement) => ({
8194
- skillIds: requirement.skillIds,
8195
- needsAny: requirement.needsAny
8196
- }))
8197
- })),
8198
- exclusiveCategoryIds: new Set(
8199
- typedValues(source.categories).filter((category) => category.exclusive !== false).map((category) => category.id)
8200
- )
8201
- };
8202
- }
8203
- var boundSemantics;
8204
- var boundTo;
8205
- function judgeSelections(resolvedSelections) {
8206
- if (!boundSemantics || boundTo !== matrix) {
8207
- boundSemantics = createSelectionSemantics(toSelectionFacts(matrix));
8208
- boundTo = matrix;
8209
- }
8210
- return boundSemantics(resolvedSelections);
8211
- }
8212
- function renderIncompatibility(cause) {
8213
- switch (cause.kind) {
8214
- case "conflict":
8215
- return `conflicts with ${labelOf(cause.skillId)}`;
8216
- case "unreachableRequirement": {
8217
- if (cause.requirement.needsAny) {
8218
- const labels = cause.requirement.skillIds.map(labelOf);
8219
- return `requires ${joinWithConjunction(labels, "or")} (all conflict with current selection)`;
8220
- }
8221
- const lostLabels = cause.lostIds.map(labelOf);
8222
- return `requires ${joinWithConjunction(lostLabels, "and")} which conflicts with current selection`;
8223
- }
8224
- }
8225
- }
8226
- function labelOf(skillId) {
8227
- return getLabel(getSkillById(skillId));
8228
- }
8229
- function isRequirementMet(req, selectedSet) {
8230
- return req.needsAny ? req.skillIds.some((id) => selectedSet.has(id)) : req.skillIds.every((id) => selectedSet.has(id));
8231
- }
8232
- function missingRequirementIds(req, selectedSet) {
8233
- if (isRequirementMet(req, selectedSet)) return [];
8234
- return req.needsAny ? [...req.skillIds] : req.skillIds.filter((id) => !selectedSet.has(id));
8235
- }
8236
- function getUnmetRequiredBy(skillId, currentSelections) {
8237
- getSkillById(skillId);
8238
- const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);
8239
- if (selectedSet.has(skillId)) return void 0;
8240
- for (const selectedId of resolvedSelections) {
8241
- const selectedSkill = matrix.skills[selectedId];
8242
- if (!selectedSkill) continue;
8243
- for (const req of selectedSkill.requires) {
8244
- if (!req.skillIds.includes(skillId)) continue;
8245
- if (req.needsAny) {
8246
- if (!req.skillIds.some((id) => selectedSet.has(id))) {
8247
- return getLabel(selectedSkill);
8248
- }
8249
- } else {
8250
- return getLabel(selectedSkill);
8251
- }
8252
- }
8253
- }
8254
- return void 0;
8255
- }
8256
- function hasUnmetRequirements(skillId, currentSelections) {
8257
- return getUnmetRequirementsReason(skillId, currentSelections) !== void 0;
8258
- }
8259
- function getCellState(skillId, currentSelections) {
8260
- const skill = getSkillById(skillId);
8261
- const { resolvedSelections } = initializeSelectionContext(currentSelections);
8262
- const verdict = judgeSelections(resolvedSelections).verdictOf(skill.id);
8263
- return verdict.status === "incompatible" ? { status: "incompatible", reason: renderIncompatibility(verdict.cause) } : verdict;
8264
- }
8265
- function getUnmetRequirementsReason(skillId, currentSelections) {
8266
- const skill = getSkillById(skillId);
8267
- const { selectedSet } = initializeSelectionContext(currentSelections);
8268
- for (const requirement of skill.requires) {
8269
- const missing = missingRequirementIds(requirement, selectedSet);
8270
- if (missing.length === 0) continue;
8271
- const names = missing.map((id) => {
8272
- const s = matrix.skills[id];
8273
- return s ? getLabel(s) : stripTerminalControls(id);
8274
- });
8275
- return withAuthorsReason(namesTheMissing(names, requirement.needsAny), requirement.reason);
8276
- }
8277
- return void 0;
8278
- }
8279
- function namesTheMissing(names, needsAny) {
8280
- return `requires ${joinWithConjunction(names, needsAny ? "or" : "and")}`;
8281
- }
8282
- var REASON_BUDGET = 60;
8283
- function withAuthorsReason(synthesised, reason) {
8284
- const stated = reason.trim();
8285
- if (stated === "") return synthesised;
8286
- return `${synthesised} \u2014 ${truncateText(stated, REASON_BUDGET)}`;
8287
- }
8288
- function unmetRequirementsReasonFor(isSelected, skillId, currentSelections) {
8289
- if (!isSelected) return {};
8290
- const reason = getUnmetRequirementsReason(skillId, currentSelections);
8291
- return reason === void 0 ? {} : { unmetRequirementsReason: reason };
8292
- }
8293
- function validateConflicts(resolvedSelections) {
8294
- const errors = [];
8295
- for (const [index, skillAId] of resolvedSelections.entries()) {
8296
- const skillA = matrix.skills[skillAId];
8297
- if (!skillA) continue;
8298
- for (const skillBId of resolvedSelections.slice(index + 1)) {
8299
- const conflict = skillA.conflictsWith.find((c) => c.skillId === skillBId);
8300
- if (conflict) {
8301
- errors.push({
8302
- type: "conflict",
8303
- // The author's own sentence, made inert but not shortened: this message is reported on
8304
- // its own line rather than into a fixed-height cell, so it needs no budget the way
8305
- // `withAuthorsReason` does — only the guarantee that a terminal will print it.
8306
- message: `${getLabel(skillA)} conflicts with ${getLabel(getSkillById(skillBId))}: ${stripTerminalControls(conflict.reason)}`,
8307
- skills: [skillA.id, skillBId]
8308
- });
8309
- }
8310
- }
8311
- }
8312
- return errors;
8313
- }
8314
- function validateRequirements(resolvedSelections, selectedSet) {
8315
- const errors = [];
8316
- for (const skillId of resolvedSelections) {
8317
- const skill = matrix.skills[skillId];
8318
- if (!skill) continue;
8319
- for (const requirement of skill.requires) {
8320
- if (requirement.needsAny) {
8321
- const hasAny = requirement.skillIds.some((reqId) => selectedSet.has(reqId));
8322
- if (!hasAny) {
8323
- errors.push({
8324
- type: "missingRequirement",
8325
- message: `${getLabel(skill)} requires one of: ${requirement.skillIds.map((id) => getLabel(getSkillById(id))).join(", ")}`,
8326
- skills: [skillId, ...requirement.skillIds]
8327
- });
8328
- }
8329
- } else {
8330
- const missingIds = requirement.skillIds.filter((reqId) => !selectedSet.has(reqId));
8331
- if (missingIds.length > 0) {
8332
- errors.push({
8333
- type: "missingRequirement",
8334
- message: `${getLabel(skill)} requires: ${missingIds.map((id) => getLabel(getSkillById(id))).join(", ")}`,
8335
- skills: [skillId, ...missingIds]
8336
- });
8337
- }
8338
- }
8339
- }
8340
- }
8341
- return errors;
8342
- }
8343
- function validateExclusivity(resolvedSelections) {
8344
- const errors = [];
8345
- const validSkills = resolvedSelections.map((skillId) => ({ skillId, skill: matrix.skills[skillId] })).filter((entry) => entry.skill != null);
8346
- const categorySelections = groupBy4(validSkills, (entry) => entry.skill.category);
8347
- for (const [categoryId, entries] of typedEntries(categorySelections)) {
8348
- if (entries.length > 1) {
8349
- const skillIds = entries.map((e) => e.skillId);
8350
- if (categoryId === LOCAL_PSEUDO_CATEGORY) continue;
8351
- const category = matrix.categories[categoryId];
8352
- if (category?.exclusive) {
8353
- errors.push({
8354
- type: "categoryExclusive",
8355
- message: `Category "${stripTerminalControls(category.displayName)}" only allows one selection, but multiple selected: ${skillIds.map((id) => getLabel(getSkillById(id))).join(", ")}`,
8356
- skills: skillIds
8357
- });
8358
- }
8359
- }
8360
- }
8361
- return errors;
8362
- }
8363
- function validateSelection2(selections) {
8364
- const { resolvedSelections, selectedSet } = initializeSelectionContext(selections);
8365
- const errors = [
8366
- ...validateConflicts(resolvedSelections),
8367
- ...validateRequirements(resolvedSelections, selectedSet),
8368
- ...validateExclusivity(resolvedSelections)
8369
- ];
8370
- return {
8371
- valid: errors.length === 0,
8372
- errors
8373
- };
8374
- }
8375
- function getAvailableSkills(categoryId, currentSelections) {
8376
- const { selectedSet } = initializeSelectionContext(currentSelections);
8377
- return getSkillsByCategory(categoryId).map((skill) => {
8378
- const isSelected = selectedSet.has(skill.id);
8379
- return {
8380
- id: skill.id,
8381
- selected: isSelected,
8382
- hasUnmetRequirements: isSelected && hasUnmetRequirements(skill.id, currentSelections),
8383
- ...unmetRequirementsReasonFor(isSelected, skill.id, currentSelections)
8384
- };
8385
- });
8386
- }
8387
- function getSkillsByCategory(categoryId) {
8388
- return allSkills().filter((skill) => skill.category === categoryId);
8389
- }
8390
-
8391
8055
  // src/cli/lib/configuration/skill-audit.ts
8392
8056
  var skillAudit = {
8393
8057
  // ── B1 — web core: frameworks, meta-frameworks, routing, server state (20) ──
@@ -9930,7 +9594,7 @@ var skillAudit = {
9930
9594
  batch: "shared-meta",
9931
9595
  classification: { class: "B", frameworks: ["react"] },
9932
9596
  sources: [
9933
- 'skill body self-scope (description "Use when reviewing React components"; When-to-use ".tsx/.jsx with JSX"; "React PR review" auto-detection) plus a React-keyed majority (4 of 5 MUSTs, 6 of 7 patterns)'
9597
+ 'skill body self-scope (description "Load when reviewing a diff that adds or changes React components or hooks"; Applies-to "Diffs that add or change React components or custom hooks"; "React PR review" auto-detection) plus a React-keyed majority (4 of 5 critical requirements, 6 of 7 patterns)'
9934
9598
  ]
9935
9599
  },
9936
9600
  "meta-reviewing-api-reviewing": {
@@ -9961,8 +9625,8 @@ var skillAudit = {
9961
9625
  var auditVerdictsPendingApply = {};
9962
9626
 
9963
9627
  // src/cli/lib/matrix/matrix-health-check.ts
9964
- function checkMatrixHealth(matrix2) {
9965
- const issues = [
9628
+ function matrixHealthIssues(matrix2) {
9629
+ return [
9966
9630
  ...checkCategoryDomains(matrix2),
9967
9631
  ...checkSkillCategories(matrix2),
9968
9632
  ...checkSkillRelationRefs(matrix2),
@@ -9970,6 +9634,9 @@ function checkMatrixHealth(matrix2) {
9970
9634
  ...checkAuditVerdictContradictions(matrix2),
9971
9635
  ...checkUnauditedSkills(matrix2)
9972
9636
  ];
9637
+ }
9638
+ function checkMatrixHealth(matrix2) {
9639
+ const issues = matrixHealthIssues(matrix2);
9973
9640
  for (const issue of issues) {
9974
9641
  warn(`[matrix] ${issue.details}`);
9975
9642
  }
@@ -9979,7 +9646,7 @@ function checkCategoryDomains(matrix2) {
9979
9646
  return typedEntries(matrix2.categories).filter(([, cat]) => cat !== void 0 && !cat.domain).map(([catId]) => ({
9980
9647
  severity: "warning",
9981
9648
  finding: "category-missing-domain",
9982
- details: `Category '${catId}' has no domain \u2014 it won't appear in any wizard domain view`
9649
+ details: `Category '${catId}' has no domain \u2014 it won't appear under any domain`
9983
9650
  }));
9984
9651
  }
9985
9652
  function checkSkillCategories(matrix2) {
@@ -10064,7 +9731,10 @@ function checkUnauditedSkills(matrix2) {
10064
9731
  }
10065
9732
 
10066
9733
  // src/cli/lib/loading/source-loader.ts
10067
- async function loadSkillsMatrixFromSource(options = {}) {
9734
+ function loadSkillsMatrixFromSource(options = {}) {
9735
+ return sayingEachWarningOnce(() => loadCatalogue(options));
9736
+ }
9737
+ async function loadCatalogue(options) {
10068
9738
  const {
10069
9739
  purpose = "fetch",
10070
9740
  caller = "stored",
@@ -10307,12 +9977,6 @@ async function loadAndMergeFromBasePath(basePath, source) {
10307
9977
  initializeMatrix(mergedMatrix);
10308
9978
  const stacks = await resolveOfferedStacks(basePath, stacksRelFile, source);
10309
9979
  mergedMatrix.suggestedStacks = stacks.map((stack) => convertStackToResolvedStack(stack));
10310
- const agentDefinedDomains = domainsDeclaredBy(await loadAllAgents(basePath));
10311
- const domainCount = typedKeys(agentDefinedDomains).length;
10312
- if (domainCount > 0) {
10313
- mergedMatrix.agentDefinedDomains = agentDefinedDomains;
10314
- verbose(`Loaded ${domainCount} agent domain definition(s)`);
10315
- }
10316
9980
  return mergedMatrix;
10317
9981
  }
10318
9982
  async function loadSourceTaxonomy(basePath) {
@@ -10338,13 +10002,6 @@ async function loadSourceTaxonomy(basePath) {
10338
10002
  }
10339
10003
  return { categories, sourceRules };
10340
10004
  }
10341
- function domainsDeclaredBy(agents) {
10342
- return typedFromEntries(
10343
- typedEntries(agents).flatMap(
10344
- ([agentId, agentDef]) => agentDef.domain ? [[agentId, agentDef.domain]] : []
10345
- )
10346
- );
10347
- }
10348
10005
  var CATALOGUE_SKILL_IDS = new Set(typedKeys(BUILT_IN_MATRIX.skills));
10349
10006
  var MAX_REPORTED_COLLISIONS = 10;
10350
10007
  async function refuseCatalogueCollisions(basePath, source, skills) {
@@ -10498,7 +10155,6 @@ export {
10498
10155
  stripTerminalControls,
10499
10156
  truncateText,
10500
10157
  plural,
10501
- toTitleCase,
10502
10158
  getErrorMessage,
10503
10159
  setVerbose,
10504
10160
  verbose,
@@ -10507,6 +10163,7 @@ export {
10507
10163
  drainBuffer,
10508
10164
  disableBuffering,
10509
10165
  warn,
10166
+ sayingEachWarningOnce,
10510
10167
  renderAgentRoleToml,
10511
10168
  agentsLeftOutOfCodexMessage,
10512
10169
  unexpressibleOnCodexMessage,
@@ -10565,6 +10222,7 @@ export {
10565
10222
  skillMetadataUnusableDetail,
10566
10223
  skillMetadataUnusableError,
10567
10224
  savedSkillMetadataUnusableError,
10225
+ editorSkillMetadataUnusableError,
10568
10226
  sharedConfigDestinations,
10569
10227
  applySharedConfigHere,
10570
10228
  shareRefusesEjectedSkills,
@@ -10579,12 +10237,11 @@ export {
10579
10237
  projectCopyRemoved,
10580
10238
  sharedConfigNeedsTerminal,
10581
10239
  nothingInstalledToApplyTo,
10582
- wizardNeedsTerminal,
10583
10240
  uninstallNeedsTerminal,
10584
- editorLoadsItsOwnMarketplace,
10585
- marketplaceFixedAtInstall,
10241
+ addMarketplaceInTheEditor,
10586
10242
  SHARED_CONFIG_ARRIVALS,
10587
10243
  keptAsInstalledGlobally,
10244
+ addedToGlobalSubAgents,
10588
10245
  authoredHereKept,
10589
10246
  unplaceableKept,
10590
10247
  keptUnassigned,
@@ -10618,7 +10275,6 @@ export {
10618
10275
  copy,
10619
10276
  formatZodErrors,
10620
10277
  isRecord,
10621
- isDomain,
10622
10278
  isAgentName,
10623
10279
  skillCategoriesFileSchema,
10624
10280
  skillRulesFileSchema,
@@ -10644,7 +10300,6 @@ export {
10644
10300
  resolveBranding,
10645
10301
  resolvePrimarySourceEntry,
10646
10302
  isLocalSource,
10647
- isSameMarketplace,
10648
10303
  normalizeStackRecord,
10649
10304
  defaultUsageGuidance,
10650
10305
  resolveAgentConfigToSkills,
@@ -10671,7 +10326,7 @@ export {
10671
10326
  typedEntries2 as typedEntries,
10672
10327
  isScopePairCompatible,
10673
10328
  splitConfigByScope,
10674
- seedToWizardResult,
10329
+ seedToInstallSelection,
10675
10330
  mergeConfigs,
10676
10331
  generateConfigTypesSource,
10677
10332
  deriveCategories,
@@ -10727,16 +10382,10 @@ export {
10727
10382
  printCompilationSummary,
10728
10383
  discoverLocalSkills,
10729
10384
  findUnusableSavedSkillMetadata,
10730
- unresolvedSkillRemovalReasons,
10731
10385
  deleteLocalSkill,
10732
10386
  migrateLocalSkillScope,
10733
- foldLocalSkillIntoGlobal,
10734
10387
  claimSlug,
10735
- getUnmetRequiredBy,
10736
- getCellState,
10737
- validateSelection2 as validateSelection,
10738
- getAvailableSkills,
10739
- checkMatrixHealth,
10388
+ matrixHealthIssues,
10740
10389
  generateMarketplace,
10741
10390
  validateMarketplaceName,
10742
10391
  validateSkillIdNamespace,
@@ -10762,4 +10411,4 @@ export {
10762
10411
  detectMigrations,
10763
10412
  executeMigration
10764
10413
  };
10765
- //# sourceMappingURL=chunk-A4KDXNOT.js.map
10414
+ //# sourceMappingURL=chunk-MQ6CGZNJ.js.map