agents-inc 0.164.0 → 0.165.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 +48 -0
  2. package/README.md +8 -9
  3. package/dist/{chunk-B6FSLXYN.js → chunk-42TNV2TK.js} +3 -3
  4. package/dist/chunk-4AAOOAIN.js +49 -0
  5. package/dist/chunk-4AAOOAIN.js.map +1 -0
  6. package/dist/{chunk-NQXO4LR3.js → chunk-4C7GL4F7.js} +16 -11
  7. package/dist/chunk-4C7GL4F7.js.map +1 -0
  8. package/dist/{chunk-Q4IRRVXK.js → chunk-57KU6SPH.js} +3 -3
  9. package/dist/{chunk-S63LXWMC.js → chunk-5M3PQNXI.js} +2 -2
  10. package/dist/{chunk-3WVH2CTK.js → chunk-5P26XBZO.js} +15 -8
  11. package/dist/chunk-5P26XBZO.js.map +1 -0
  12. package/dist/{chunk-G2JJ5BO5.js → chunk-6AIZPSEI.js} +337 -140
  13. package/dist/chunk-6AIZPSEI.js.map +1 -0
  14. package/dist/{chunk-NKGYKOB7.js → chunk-6CY6PW5X.js} +7 -8
  15. package/dist/chunk-6CY6PW5X.js.map +1 -0
  16. package/dist/{chunk-XHPWTL4I.js → chunk-6SW6SB7H.js} +3 -3
  17. package/dist/chunk-AAWZED5M.js +980 -0
  18. package/dist/chunk-AAWZED5M.js.map +1 -0
  19. package/dist/{chunk-UITEKY2R.js → chunk-AQXKAPCD.js} +30 -4
  20. package/dist/chunk-AQXKAPCD.js.map +1 -0
  21. package/dist/{chunk-X4SSJZLY.js → chunk-B5UUHBAM.js} +12 -261
  22. package/dist/chunk-B5UUHBAM.js.map +1 -0
  23. package/dist/{chunk-ARYNOWKF.js → chunk-BGU25XAY.js} +8 -8
  24. package/dist/{chunk-QGUP3QJF.js → chunk-CBMAO6OP.js} +22 -18
  25. package/dist/{chunk-QGUP3QJF.js.map → chunk-CBMAO6OP.js.map} +1 -1
  26. package/dist/{chunk-YRS3QZP2.js → chunk-CEBDGZID.js} +3 -3
  27. package/dist/{chunk-ABAZMMG4.js → chunk-CK5RM3DJ.js} +2 -2
  28. package/dist/{chunk-PHCPUQVR.js → chunk-CTUJO23Z.js} +2 -2
  29. package/dist/{chunk-QZX7SYKU.js → chunk-E6CHHXGY.js} +2 -2
  30. package/dist/{chunk-ZVXGW2IC.js → chunk-F2ZWFWTP.js} +4 -6
  31. package/dist/chunk-F2ZWFWTP.js.map +1 -0
  32. package/dist/{chunk-AVK2HEKB.js → chunk-GKPW33FP.js} +2 -6
  33. package/dist/{chunk-AVK2HEKB.js.map → chunk-GKPW33FP.js.map} +1 -1
  34. package/dist/{chunk-ECURHW3T.js → chunk-HR4YDSJK.js} +13 -12
  35. package/dist/chunk-HR4YDSJK.js.map +1 -0
  36. package/dist/{chunk-XPDVAJDH.js → chunk-IM45LLQX.js} +3599 -1558
  37. package/dist/chunk-IM45LLQX.js.map +1 -0
  38. package/dist/chunk-IVNKU4DM.js +39 -0
  39. package/dist/chunk-IVNKU4DM.js.map +1 -0
  40. package/dist/{chunk-XVAQG2CV.js → chunk-JOEA52NR.js} +10 -8
  41. package/dist/chunk-JOEA52NR.js.map +1 -0
  42. package/dist/{chunk-RGYDFBCT.js → chunk-JV4TKXEN.js} +5 -5
  43. package/dist/{chunk-4VL3CEOS.js → chunk-LXXGZAD3.js} +3 -3
  44. package/dist/chunk-MBUGQI2M.js +73 -0
  45. package/dist/chunk-MBUGQI2M.js.map +1 -0
  46. package/dist/{chunk-URXIQE7I.js → chunk-MWDY76MT.js} +2 -2
  47. package/dist/{chunk-V5GLL2JB.js → chunk-P3KJCYSR.js} +7 -7
  48. package/dist/{chunk-6MV4JOCL.js → chunk-PSX7CT6V.js} +2 -2
  49. package/dist/{chunk-B3Y3QMWI.js → chunk-TRTVOVHR.js} +4 -4
  50. package/dist/{chunk-AOTCIUGX.js → chunk-TV5Y53R2.js} +2 -2
  51. package/dist/{chunk-K5ITEA3I.js → chunk-UBSSIIWD.js} +34 -17
  52. package/dist/chunk-UBSSIIWD.js.map +1 -0
  53. package/dist/chunk-UCORXS4D.js +250 -0
  54. package/dist/chunk-UCORXS4D.js.map +1 -0
  55. package/dist/chunk-UR3RRTPO.js +159 -0
  56. package/dist/chunk-UR3RRTPO.js.map +1 -0
  57. package/dist/chunk-V5CWACR5.js +375 -0
  58. package/dist/chunk-V5CWACR5.js.map +1 -0
  59. package/dist/{chunk-LT5GXEB2.js → chunk-VPJUCVU7.js} +8 -7
  60. package/dist/chunk-VPJUCVU7.js.map +1 -0
  61. package/dist/chunk-VRXX4D6K.js +31 -0
  62. package/dist/chunk-VRXX4D6K.js.map +1 -0
  63. package/dist/{chunk-2CQNPLVF.js → chunk-WIFIAQZU.js} +63 -42
  64. package/dist/chunk-WIFIAQZU.js.map +1 -0
  65. package/dist/chunk-WSGX4IWC.js +356 -0
  66. package/dist/chunk-WSGX4IWC.js.map +1 -0
  67. package/dist/{chunk-X37UYIE3.js → chunk-WTANOSXK.js} +436 -739
  68. package/dist/chunk-WTANOSXK.js.map +1 -0
  69. package/dist/{chunk-XATLUKXK.js → chunk-X2KUI7V3.js} +6 -6
  70. package/dist/{chunk-NTF4UXGK.js → chunk-XATIKM3P.js} +73 -30
  71. package/dist/chunk-XATIKM3P.js.map +1 -0
  72. package/dist/{chunk-J27W6TXS.js → chunk-XQHZPINL.js} +8 -4
  73. package/dist/chunk-XQHZPINL.js.map +1 -0
  74. package/dist/{chunk-DSL66I4N.js → chunk-Y5SNGMB7.js} +6 -6
  75. package/dist/{chunk-7REKOTKG.js → chunk-YNOOZFIB.js} +3 -3
  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 +106 -27
  81. package/dist/commands/compile.js.map +1 -1
  82. package/dist/commands/doctor.js +427 -192
  83. package/dist/commands/doctor.js.map +1 -1
  84. package/dist/commands/edit.js +504 -314
  85. package/dist/commands/edit.js.map +1 -1
  86. package/dist/commands/eject.js +41 -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 +103 -15
  96. package/dist/commands/share.js.map +1 -1
  97. package/dist/commands/uninstall.js +264 -106
  98. package/dist/commands/uninstall.js.map +1 -1
  99. package/dist/commands/update.js +50 -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 +59 -43
  124. package/dist/hooks/init.js.map +1 -1
  125. package/dist/load-agent-defs-JHLE6MAE.js +14 -0
  126. package/dist/recompile-project-agents-ZPP5NOLZ.js +18 -0
  127. package/dist/{source-loader-GRBVNRAW.js → source-loader-RWZAYJ7E.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-B6FSLXYN.js.map → chunk-42TNV2TK.js.map} +0 -0
  171. /package/dist/{chunk-Q4IRRVXK.js.map → chunk-57KU6SPH.js.map} +0 -0
  172. /package/dist/{chunk-S63LXWMC.js.map → chunk-5M3PQNXI.js.map} +0 -0
  173. /package/dist/{chunk-XHPWTL4I.js.map → chunk-6SW6SB7H.js.map} +0 -0
  174. /package/dist/{chunk-ARYNOWKF.js.map → chunk-BGU25XAY.js.map} +0 -0
  175. /package/dist/{chunk-YRS3QZP2.js.map → chunk-CEBDGZID.js.map} +0 -0
  176. /package/dist/{chunk-ABAZMMG4.js.map → chunk-CK5RM3DJ.js.map} +0 -0
  177. /package/dist/{chunk-PHCPUQVR.js.map → chunk-CTUJO23Z.js.map} +0 -0
  178. /package/dist/{chunk-QZX7SYKU.js.map → chunk-E6CHHXGY.js.map} +0 -0
  179. /package/dist/{chunk-RGYDFBCT.js.map → chunk-JV4TKXEN.js.map} +0 -0
  180. /package/dist/{chunk-4VL3CEOS.js.map → chunk-LXXGZAD3.js.map} +0 -0
  181. /package/dist/{chunk-URXIQE7I.js.map → chunk-MWDY76MT.js.map} +0 -0
  182. /package/dist/{chunk-V5GLL2JB.js.map → chunk-P3KJCYSR.js.map} +0 -0
  183. /package/dist/{chunk-6MV4JOCL.js.map → chunk-PSX7CT6V.js.map} +0 -0
  184. /package/dist/{chunk-B3Y3QMWI.js.map → chunk-TRTVOVHR.js.map} +0 -0
  185. /package/dist/{chunk-AOTCIUGX.js.map → chunk-TV5Y53R2.js.map} +0 -0
  186. /package/dist/{chunk-XATLUKXK.js.map → chunk-X2KUI7V3.js.map} +0 -0
  187. /package/dist/{chunk-DSL66I4N.js.map → chunk-Y5SNGMB7.js.map} +0 -0
  188. /package/dist/{chunk-7REKOTKG.js.map → chunk-YNOOZFIB.js.map} +0 -0
  189. /package/dist/{load-agent-defs-7IM3GBEQ.js.map → load-agent-defs-JHLE6MAE.js.map} +0 -0
  190. /package/dist/{recompile-project-agents-VR4NLGOU.js.map → recompile-project-agents-ZPP5NOLZ.js.map} +0 -0
  191. /package/dist/{source-loader-GRBVNRAW.js.map → source-loader-RWZAYJ7E.js.map} +0 -0
@@ -1,256 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- claimSlug,
4
- computeFileHash,
5
- defaultUsageGuidance,
6
- directoryExists,
7
- glob,
8
- injectForkedFromMetadata,
9
- readFile,
10
- readForkedFromMetadata,
11
- readLocalSkillMetadata,
12
- readSkillMetadata,
13
- resolveInstallPaths,
14
- truncateText,
15
- validateSkillPath,
16
- writeFile,
17
- writeMetadataYaml
18
- } from "./chunk-XPDVAJDH.js";
3
+ truncateText
4
+ } from "./chunk-IM45LLQX.js";
19
5
  import {
20
- BUILT_IN_MATRIX,
21
- getCategoryDomain,
22
- typedEntries,
23
- typedKeys
24
- } from "./chunk-AVK2HEKB.js";
25
- import {
26
- GITHUB_SOURCE,
27
- LOCAL_SKILLS_PATH,
28
- STANDARD_FILES,
29
- seedExternalSkillSchema,
30
6
  seedPayloadSchema
31
- } from "./chunk-UITEKY2R.js";
32
-
33
- // src/cli/lib/seed/external-skills.ts
34
- import path from "path";
35
- function pluginInstallError(ids) {
36
- return [
37
- "This configuration cannot be installed: these skills travel inside it, so no marketplace serves them and they cannot be installed as plugins:",
38
- ...ids.map((id) => ` ${id}`),
39
- "Re-share it with each skill above set to eject, which is the only way a carried skill installs."
40
- ].join("\n");
41
- }
42
- function selectedExternals(payload) {
43
- return typedEntries(payload.external ?? {}).flatMap(([id, skill]) => {
44
- const entry = payload.skills[id];
45
- return entry ? [{ id, skill, entry }] : [];
46
- });
47
- }
48
- function askedForAsPlugin(externals) {
49
- return externals.filter(({ entry }) => entry.install !== "eject").map(({ id }) => id);
50
- }
51
- function claimingACatalogueId(externals, matrix) {
52
- return externals.filter(({ id }) => heldByEitherCatalogue(id, matrix)).map(({ id }) => id);
53
- }
54
- var CATALOGUE_SKILL_IDS = new Set(typedKeys(BUILT_IN_MATRIX.skills));
55
- function heldByEitherCatalogue(id, matrix) {
56
- return heldByLoadedCatalogue(matrix.skills[id]) || CATALOGUE_SKILL_IDS.has(id);
57
- }
58
- function heldByLoadedCatalogue(incumbent) {
59
- return incumbent !== void 0 && incumbent.local !== true;
60
- }
61
- function catalogueIdCollisionError(ids) {
62
- return [
63
- "This configuration cannot be installed: these skills travel inside it under ids a catalogue already owns:",
64
- ...ids.map((id) => ` ${id}`),
65
- "A skill id is the directory the skill installs into, so each would be written over the catalogue's own copy of that skill. Re-share it with each skill above added again, which mints an id \u2014 'external-<category>-<name>' \u2014 that no catalogue owns."
66
- ].join("\n");
67
- }
68
- function externalSlug(id) {
69
- return id;
70
- }
71
- function skillAuthor(repo) {
72
- const [owner = repo] = repo.split("/");
73
- return `@${owner}`;
74
- }
75
- function repoRef(repo) {
76
- return `${GITHUB_SOURCE.GITHUB_PREFIX}${repo}`;
77
- }
78
- function externalSkillDir(id, scope, projectDir) {
79
- return path.join(resolveInstallPaths(projectDir, scope).skillsDir, id);
80
- }
81
- function externalCatalogueEntry(install) {
82
- return {
83
- id: install.id,
84
- slug: externalSlug(install.id),
85
- displayName: install.skill.displayName,
86
- description: install.skill.description,
87
- // Boundary cast held by the guard above it: the category was confirmed against the catalogue
88
- // the payload names, and this one has just been shown to declare it too.
89
- category: install.skill.categoryId,
90
- author: skillAuthor(install.skill.repo),
91
- path: `${LOCAL_SKILLS_PATH}/${install.id}/`,
92
- conflictsWith: [],
93
- requires: [],
94
- alternatives: [],
95
- discourages: [],
96
- // Local and custom for the same reason: the bytes are on this machine and nowhere else, and
97
- // the skill was authored outside the vocabulary this catalogue ships.
98
- local: true,
99
- custom: true,
100
- localPath: install.skillDir
101
- };
102
- }
103
- function seatExternalSkill({ id, skill, entry }, matrix, projectDir) {
104
- const domain = getCategoryDomain(skill.categoryId);
105
- if (domain === void 0) return [];
106
- const install = {
107
- id,
108
- skill,
109
- domain,
110
- scope: entry.scope,
111
- skillDir: externalSkillDir(id, entry.scope, projectDir)
112
- };
113
- matrix.skills[id] = externalCatalogueEntry(install);
114
- claimSlug(matrix.slugMap, externalSlug(id), id);
115
- return [install];
116
- }
117
- function registerExternalSkills(payload, matrix, projectDir) {
118
- const externals = selectedExternals(payload);
119
- const asPlugin = askedForAsPlugin(externals);
120
- const colliding = claimingACatalogueId(externals, matrix);
121
- if (asPlugin.length > 0) throw new Error(pluginInstallError(asPlugin));
122
- if (colliding.length > 0) throw new Error(catalogueIdCollisionError(colliding));
123
- return externals.flatMap((external) => seatExternalSkill(external, matrix, projectDir));
124
- }
125
- async function writeExternalSkills(installs) {
126
- await refuseUncarriedDestinations(installs);
127
- for (const install of installs) {
128
- await writeSkillTree(install);
129
- await writeSkillManifest(install);
130
- await registerSkillOnDisk(install);
131
- }
132
- }
133
- async function refuseUncarriedDestinations(installs) {
134
- const judged = await Promise.all(installs.map(judgeDestination));
135
- const blocked = judged.filter((destination) => destination !== null);
136
- if (blocked.length > 0) throw new Error(uncarriedDestinationError(blocked));
137
- }
138
- async function judgeDestination(install) {
139
- const { id, skillDir } = install;
140
- if (!await directoryExists(skillDir)) return null;
141
- if ((await readForkedFromMetadata(skillDir))?.path !== void 0) return null;
142
- return { id, skillDir };
143
- }
144
- function uncarriedDestinationError(blocked) {
145
- return [
146
- "This configuration cannot be installed: these skills travel inside it under ids this installation already keeps a skill directory for, and no shared configuration put those directories there:",
147
- ...blocked.map(({ id, skillDir }) => ` ${id} -> ${skillDir}`),
148
- "A skill id is the directory the skill installs into, so each would be written over a skill written here by hand or ejected from a marketplace. Move or rename the directory above, or re-share the configuration with each skill added again, which mints an id \u2014 'external-<category>-<name>' \u2014 that nothing here holds."
149
- ].join("\n");
150
- }
151
- async function writeSkillTree(install) {
152
- for (const [relativePath, contents] of Object.entries(install.skill.files)) {
153
- const filePath = path.join(install.skillDir, relativePath);
154
- validateSkillPath(filePath, install.skillDir, relativePath);
155
- await writeFile(filePath, contents);
156
- }
157
- }
158
- var FRONTMATTER_BLOCK = /^---\r?\n([\s\S]*?)\r?\n---/;
159
- var NAME_FIELD = /^name:.*$/m;
160
- function withInstalledName(manifest, install) {
161
- const named = `name: ${install.id}`;
162
- const block = FRONTMATTER_BLOCK.exec(manifest);
163
- if (!block) {
164
- return `---
165
- ${named}
166
- description: ${install.skill.description}
167
- ---
168
-
169
- ${manifest}`;
170
- }
171
- const [whole, fields = ""] = block;
172
- const renamed = NAME_FIELD.test(fields) ? fields.replace(NAME_FIELD, named) : `${named}
173
- ${fields}`;
174
- return `---
175
- ${renamed}
176
- ---${manifest.slice(whole.length)}`;
177
- }
178
- async function writeSkillManifest(install) {
179
- const manifestPath = path.join(install.skillDir, STANDARD_FILES.SKILL_MD);
180
- await writeFile(manifestPath, withInstalledName(await readFile(manifestPath), install));
181
- }
182
- function externalSkillMetadata(install, shipped) {
183
- return {
184
- author: skillAuthor(install.skill.repo),
185
- usageGuidance: defaultUsageGuidance(install.skill.categoryId),
186
- ...shipped,
187
- displayName: install.skill.displayName,
188
- slug: install.id,
189
- category: install.skill.categoryId,
190
- domain: install.domain,
191
- cliDescription: install.skill.description,
192
- custom: true
193
- };
194
- }
195
- async function registerSkillOnDisk(install) {
196
- const metadataPath = path.join(install.skillDir, STANDARD_FILES.METADATA_YAML);
197
- const shipped = await readLocalSkillMetadata(install.skillDir);
198
- await writeMetadataYaml(metadataPath, externalSkillMetadata(install, shipped));
199
- await injectForkedFromMetadata(
200
- install.skillDir,
201
- install.id,
202
- await computeFileHash(path.join(install.skillDir, STANDARD_FILES.SKILL_MD)),
203
- { source: repoRef(install.skill.repo), path: install.skill.path }
204
- );
205
- }
206
- function unnameableRepoMessage(id) {
207
- return `${id} travels inside a shared configuration, and this installation does not record the repository its content came from`;
208
- }
209
- function uncarryableContentMessage(id, reason) {
210
- return `${id} travels inside a shared configuration, and ${reason}`;
211
- }
212
- function repoFromRef(ref) {
213
- if (ref === void 0 || !ref.startsWith(GITHUB_SOURCE.GITHUB_PREFIX)) return void 0;
214
- return ref.slice(GITHUB_SOURCE.GITHUB_PREFIX.length);
215
- }
216
- async function readSkillTree(skillDir) {
217
- const files = await glob("**/*", skillDir, { dot: true });
218
- const entries = await Promise.all(
219
- files.map(async (file) => [file, await readFile(path.join(skillDir, file))])
220
- );
221
- return Object.fromEntries(entries);
222
- }
223
- async function readCarriedSkill({ id, skillDir, provenance }) {
224
- if (provenance.path === void 0) return { carries: "nothing" };
225
- const repo = repoFromRef(provenance.source);
226
- if (repo === void 0) return { carries: "unshareable", line: unnameableRepoMessage(id) };
227
- const described = await readSkillMetadata(path.join(skillDir, STANDARD_FILES.METADATA_YAML));
228
- if (!described.usable) {
229
- return { carries: "unshareable", line: uncarryableContentMessage(id, described.reason) };
230
- }
231
- const parsed = seedExternalSkillSchema.safeParse({
232
- displayName: described.metadata.displayName,
233
- description: described.metadata.cliDescription,
234
- categoryId: described.metadata.category,
235
- repo,
236
- path: provenance.path,
237
- files: await readSkillTree(skillDir)
238
- });
239
- if (!parsed.success) {
240
- const reason = parsed.error.issues.map((issue) => issue.message).join("; ");
241
- return { carries: "unshareable", line: uncarryableContentMessage(id, reason) };
242
- }
243
- return { carries: "content", id, skill: parsed.data };
244
- }
245
- async function readCarriedSkills(owned) {
246
- const reads = await Promise.all(owned.map(readCarriedSkill));
247
- return {
248
- external: Object.fromEntries(
249
- reads.flatMap((read) => read.carries === "content" ? [[read.id, read.skill]] : [])
250
- ),
251
- uncarryable: reads.flatMap((read) => read.carries === "unshareable" ? [read.line] : [])
252
- };
253
- }
7
+ } from "./chunk-AQXKAPCD.js";
254
8
 
255
9
  // ../../node_modules/hono/dist/utils/cookie.js
256
10
  var validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/;
@@ -326,11 +80,11 @@ var serialize = (name, value, opt) => {
326
80
  };
327
81
 
328
82
  // ../../node_modules/hono/dist/client/utils.js
329
- var mergePath = (base, path2) => {
83
+ var mergePath = (base, path) => {
330
84
  base = base.replace(/\/+$/, "");
331
85
  base = base + "/";
332
- path2 = path2.replace(/^\/+/, "");
333
- return base + path2;
86
+ path = path.replace(/^\/+/, "");
87
+ return base + path;
334
88
  };
335
89
  var replaceUrlParam = (urlString, params) => {
336
90
  for (const [k, v] of Object.entries(params)) {
@@ -389,18 +143,18 @@ function deepMerge(target, source) {
389
143
  }
390
144
 
391
145
  // ../../node_modules/hono/dist/client/client.js
392
- var createProxy = (callback, path2) => {
146
+ var createProxy = (callback, path) => {
393
147
  const proxy = new Proxy(() => {
394
148
  }, {
395
149
  get(_obj, key) {
396
150
  if (typeof key !== "string" || key === "then") {
397
151
  return void 0;
398
152
  }
399
- return createProxy(callback, [...path2, key]);
153
+ return createProxy(callback, [...path, key]);
400
154
  },
401
155
  apply(_1, _2, args) {
402
156
  return callback({
403
- path: path2,
157
+ path,
404
158
  args
405
159
  });
406
160
  }
@@ -504,8 +258,8 @@ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
504
258
  method = last.replace(/^\$/, "");
505
259
  }
506
260
  }
507
- const path2 = parts.join("/");
508
- const url = mergePath(baseUrl, path2);
261
+ const path = parts.join("/");
262
+ const url = mergePath(baseUrl, path);
509
263
  if (method === "url" || method === "path") {
510
264
  let result = url;
511
265
  if (opts.args[0]) {
@@ -650,11 +404,8 @@ function explanationOf(body) {
650
404
  }
651
405
 
652
406
  export {
653
- registerExternalSkills,
654
- writeExternalSkills,
655
- readCarriedSkills,
656
407
  SEED_API_URL,
657
408
  SEED_USER_AGENT,
658
409
  fetchSeedConfig
659
410
  };
660
- //# sourceMappingURL=chunk-X4SSJZLY.js.map
411
+ //# sourceMappingURL=chunk-B5UUHBAM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/hono/dist/utils/cookie.js","../../../node_modules/hono/dist/client/utils.js","../../../node_modules/hono/dist/client/client.js","../../api/src/client.ts","../src/cli/lib/seed/fetch-seed.ts"],"sourcesContent":["// src/utils/cookie.ts\nimport { decodeURIComponent_, tryDecode } from \"./url.js\";\nvar algorithm = { name: \"HMAC\", hash: \"SHA-256\" };\nvar getCryptoKey = async (secret) => {\n const secretBuf = typeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n return await crypto.subtle.importKey(\"raw\", secretBuf, algorithm, false, [\"sign\", \"verify\"]);\n};\nvar makeSignature = async (value, secret) => {\n const key = await getCryptoKey(secret);\n const signature = await crypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value));\n return btoa(String.fromCharCode(...new Uint8Array(signature)));\n};\nvar verifySignature = async (base64Signature, value, secret) => {\n try {\n const signatureBinStr = atob(base64Signature);\n const signature = new Uint8Array(signatureBinStr.length);\n for (let i = 0, len = signatureBinStr.length; i < len; i++) {\n signature[i] = signatureBinStr.charCodeAt(i);\n }\n return await crypto.subtle.verify(algorithm, secret, signature, new TextEncoder().encode(value));\n } catch {\n return false;\n }\n};\nvar validCookieNameRegEx = /^[\\w!#$%&'*.^`|~+-]+$/;\nvar relaxedCookieNameRegEx = /^[!#-:<>-[\\]-~]+$/;\nvar validCookieValueRegEx = /^[ !#-:<-[\\]-~]*$/;\nvar trimCookieWhitespace = (value) => {\n let start = 0;\n let end = value.length;\n while (start < end) {\n const charCode = value.charCodeAt(start);\n if (charCode !== 32 && charCode !== 9) {\n break;\n }\n start++;\n }\n while (end > start) {\n const charCode = value.charCodeAt(end - 1);\n if (charCode !== 32 && charCode !== 9) {\n break;\n }\n end--;\n }\n return start === 0 && end === value.length ? value : value.slice(start, end);\n};\nvar parse = (cookie, name) => {\n if (name && cookie.indexOf(name) === -1) {\n return {};\n }\n const pairs = cookie.split(\";\");\n const parsedCookie = /* @__PURE__ */ Object.create(null);\n for (const pairStr of pairs) {\n const valueStartPos = pairStr.indexOf(\"=\");\n if (valueStartPos === -1) {\n continue;\n }\n const cookieName = trimCookieWhitespace(pairStr.substring(0, valueStartPos));\n if (name && name !== cookieName || !relaxedCookieNameRegEx.test(cookieName) || cookieName in parsedCookie) {\n continue;\n }\n let cookieValue = trimCookieWhitespace(pairStr.substring(valueStartPos + 1));\n if (cookieValue.startsWith('\"') && cookieValue.endsWith('\"')) {\n cookieValue = cookieValue.slice(1, -1);\n }\n if (validCookieValueRegEx.test(cookieValue)) {\n parsedCookie[cookieName] = cookieValue.indexOf(\"%\") !== -1 ? tryDecode(cookieValue, decodeURIComponent_) : cookieValue;\n if (name) {\n break;\n }\n }\n }\n return parsedCookie;\n};\nvar parseSigned = async (cookie, secret, name) => {\n const parsedCookie = /* @__PURE__ */ Object.create(null);\n const secretKey = await getCryptoKey(secret);\n for (const [key, value] of Object.entries(parse(cookie, name))) {\n const signatureStartPos = value.lastIndexOf(\".\");\n if (signatureStartPos < 1) {\n continue;\n }\n const signedValue = value.substring(0, signatureStartPos);\n const signature = value.substring(signatureStartPos + 1);\n if (signature.length !== 44 || !signature.endsWith(\"=\")) {\n continue;\n }\n const isVerified = await verifySignature(signature, signedValue, secretKey);\n parsedCookie[key] = isVerified ? signedValue : false;\n }\n return parsedCookie;\n};\nvar _serialize = (name, value, opt = {}) => {\n if (!validCookieNameRegEx.test(name)) {\n throw new Error(\"Invalid cookie name\");\n }\n let cookie = `${name}=${value}`;\n if (name.startsWith(\"__Secure-\") && !opt.secure) {\n throw new Error(\"__Secure- Cookie must have Secure attributes\");\n }\n if (name.startsWith(\"__Host-\")) {\n if (!opt.secure) {\n throw new Error(\"__Host- Cookie must have Secure attributes\");\n }\n if (opt.path !== \"/\") {\n throw new Error('__Host- Cookie must have Path attributes with \"/\"');\n }\n if (opt.domain) {\n throw new Error(\"__Host- Cookie must not have Domain attributes\");\n }\n }\n for (const key of [\"domain\", \"path\", \"sameSite\", \"priority\"]) {\n if (opt[key] && /[;\\r\\n]/.test(opt[key])) {\n throw new Error(`${key} must not contain \";\", \"\\\\r\", or \"\\\\n\"`);\n }\n }\n if (opt && typeof opt.maxAge === \"number\" && opt.maxAge >= 0) {\n if (opt.maxAge > 3456e4) {\n throw new Error(\n \"Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.\"\n );\n }\n cookie += `; Max-Age=${opt.maxAge | 0}`;\n }\n if (opt.domain && opt.prefix !== \"host\") {\n cookie += `; Domain=${opt.domain}`;\n }\n if (opt.path) {\n cookie += `; Path=${opt.path}`;\n }\n if (opt.expires) {\n if (opt.expires.getTime() - Date.now() > 3456e7) {\n throw new Error(\n \"Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.\"\n );\n }\n cookie += `; Expires=${opt.expires.toUTCString()}`;\n }\n if (opt.httpOnly) {\n cookie += \"; HttpOnly\";\n }\n if (opt.secure) {\n cookie += \"; Secure\";\n }\n if (opt.sameSite) {\n cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`;\n }\n if (opt.priority) {\n cookie += `; Priority=${opt.priority.charAt(0).toUpperCase() + opt.priority.slice(1)}`;\n }\n if (opt.partitioned) {\n if (!opt.secure) {\n throw new Error(\"Partitioned Cookie must have Secure attributes\");\n }\n cookie += \"; Partitioned\";\n }\n return cookie;\n};\nvar serialize = (name, value, opt) => {\n value = encodeURIComponent(value);\n return _serialize(name, value, opt);\n};\nvar serializeSigned = async (name, value, secret, opt = {}) => {\n const signature = await makeSignature(value, secret);\n value = `${value}.${signature}`;\n value = encodeURIComponent(value);\n return _serialize(name, value, opt);\n};\nexport {\n parse,\n parseSigned,\n serialize,\n serializeSigned\n};\n","// src/client/utils.ts\nimport { fetchRP, DetailedError } from \"./fetch-result-please.js\";\nvar mergePath = (base, path) => {\n base = base.replace(/\\/+$/, \"\");\n base = base + \"/\";\n path = path.replace(/^\\/+/, \"\");\n return base + path;\n};\nvar replaceUrlParam = (urlString, params) => {\n for (const [k, v] of Object.entries(params)) {\n const reg = new RegExp(\"/:\" + k + \"(?:{[^/]+})?\\\\??(?=/|$)\");\n urlString = urlString.replace(reg, v ? `/${v}` : \"\");\n }\n return urlString;\n};\nvar buildSearchParams = (query) => {\n const searchParams = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) {\n if (v === void 0) {\n continue;\n }\n if (Array.isArray(v)) {\n for (const v2 of v) {\n searchParams.append(k, v2);\n }\n } else {\n searchParams.set(k, v);\n }\n }\n return searchParams;\n};\nvar replaceUrlProtocol = (urlString, protocol) => {\n switch (protocol) {\n case \"ws\":\n return urlString.replace(/^http/, \"ws\");\n case \"http\":\n return urlString.replace(/^ws/, \"http\");\n }\n};\nvar removeIndexString = (urlString) => {\n if (/^https?:\\/\\/[^\\/]+?\\/index(?=\\?|$)/.test(urlString)) {\n return urlString.replace(/\\/index(?=\\?|$)/, \"/\");\n }\n return urlString.replace(/\\/index(?=\\?|$)/, \"\");\n};\nfunction isObject(item) {\n return typeof item === \"object\" && item !== null && !Array.isArray(item);\n}\nfunction deepMerge(target, source) {\n if (!isObject(target) && !isObject(source)) {\n return source;\n }\n const merged = { ...target };\n for (const key in source) {\n const value = source[key];\n if (isObject(merged[key]) && isObject(value)) {\n merged[key] = deepMerge(merged[key], value);\n } else {\n merged[key] = value;\n }\n }\n return merged;\n}\nasync function parseResponse(fetchRes) {\n return fetchRP(fetchRes);\n}\nexport {\n DetailedError,\n buildSearchParams,\n deepMerge,\n mergePath,\n parseResponse,\n removeIndexString,\n replaceUrlParam,\n replaceUrlProtocol\n};\n","// src/client/client.ts\nimport { serialize } from \"../utils/cookie.js\";\nimport {\n buildSearchParams,\n deepMerge,\n mergePath,\n removeIndexString,\n replaceUrlParam,\n replaceUrlProtocol\n} from \"./utils.js\";\nvar createProxy = (callback, path) => {\n const proxy = new Proxy(() => {\n }, {\n get(_obj, key) {\n if (typeof key !== \"string\" || key === \"then\") {\n return void 0;\n }\n return createProxy(callback, [...path, key]);\n },\n apply(_1, _2, args) {\n return callback({\n path,\n args\n });\n }\n });\n return proxy;\n};\nvar ClientRequestImpl = class {\n url;\n method;\n buildSearchParams;\n queryParams = void 0;\n pathParams = {};\n rBody;\n cType = void 0;\n constructor(url, method, options) {\n this.url = url;\n this.method = method;\n this.buildSearchParams = options.buildSearchParams;\n }\n fetch = async (args, opt) => {\n if (args) {\n if (args.query) {\n this.queryParams = this.buildSearchParams(args.query);\n }\n if (args.form) {\n const form = new FormData();\n for (const [k, v] of Object.entries(args.form)) {\n if (v === void 0) {\n continue;\n }\n if (Array.isArray(v)) {\n for (const v2 of v) {\n form.append(k, v2);\n }\n } else {\n form.append(k, v);\n }\n }\n this.rBody = form;\n }\n if (args.json) {\n this.rBody = JSON.stringify(args.json);\n this.cType = \"application/json\";\n }\n if (args.param) {\n this.pathParams = args.param;\n }\n }\n let methodUpperCase = this.method.toUpperCase();\n const headerValues = {\n ...args?.header,\n ...typeof opt?.headers === \"function\" ? await opt.headers() : opt?.headers\n };\n if (args?.cookie) {\n const cookies = [];\n for (const [key, value] of Object.entries(args.cookie)) {\n cookies.push(serialize(key, value, { path: \"/\" }));\n }\n headerValues[\"Cookie\"] = cookies.join(\",\");\n }\n if (this.cType) {\n headerValues[\"Content-Type\"] = this.cType;\n }\n const headers = new Headers(headerValues ?? void 0);\n let url = this.url;\n url = removeIndexString(url);\n url = replaceUrlParam(url, this.pathParams);\n if (this.queryParams) {\n url = url + \"?\" + this.queryParams.toString();\n }\n methodUpperCase = this.method.toUpperCase();\n const setBody = !(methodUpperCase === \"GET\" || methodUpperCase === \"HEAD\");\n return (opt?.fetch || fetch)(url, {\n body: setBody ? this.rBody : void 0,\n method: methodUpperCase,\n headers,\n ...opt?.init\n });\n };\n};\nvar hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {\n const buildSearchParamsOption = options?.buildSearchParams ?? buildSearchParams;\n const parts = [...opts.path];\n const lastParts = parts.slice(-3).reverse();\n if (lastParts[0] === \"toString\") {\n if (lastParts[1] === \"name\") {\n return lastParts[2] || \"\";\n }\n return proxyCallback.toString();\n }\n if (lastParts[0] === \"valueOf\") {\n if (lastParts[1] === \"name\") {\n return lastParts[2] || \"\";\n }\n return proxyCallback;\n }\n let method = \"\";\n if (/^\\$/.test(lastParts[0])) {\n const last = parts.pop();\n if (last) {\n method = last.replace(/^\\$/, \"\");\n }\n }\n const path = parts.join(\"/\");\n const url = mergePath(baseUrl, path);\n if (method === \"url\" || method === \"path\") {\n let result = url;\n if (opts.args[0]) {\n if (opts.args[0].param) {\n result = replaceUrlParam(url, opts.args[0].param);\n }\n if (opts.args[0].query) {\n result = result + \"?\" + buildSearchParamsOption(opts.args[0].query).toString();\n }\n }\n result = removeIndexString(result);\n if (method === \"url\") {\n return new URL(result);\n }\n return result.slice(baseUrl.replace(/\\/+$/, \"\").length).replace(/^\\/?/, \"/\");\n }\n if (method === \"ws\") {\n const webSocketUrl = replaceUrlProtocol(\n opts.args[0] && opts.args[0].param ? replaceUrlParam(url, opts.args[0].param) : url,\n \"ws\"\n );\n const targetUrl = new URL(webSocketUrl);\n const queryParams = opts.args[0]?.query;\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((item) => targetUrl.searchParams.append(key, item));\n } else {\n targetUrl.searchParams.set(key, value);\n }\n });\n }\n const establishWebSocket = (...args) => {\n if (options?.webSocket !== void 0 && typeof options.webSocket === \"function\") {\n return options.webSocket(...args);\n }\n return new WebSocket(...args);\n };\n return establishWebSocket(targetUrl.toString());\n }\n const req = new ClientRequestImpl(url, method, {\n buildSearchParams: buildSearchParamsOption\n });\n if (method) {\n options ??= {};\n const reqOptions = { ...opts.args[1] };\n const baseHeaders = options.headers;\n const reqHeaders = reqOptions.headers;\n if (baseHeaders && reqHeaders) {\n reqOptions.headers = async () => ({\n ...typeof baseHeaders === \"function\" ? await baseHeaders() : baseHeaders,\n ...typeof reqHeaders === \"function\" ? await reqHeaders() : reqHeaders\n });\n }\n const args = deepMerge(options, reqOptions);\n return req.fetch(opts.args[0], args);\n }\n return req;\n}, []);\nexport {\n hc\n};\n","import { hc } from \"hono/client\"\n\nimport type { AppType } from \"server\"\n\n/**\n * The typed client both front doors reach the worker through.\n *\n * The editor and the CLI shared nothing before this package existed: the\n * editor configured `hc<AppType>` and the CLI hand-wrote a `fetch` at a URL it\n * built itself, so the two agreed about the worker's routes only by\n * coincidence. What they genuinely differ in is small and finite — where the\n * worker is, whether a session cookie rides along, and what identifies the\n * caller — so those are the parameters and everything else is shared.\n *\n * What this package deliberately does NOT own is either consumer's refusal\n * copy. The editor turns a failure into a union member a component renders;\n * the CLI turns one into a sentence a person reads in a terminal. Those are\n * different artefacts for different readers, and a shared \"message\" would be\n * wrong for both.\n *\n * `AppType` is a type and nothing else. `import type` erases before any\n * bundler sees it, so no worker code is reachable from the editor's bundle\n * (which fails its build on a first-paint budget) or from the CLI's.\n */\n\n/**\n * Whether the browser's session cookie rides along.\n *\n * Only the two values either consumer has a use for, rather than the full\n * `RequestCredentials`: `same-origin` is exactly the setting that breaks the\n * editor, because the cookie is set on `.agentsinc.sh` by a different origin\n * than the one the app is served from, and naming it here would make it\n * reachable by a typo.\n */\nexport type ApiCredentials = \"include\" | \"omit\"\n\n/**\n * What every request carries, however it is sent.\n *\n * `credentials` defaults to `\"include\"` and that direction is the point. The\n * session cookie is set by a different origin on the same registrable domain,\n * and without it sign-in appears to work and the very next request is\n * anonymous — with nothing logged on either side. A policy that has to be\n * opted INTO is one a new call site can forget silently; this one has to be\n * opted out of by name, which is a thing a reader can see.\n */\nexport type ApiRequestPolicy = {\n headers?: Record<string, string>\n credentials?: ApiCredentials\n}\n\nexport type ApiClientOptions = ApiRequestPolicy & {\n /** Where the worker is. No default: a wrong guess is a silent wrong API. */\n baseUrl: string\n /**\n * The seam tests reach through. hc calls\n * `(opt?.fetch || fetch)(url, { body, method, headers, ...opt?.init })`, so\n * injecting one is the only way to observe what this package produces without\n * a network — and the exact shape matters, because `init` is spread LAST.\n * That is why `headers` goes through hc's own option rather than through\n * `init`: in `init` it would replace the whole `Headers` object, including\n * the content type hc sets for a JSON body.\n */\n fetch?: typeof globalThis.fetch\n}\n\ntype ResolvedPolicy = {\n headers: Record<string, string>\n credentials: ApiCredentials\n}\n\n/**\n * The one place the defaults are applied, so the typed client and any\n * hand-written fetch cannot drift about what a request carries.\n */\nconst resolvePolicy = ({\n headers = {},\n credentials = \"include\",\n}: ApiRequestPolicy): ResolvedPolicy => ({ headers, credentials })\n\n/**\n * The policy as a `RequestInit`, for the paths `AppType` does not describe.\n *\n * Better Auth mounts its own surface under `/api/auth/*` with a single\n * handler rather than a described route, so there is nothing there for `hc` to\n * type — and a hand-written fetch at those paths is how the editor signs a\n * person in. This is what keeps that call on the same session policy as the\n * typed ones instead of on a second copy of it.\n *\n * Spread it LAST over a caller's own init: a caller may add a method, a body\n * or headers of its own, and may not drop the cookie.\n */\nexport const apiRequestInit = (policy: ApiRequestPolicy): RequestInit =>\n resolvePolicy(policy)\n\n/**\n * Builds the client for one consumer's base URL, headers and session policy.\n *\n * The two configured values go to different places in hc's options, and which\n * goes where is load-bearing. hc spreads `init` LAST over the request it\n * built, so anything named there replaces what hc put in that field — a\n * `headers` in `init` would replace the whole `Headers` object, including the\n * `Content-Type: application/json` hc sets for a `$post({ json })`. Headers go\n * through hc's own `headers` option, which is merged into that object instead,\n * and `init` names `credentials` and nothing else.\n */\nexport const createApiClient = ({\n baseUrl,\n fetch,\n ...policy\n}: ApiClientOptions) => {\n const { headers, credentials } = resolvePolicy(policy)\n\n return hc<AppType>(baseUrl, {\n headers,\n init: { credentials },\n // Spread rather than named. Under `exactOptionalPropertyTypes` hc's\n // optional `fetch` does not accept an explicit `undefined`, so writing\n // `fetch,` here is a TS2379 whenever a caller omits one.\n ...(fetch && { fetch }),\n })\n}\n\n/** The configured client, for consumers that pass one around. */\nexport type ApiClient = ReturnType<typeof createApiClient>\n","import { createApiClient } from \"@workspace/api\";\nimport { seedPayloadSchema, type SeedPayload } from \"@workspace/matrix/seed\";\n\nimport { truncateText } from \"../../utils/string.js\";\n\n/** The config store behind agentsinc.sh. Overridable so tests never touch the network. */\nexport const SEED_API_URL = process.env.AGENTS_INC_API_URL ?? \"https://api.agentsinc.sh\";\n\n/**\n * Identifies this fetch as the CLI rather than a browser.\n *\n * `GET /configs/:id` is the only place either side can observe a config being *installed* rather\n * than merely built, and the worker can only separate that from someone opening a share link if\n * we say so. Without this the conversion signal does not exist.\n */\nexport const SEED_USER_AGENT = \"agents-inc-cli\";\n\n/**\n * The worker's routes, typed from the worker itself, configured for a terminal.\n *\n * `credentials: \"omit\"` is named rather than left to the shared default. The default is `include`\n * because the editor's session is a cookie the browser holds; a terminal holds no cookie jar at\n * all, so inheriting that default would claim a session that cannot exist.\n *\n * Built once at module scope, like `SEED_API_URL` above and for the same reason — the base URL is\n * read from the environment once at import, so there is nothing per-call for a client to pick up.\n */\nconst store = createApiClient({\n baseUrl: SEED_API_URL,\n headers: { accept: \"application/json\", \"user-agent\": SEED_USER_AGENT },\n credentials: \"omit\",\n});\n\n/**\n * How much of the store's account of a refused read to quote back.\n *\n * Sized on what this route really says, which is one short line per refusal: `Stored config is\n * unreadable` and `Could not read this config` are both under thirty characters. This holds the\n * longer of them four times over — room for that sentence to grow into a real one, and none for\n * anything that has stopped being a sentence.\n *\n * Far short of the 300-character `EXPLANATION_BUDGET` in `publish-seed.ts`, and for the reason\n * that one gives for its own size rather than in spite of it: a budget is sized on what the store\n * really writes there, and what it writes there is a list of schema issues naming a skill and a\n * sub-agent apiece. Neither number is a policy about terminals; each is a measurement of one\n * route.\n */\nconst EXPLANATION_BUDGET = 120;\n\n/** The content type the store's own refusals arrive as, and the only one worth reading. */\nconst QUOTABLE_TYPE = \"text/plain\";\n\n/** The status the store spends on an id it has never held, which is the one it is asked for. */\nconst NO_SUCH_CONFIG = 404;\n\nexport type FetchSeedResult = { ok: true; payload: SeedPayload } | { ok: false; error: string };\n\n/**\n * Fetches and validates a shared configuration.\n *\n * Every failure is a message rather than a throw: this runs before anything has been written, so\n * there is nothing to roll back and the caller's job is to explain rather than recover.\n */\nexport async function fetchSeedConfig(id: string): Promise<FetchSeedResult> {\n let response: Response;\n try {\n // Escaped here rather than by the client: hono's `replaceUrlParam` substitutes a path\n // parameter verbatim, so an id carrying a `/` or a `?` would silently address another route.\n response = await store.configs[\":id\"].$get({ param: { id: encodeURIComponent(id) } });\n } catch {\n return { ok: false, error: `Could not reach ${SEED_API_URL} — check your connection.` };\n }\n\n // Ahead of the quoting arm below, and the only status held out of it. The store answers this\n // one `No config under this id`, which says strictly less than the sentence here does — it does\n // not name the id the caller typed, and that is the whole of what a person needs to see.\n if (response.status === NO_SUCH_CONFIG) {\n return { ok: false, error: `No configuration found for id '${id}'.` };\n }\n if (!response.ok) {\n return { ok: false, error: await refusalMessage(response) };\n }\n\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n return { ok: false, error: \"The configuration store returned something that is not JSON.\" };\n }\n\n const parsed = seedPayloadSchema.safeParse(body);\n if (!parsed.success) {\n // Names the remedy rather than a cause it cannot observe. The payload was validated by the\n // store on the way IN, so a stored payload that no longer parses means the contract moved\n // underneath it — and every way that happens lands in this one `safeParse`: an id minted\n // before a version bump, an id minted after one, and a body that is simply broken. The CLI\n // cannot tell them apart, and the one thing true of all three is that re-sharing fixes it,\n // because the store content-addresses an id and a fresh share mints one under this version.\n return {\n ok: false,\n error: `Configuration '${id}' is not in a format this version of the CLI can install. Shared ids are never migrated — re-share the configuration to mint a current one, or update the CLI if that id came from a newer version.`,\n };\n }\n\n return { ok: true, payload: parsed.data };\n}\n\n/**\n * A refusal, carrying the store's own account of it wherever there is one to have.\n *\n * The same posture `refusalMessage` in `publish-seed.ts` takes on the write side, and deliberately\n * NOT the same mechanism. That route's 400 arrives as a `@hono/zod-validator` envelope with the\n * refused issues rendered inside it; `getConfig` writes every one of its refusals with `c.text`,\n * so there is no envelope here to parse and a copy of that parser would find nothing in any body\n * this route can produce.\n *\n * The status is never given up. It is what separates a store that is present and holding bytes it\n * can no longer read (500) from one that would not answer at all (503) — and what the body then\n * adds is the store saying which of its own failures this was, in words the status has no room\n * for.\n */\nasync function refusalMessage(response: Response): Promise<string> {\n const refused = `Fetching configuration failed (HTTP ${response.status}).`;\n const explanation = explanationOf(await refusalBody(response));\n\n return explanation === undefined ? refused : `${refused} The store said: ${explanation}`;\n}\n\n/**\n * Whatever the store sent, as far as it can be read — and only where it was the store that sent it.\n *\n * Nothing below this line is worth failing over: the message being assembled is already a failure,\n * and a body that cannot be read is one more thing the status will have to cover on its own.\n * Draining the stream can throw in its own right — a connection dropped mid-body — which is why\n * the `try` is around the read.\n */\nasync function refusalBody(response: Response): Promise<string | undefined> {\n if (!arrivedAsText(response)) return undefined;\n\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether what arrived is the store speaking, as far as the wire says it is.\n *\n * `getConfig` writes every refusal with `c.text(...)`, so `text/plain` is the shape the store's\n * own words take on this route. What arrives as anything else did not come from it: a proxy, a\n * WAF, a captive portal or a gateway answering in its place — and their answer is markup rather\n * than prose, which quoted into a terminal is a screenful of tags that explains nothing and buries\n * the status that does.\n *\n * This is the plain-text half of what `refusalSchema` does for `publish-seed.ts`. That side has a\n * SHAPE a foreign body fails to be; a sentence has no shape, so the wire's own statement of what\n * it sent is the only discriminator there is. It is not proof — a hostile answer may claim any\n * type it likes — which is what {@link EXPLANATION_BUDGET} is for, and why what survives both is\n * attributed to the store rather than spoken in the CLI's own voice.\n */\nfunction arrivedAsText(response: Response): boolean {\n return (response.headers.get(\"content-type\") ?? \"\").startsWith(QUOTABLE_TYPE);\n}\n\n/** The store's account of a refusal, where what came back really is one. */\nfunction explanationOf(body: string | undefined): string | undefined {\n if (body === undefined) return undefined;\n\n const said = body.trim();\n if (said === \"\") return undefined;\n\n return truncateText(said, EXPLANATION_BUDGET);\n}\n"],"mappings":"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","names":["fetch"]}
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SummaryPanel
4
- } from "./chunk-LT5GXEB2.js";
4
+ } from "./chunk-VPJUCVU7.js";
5
5
  import {
6
6
  Toast
7
- } from "./chunk-QZX7SYKU.js";
7
+ } from "./chunk-E6CHHXGY.js";
8
8
  import {
9
9
  WizardTabs,
10
10
  wizardTabsFor
11
- } from "./chunk-S63LXWMC.js";
11
+ } from "./chunk-5M3PQNXI.js";
12
12
  import {
13
13
  getDomainDisplayName,
14
14
  getStackName
15
- } from "./chunk-4VL3CEOS.js";
15
+ } from "./chunk-LXXGZAD3.js";
16
16
  import {
17
17
  HOTKEY_INFO,
18
18
  HOTKEY_SCOPE,
@@ -25,17 +25,17 @@ import {
25
25
  import {
26
26
  getActiveStepFlow,
27
27
  useWizardStore
28
- } from "./chunk-K5ITEA3I.js";
28
+ } from "./chunk-UBSSIIWD.js";
29
29
  import {
30
30
  formatTerminalTooSmallMessage,
31
31
  isTerminalLargeEnough
32
- } from "./chunk-PHCPUQVR.js";
32
+ } from "./chunk-CTUJO23Z.js";
33
33
  import {
34
34
  CLI_COLORS,
35
35
  FALLBACK_DOMAIN,
36
36
  LOGO_MIN_TERMINAL_ROWS,
37
37
  orderDomains
38
- } from "./chunk-UITEKY2R.js";
38
+ } from "./chunk-AQXKAPCD.js";
39
39
 
40
40
  // src/cli/components/wizard/wizard-layout.tsx
41
41
  import { Box, Text } from "ink";
@@ -234,4 +234,4 @@ export {
234
234
  useTerminalDimensions,
235
235
  WizardLayout
236
236
  };
237
- //# sourceMappingURL=chunk-ARYNOWKF.js.map
237
+ //# sourceMappingURL=chunk-BGU25XAY.js.map
@@ -1,24 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ScrollAffordance
4
- } from "./chunk-6MV4JOCL.js";
4
+ } from "./chunk-PSX7CT6V.js";
5
5
  import {
6
6
  useFocusedListItem
7
- } from "./chunk-J27W6TXS.js";
7
+ } from "./chunk-XQHZPINL.js";
8
8
  import {
9
9
  KEY_SPACE
10
10
  } from "./chunk-WTJ3AY33.js";
11
11
  import {
12
12
  useSectionScroll
13
- } from "./chunk-ABAZMMG4.js";
13
+ } from "./chunk-CK5RM3DJ.js";
14
14
  import {
15
15
  getSkillById
16
- } from "./chunk-AVK2HEKB.js";
16
+ } from "./chunk-GKPW33FP.js";
17
17
  import {
18
18
  CLI_COLORS,
19
19
  INSTALL_MODE_CELL_LABELS,
20
20
  UI_SYMBOLS
21
- } from "./chunk-UITEKY2R.js";
21
+ } from "./chunk-AQXKAPCD.js";
22
22
 
23
23
  // src/cli/components/wizard/source-grid.tsx
24
24
  import { useCallback, useMemo } from "react";
@@ -150,13 +150,17 @@ var SourceGrid = ({
150
150
  [rows]
151
151
  );
152
152
  const effectiveDefaultRow = firstFocusableRowIndex(rows, defaultFocusedRow);
153
- const { focusedRow, focusedCol, moveFocus } = useFocusedListItem(rows.length, getColCount, {
154
- wrap: true,
155
- ...onFocusChange !== void 0 && { onChange: onFocusChange },
156
- initialRow: effectiveDefaultRow,
157
- initialCol: defaultFocusedCol,
158
- skipRow
159
- });
153
+ const { focusedRow, focusedCol, currentFocus, moveFocus } = useFocusedListItem(
154
+ rows.length,
155
+ getColCount,
156
+ {
157
+ wrap: true,
158
+ ...onFocusChange !== void 0 && { onChange: onFocusChange },
159
+ initialRow: effectiveDefaultRow,
160
+ initialCol: defaultFocusedCol,
161
+ skipRow
162
+ }
163
+ );
160
164
  const {
161
165
  setSectionRef,
162
166
  setViewportRef,
@@ -176,17 +180,18 @@ var SourceGrid = ({
176
180
  useInput(
177
181
  useCallback(
178
182
  (input, key) => {
183
+ const focused = currentFocus();
179
184
  if (input === KEY_SPACE) {
180
- const currentRow = rows[focusedRow];
185
+ const currentRow = rows[focused.row];
181
186
  if (!currentRow || isRowInert(currentRow)) return;
182
- const currentOption = currentRow.options[focusedCol];
187
+ const currentOption = currentRow.options[focused.col];
183
188
  if (currentOption) {
184
189
  onSelect(currentRow.skillId, currentOption.mode);
185
190
  }
186
191
  return;
187
192
  }
188
193
  const noFocusableRow = lastFocusableRow === -1;
189
- const atLastFocusableRow = focusedRow === lastFocusableRow;
194
+ const atLastFocusableRow = focused.row === lastFocusableRow;
190
195
  if (key.leftArrow) {
191
196
  moveFocus("left");
192
197
  } else if (key.rightArrow) {
@@ -207,8 +212,7 @@ var SourceGrid = ({
207
212
  },
208
213
  [
209
214
  rows,
210
- focusedRow,
211
- focusedCol,
215
+ currentFocus,
212
216
  onSelect,
213
217
  moveFocus,
214
218
  scrollEnabled,
@@ -285,4 +289,4 @@ export {
285
289
  isRowInert,
286
290
  SourceGrid
287
291
  };
288
- //# sourceMappingURL=chunk-QGUP3QJF.js.map
292
+ //# sourceMappingURL=chunk-CBMAO6OP.js.map