agents-inc 0.161.0 → 0.162.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/{chunk-ADDYIMWN.js → chunk-2IMHZEIK.js} +3 -3
- package/dist/{chunk-DHRW3MDM.js → chunk-33ZKIYJM.js} +3 -3
- package/dist/{chunk-DTCUZL7S.js → chunk-3JDVBHWO.js} +2 -2
- package/dist/{chunk-BLGETWYI.js → chunk-3QBOVV6A.js} +2 -2
- package/dist/{chunk-ODUACQLV.js → chunk-4KVJJJG2.js} +6 -6
- package/dist/{chunk-5MML3K36.js → chunk-4NAWM4OQ.js} +2 -2
- package/dist/{chunk-EY7Z34Y4.js → chunk-53XPSAJ4.js} +14 -14
- package/dist/chunk-53XPSAJ4.js.map +1 -0
- package/dist/{chunk-ZQZHDYHQ.js → chunk-57YWAMNT.js} +7 -7
- package/dist/{chunk-3M75HVIM.js → chunk-5J6DO4VW.js} +3 -3
- package/dist/{chunk-UMYEY6BA.js → chunk-77YZFVQD.js} +2 -2
- package/dist/{chunk-SX57ZIGM.js → chunk-AQSMNUKJ.js} +4 -4
- package/dist/{chunk-B7YTQVAF.js → chunk-BR3TNSO3.js} +4 -4
- package/dist/{chunk-MED6GNV3.js → chunk-C53RJ7AA.js} +9 -9
- package/dist/{chunk-EEFTUZHZ.js → chunk-EN5MEPAS.js} +5 -5
- package/dist/{chunk-B3YSTZZC.js → chunk-ES7WGE32.js} +3 -3
- package/dist/{chunk-BRHU6J3C.js → chunk-FL2CJ5T5.js} +3 -3
- package/dist/{chunk-3TM4FHTG.js → chunk-FXL63LDL.js} +2 -2
- package/dist/{chunk-5DWDT6GM.js → chunk-GFO55TMY.js} +10 -5
- package/dist/chunk-GFO55TMY.js.map +1 -0
- package/dist/{chunk-2MPXMJ2O.js → chunk-H2MDPOLG.js} +5 -5
- package/dist/{chunk-A2NA377T.js → chunk-HRVPZMKK.js} +6 -6
- package/dist/{chunk-6PVWDTEM.js → chunk-IMTWWA3N.js} +12 -12
- package/dist/{chunk-AMZO4YJK.js → chunk-IV42Z63R.js} +2 -2
- package/dist/{chunk-AMZO4YJK.js.map → chunk-IV42Z63R.js.map} +1 -1
- package/dist/{chunk-XA4SWA2Z.js → chunk-J2YG7P7L.js} +32 -6
- package/dist/{chunk-XA4SWA2Z.js.map → chunk-J2YG7P7L.js.map} +1 -1
- package/dist/{chunk-YOVUXONB.js → chunk-K26SBQLO.js} +4 -4
- package/dist/{chunk-EQSMVZGS.js → chunk-L65XGQKR.js} +8 -8
- package/dist/{chunk-264XDRU7.js → chunk-MI7LKLD7.js} +2 -2
- package/dist/{chunk-HB3YIAFD.js → chunk-MSUTHS2V.js} +2 -2
- package/dist/{chunk-W2RXRWDB.js → chunk-QM3ZNOWJ.js} +2 -2
- package/dist/{chunk-3H42U56X.js → chunk-RMMEYCEA.js} +2 -2
- package/dist/{chunk-LZPRLHUE.js → chunk-S6GX7IJ2.js} +6 -6
- package/dist/{chunk-T4RVCFWN.js → chunk-T2RPUNYP.js} +3 -3
- package/dist/{chunk-YSQ76LWG.js → chunk-UNASGGW2.js} +46 -27
- package/dist/chunk-UNASGGW2.js.map +1 -0
- package/dist/{chunk-WVCF7KFV.js → chunk-VEBEGZUV.js} +5 -5
- package/dist/{chunk-AO6DXJUK.js → chunk-VEONZFTL.js} +3 -3
- package/dist/{chunk-DGXW2ZFY.js → chunk-VFZF7LVY.js} +3 -3
- package/dist/{chunk-N6CILY5A.js → chunk-WIJM6BX6.js} +2 -2
- package/dist/{chunk-EERGAAGE.js → chunk-X6KXPRKI.js} +4 -4
- package/dist/{chunk-QKMT6OOP.js → chunk-XSM3IBMG.js} +2 -2
- package/dist/{chunk-F6LS2BQD.js → chunk-ZFPQM63K.js} +71 -9
- package/dist/{chunk-F6LS2BQD.js.map → chunk-ZFPQM63K.js.map} +1 -1
- package/dist/commands/build/marketplace.js +7 -7
- package/dist/commands/build/plugins.js +7 -7
- package/dist/commands/compile.js +10 -10
- package/dist/commands/doctor.js +10 -10
- package/dist/commands/edit.js +37 -37
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +10 -10
- package/dist/commands/init.js +36 -36
- package/dist/commands/list.js +8 -8
- package/dist/commands/new/marketplace.js +7 -7
- package/dist/commands/search.js +15 -14
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +22 -16
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +11 -11
- package/dist/commands/update.js +6 -6
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/wizard/category-grid.js +4 -4
- package/dist/components/wizard/checkbox-grid.js +4 -4
- package/dist/components/wizard/domain-selection.js +9 -9
- package/dist/components/wizard/run-wizard-session.js +26 -26
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +5 -5
- package/dist/components/wizard/source-grid.js +5 -5
- package/dist/components/wizard/stack-selection.js +7 -7
- package/dist/components/wizard/step-agents.js +8 -8
- package/dist/components/wizard/step-build.js +7 -7
- package/dist/components/wizard/step-confirm.js +9 -9
- package/dist/components/wizard/step-sources.js +8 -8
- package/dist/components/wizard/step-stack.js +8 -8
- package/dist/components/wizard/summary-panel.js +8 -8
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +12 -12
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard.js +25 -25
- package/dist/hooks/init.js +36 -36
- package/dist/load-agent-defs-57YKPVQW.js +13 -0
- package/dist/recompile-project-agents-IQD3HRRS.js +17 -0
- package/dist/{source-loader-TSF5VS6V.js → source-loader-KAWB76OH.js} +4 -4
- package/dist/stores/wizard-store.js +4 -4
- package/package.json +2 -2
- package/dist/chunk-5DWDT6GM.js.map +0 -1
- package/dist/chunk-EY7Z34Y4.js.map +0 -1
- package/dist/chunk-YSQ76LWG.js.map +0 -1
- package/dist/load-agent-defs-LDSND43G.js +0 -13
- package/dist/recompile-project-agents-GQLODH24.js +0 -17
- /package/dist/{chunk-ADDYIMWN.js.map → chunk-2IMHZEIK.js.map} +0 -0
- /package/dist/{chunk-DHRW3MDM.js.map → chunk-33ZKIYJM.js.map} +0 -0
- /package/dist/{chunk-DTCUZL7S.js.map → chunk-3JDVBHWO.js.map} +0 -0
- /package/dist/{chunk-BLGETWYI.js.map → chunk-3QBOVV6A.js.map} +0 -0
- /package/dist/{chunk-ODUACQLV.js.map → chunk-4KVJJJG2.js.map} +0 -0
- /package/dist/{chunk-5MML3K36.js.map → chunk-4NAWM4OQ.js.map} +0 -0
- /package/dist/{chunk-ZQZHDYHQ.js.map → chunk-57YWAMNT.js.map} +0 -0
- /package/dist/{chunk-3M75HVIM.js.map → chunk-5J6DO4VW.js.map} +0 -0
- /package/dist/{chunk-UMYEY6BA.js.map → chunk-77YZFVQD.js.map} +0 -0
- /package/dist/{chunk-SX57ZIGM.js.map → chunk-AQSMNUKJ.js.map} +0 -0
- /package/dist/{chunk-B7YTQVAF.js.map → chunk-BR3TNSO3.js.map} +0 -0
- /package/dist/{chunk-MED6GNV3.js.map → chunk-C53RJ7AA.js.map} +0 -0
- /package/dist/{chunk-EEFTUZHZ.js.map → chunk-EN5MEPAS.js.map} +0 -0
- /package/dist/{chunk-B3YSTZZC.js.map → chunk-ES7WGE32.js.map} +0 -0
- /package/dist/{chunk-BRHU6J3C.js.map → chunk-FL2CJ5T5.js.map} +0 -0
- /package/dist/{chunk-3TM4FHTG.js.map → chunk-FXL63LDL.js.map} +0 -0
- /package/dist/{chunk-2MPXMJ2O.js.map → chunk-H2MDPOLG.js.map} +0 -0
- /package/dist/{chunk-A2NA377T.js.map → chunk-HRVPZMKK.js.map} +0 -0
- /package/dist/{chunk-6PVWDTEM.js.map → chunk-IMTWWA3N.js.map} +0 -0
- /package/dist/{chunk-YOVUXONB.js.map → chunk-K26SBQLO.js.map} +0 -0
- /package/dist/{chunk-EQSMVZGS.js.map → chunk-L65XGQKR.js.map} +0 -0
- /package/dist/{chunk-264XDRU7.js.map → chunk-MI7LKLD7.js.map} +0 -0
- /package/dist/{chunk-HB3YIAFD.js.map → chunk-MSUTHS2V.js.map} +0 -0
- /package/dist/{chunk-W2RXRWDB.js.map → chunk-QM3ZNOWJ.js.map} +0 -0
- /package/dist/{chunk-3H42U56X.js.map → chunk-RMMEYCEA.js.map} +0 -0
- /package/dist/{chunk-LZPRLHUE.js.map → chunk-S6GX7IJ2.js.map} +0 -0
- /package/dist/{chunk-T4RVCFWN.js.map → chunk-T2RPUNYP.js.map} +0 -0
- /package/dist/{chunk-WVCF7KFV.js.map → chunk-VEBEGZUV.js.map} +0 -0
- /package/dist/{chunk-AO6DXJUK.js.map → chunk-VEONZFTL.js.map} +0 -0
- /package/dist/{chunk-DGXW2ZFY.js.map → chunk-VFZF7LVY.js.map} +0 -0
- /package/dist/{chunk-N6CILY5A.js.map → chunk-WIJM6BX6.js.map} +0 -0
- /package/dist/{chunk-EERGAAGE.js.map → chunk-X6KXPRKI.js.map} +0 -0
- /package/dist/{chunk-QKMT6OOP.js.map → chunk-XSM3IBMG.js.map} +0 -0
- /package/dist/{load-agent-defs-LDSND43G.js.map → load-agent-defs-57YKPVQW.js.map} +0 -0
- /package/dist/{recompile-project-agents-GQLODH24.js.map → recompile-project-agents-IQD3HRRS.js.map} +0 -0
- /package/dist/{source-loader-TSF5VS6V.js.map → source-loader-KAWB76OH.js.map} +0 -0
|
@@ -7,19 +7,19 @@ import {
|
|
|
7
7
|
} from "./chunk-XVAQG2CV.js";
|
|
8
8
|
import {
|
|
9
9
|
useRowScroll
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FL2CJ5T5.js";
|
|
11
11
|
import {
|
|
12
12
|
showWarningsAsToast,
|
|
13
13
|
useWizardStore
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-K26SBQLO.js";
|
|
15
15
|
import {
|
|
16
16
|
matrix,
|
|
17
17
|
typedKeys
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-3QBOVV6A.js";
|
|
19
19
|
import {
|
|
20
20
|
CLI_COLORS,
|
|
21
21
|
UI_SYMBOLS
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-IV42Z63R.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/components/wizard/stack-selection.tsx
|
|
25
25
|
import { groupBy } from "remeda";
|
|
@@ -194,4 +194,4 @@ var StackSelection = ({ onCancel }) => {
|
|
|
194
194
|
export {
|
|
195
195
|
StackSelection
|
|
196
196
|
};
|
|
197
|
-
//# sourceMappingURL=chunk-
|
|
197
|
+
//# sourceMappingURL=chunk-VEBEGZUV.js.map
|
|
@@ -6,14 +6,14 @@ import {
|
|
|
6
6
|
verbose,
|
|
7
7
|
warn,
|
|
8
8
|
writeFile
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UNASGGW2.js";
|
|
10
10
|
import {
|
|
11
11
|
DEFAULT_PUBLIC_SOURCE_NAME,
|
|
12
12
|
DEFAULT_VERSION,
|
|
13
13
|
PLUGIN_MANIFEST_DIR,
|
|
14
14
|
PLUGIN_MANIFEST_FILE,
|
|
15
15
|
PUBLIC_CATALOGUE_PACKAGE
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-IV42Z63R.js";
|
|
17
17
|
|
|
18
18
|
// src/cli/lib/marketplace-generator.ts
|
|
19
19
|
import path from "path";
|
|
@@ -127,4 +127,4 @@ export {
|
|
|
127
127
|
writeMarketplace,
|
|
128
128
|
getMarketplaceStats
|
|
129
129
|
};
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
130
|
+
//# sourceMappingURL=chunk-VEONZFTL.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
useRowScroll
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FL2CJ5T5.js";
|
|
5
5
|
import {
|
|
6
6
|
KEY_SPACE
|
|
7
7
|
} from "./chunk-WTJ3AY33.js";
|
|
8
8
|
import {
|
|
9
9
|
CLI_COLORS,
|
|
10
10
|
UI_SYMBOLS
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-IV42Z63R.js";
|
|
12
12
|
|
|
13
13
|
// src/cli/components/wizard/checkbox-grid.tsx
|
|
14
14
|
import { Box, Text, useInput } from "ink";
|
|
@@ -108,4 +108,4 @@ var CheckboxGrid = ({
|
|
|
108
108
|
export {
|
|
109
109
|
CheckboxGrid
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-VFZF7LVY.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
execCommand,
|
|
4
4
|
getErrorMessage
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UNASGGW2.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/utils/open-url.ts
|
|
8
8
|
function browserOpenerCommand(platform, url) {
|
|
@@ -32,4 +32,4 @@ async function openUrl(url) {
|
|
|
32
32
|
export {
|
|
33
33
|
openUrl
|
|
34
34
|
};
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
35
|
+
//# sourceMappingURL=chunk-WIJM6BX6.js.map
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
} from "./chunk-WTJ3AY33.js";
|
|
10
10
|
import {
|
|
11
11
|
useSectionScroll
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MI7LKLD7.js";
|
|
13
13
|
import {
|
|
14
14
|
getSkillById
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3QBOVV6A.js";
|
|
16
16
|
import {
|
|
17
17
|
CLI_COLORS
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-IV42Z63R.js";
|
|
19
19
|
|
|
20
20
|
// src/cli/components/wizard/category-grid.tsx
|
|
21
21
|
import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
|
|
@@ -260,4 +260,4 @@ var CategoryGrid = ({
|
|
|
260
260
|
export {
|
|
261
261
|
CategoryGrid
|
|
262
262
|
};
|
|
263
|
-
//# sourceMappingURL=chunk-
|
|
263
|
+
//# sourceMappingURL=chunk-X6KXPRKI.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SummaryPanel
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4KVJJJG2.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/components/wizard/step-confirm.tsx
|
|
7
7
|
import { useInput } from "ink";
|
|
@@ -22,4 +22,4 @@ var StepConfirm = ({ onComplete, onBack }) => {
|
|
|
22
22
|
export {
|
|
23
23
|
StepConfirm
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
25
|
+
//# sourceMappingURL=chunk-XSM3IBMG.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
SEED_API_URL,
|
|
4
4
|
SEED_USER_AGENT,
|
|
5
5
|
readCarriedSkills
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-J2YG7P7L.js";
|
|
7
7
|
import {
|
|
8
8
|
ERROR_MESSAGES,
|
|
9
9
|
directoryExists,
|
|
@@ -11,20 +11,22 @@ import {
|
|
|
11
11
|
isScopePairCompatible,
|
|
12
12
|
loadProjectConfig,
|
|
13
13
|
readForkedFromMetadata,
|
|
14
|
-
resolveInstallPaths
|
|
15
|
-
|
|
14
|
+
resolveInstallPaths,
|
|
15
|
+
truncateText
|
|
16
|
+
} from "./chunk-UNASGGW2.js";
|
|
16
17
|
import {
|
|
17
18
|
typedEntries,
|
|
18
19
|
typedValues
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-3QBOVV6A.js";
|
|
20
21
|
import {
|
|
22
|
+
CLI_INVOKE_COMMAND,
|
|
21
23
|
DEFAULT_PUBLIC_SOURCE_NAME,
|
|
22
24
|
EJECT_SOURCE,
|
|
23
25
|
MATRIX_VERSION,
|
|
24
26
|
SEED_VERSION,
|
|
25
27
|
installableSeedPayloadSchema,
|
|
26
28
|
seedModelSchema
|
|
27
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-IV42Z63R.js";
|
|
28
30
|
|
|
29
31
|
// src/cli/lib/seed/installation-payload.ts
|
|
30
32
|
import path from "path";
|
|
@@ -203,8 +205,20 @@ function mapOrRefuse({ config, content }) {
|
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
// src/cli/lib/seed/publish-seed.ts
|
|
208
|
+
import { STATUS_CODES } from "http";
|
|
206
209
|
import { z } from "zod";
|
|
207
210
|
var mintedSchema = z.object({ id: z.string().min(1) });
|
|
211
|
+
var refusalSchema = z.object({ error: z.object({ message: z.string() }) });
|
|
212
|
+
var refusedIssuesSchema = z.array(
|
|
213
|
+
z.object({
|
|
214
|
+
path: z.array(z.union([z.string(), z.number()])),
|
|
215
|
+
message: z.string().min(1)
|
|
216
|
+
})
|
|
217
|
+
).min(1);
|
|
218
|
+
var EXPLANATION_BUDGET = 300;
|
|
219
|
+
var QUOTABLE_TYPE = "text/plain";
|
|
220
|
+
var CONTRACT_MISMATCH = 409;
|
|
221
|
+
var OUT_OF_DATE_AGAINST_STORE = `This CLI is out of date against the configuration store: it writes a version of the sharing contract the store does not serve, and that version travels inside the CLI rather than with the configuration. Re-run this command through '${CLI_INVOKE_COMMAND}@latest'.`;
|
|
208
222
|
async function publishSeedConfig(payload) {
|
|
209
223
|
const url = `${SEED_API_URL}/configs`;
|
|
210
224
|
let response;
|
|
@@ -223,9 +237,7 @@ async function publishSeedConfig(payload) {
|
|
|
223
237
|
} catch {
|
|
224
238
|
return { ok: false, error: `Could not reach ${SEED_API_URL} \u2014 check your connection.` };
|
|
225
239
|
}
|
|
226
|
-
if (!response.ok) {
|
|
227
|
-
return { ok: false, error: `Sharing this configuration failed (HTTP ${response.status}).` };
|
|
228
|
-
}
|
|
240
|
+
if (!response.ok) return { ok: false, error: await refusalMessage(response) };
|
|
229
241
|
let body;
|
|
230
242
|
try {
|
|
231
243
|
body = await response.json();
|
|
@@ -238,10 +250,60 @@ async function publishSeedConfig(payload) {
|
|
|
238
250
|
}
|
|
239
251
|
return { ok: true, id: minted.data.id };
|
|
240
252
|
}
|
|
253
|
+
async function refusalMessage(response) {
|
|
254
|
+
const refused = `Sharing this configuration failed (HTTP ${response.status}).`;
|
|
255
|
+
if (response.status === CONTRACT_MISMATCH) return `${refused} ${OUT_OF_DATE_AGAINST_STORE}`;
|
|
256
|
+
const explanation = explanationOf(response, await refusalBody(response));
|
|
257
|
+
return explanation === void 0 ? refused : `${refused} The store said: ${explanation}`;
|
|
258
|
+
}
|
|
259
|
+
async function refusalBody(response) {
|
|
260
|
+
try {
|
|
261
|
+
return await response.text();
|
|
262
|
+
} catch {
|
|
263
|
+
return void 0;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function jsonOf(text) {
|
|
267
|
+
try {
|
|
268
|
+
return JSON.parse(text);
|
|
269
|
+
} catch {
|
|
270
|
+
return void 0;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function explanationOf(response, body) {
|
|
274
|
+
if (body === void 0) return void 0;
|
|
275
|
+
const said = schemaIssuesIn(body) ?? quotableProseIn(response, body);
|
|
276
|
+
return said === void 0 ? void 0 : truncateText(said, EXPLANATION_BUDGET);
|
|
277
|
+
}
|
|
278
|
+
function schemaIssuesIn(body) {
|
|
279
|
+
const refusal = refusalSchema.safeParse(jsonOf(body));
|
|
280
|
+
if (!refusal.success) return void 0;
|
|
281
|
+
const issues = refusedIssuesSchema.safeParse(jsonOf(refusal.data.error.message));
|
|
282
|
+
if (!issues.success) return void 0;
|
|
283
|
+
return issues.data.map(sentenceOf).join("; ");
|
|
284
|
+
}
|
|
285
|
+
function quotableProseIn(response, body) {
|
|
286
|
+
if (!arrivedAsText(response)) return void 0;
|
|
287
|
+
const said = body.trim();
|
|
288
|
+
if (said === "") return void 0;
|
|
289
|
+
if (restatesItsOwnStatus(said, response.status)) return void 0;
|
|
290
|
+
return said;
|
|
291
|
+
}
|
|
292
|
+
function arrivedAsText(response) {
|
|
293
|
+
return (response.headers.get("content-type") ?? "").startsWith(QUOTABLE_TYPE);
|
|
294
|
+
}
|
|
295
|
+
function restatesItsOwnStatus(said, status) {
|
|
296
|
+
const reason = STATUS_CODES[status];
|
|
297
|
+
return reason !== void 0 && said.toLowerCase() === reason.toLowerCase();
|
|
298
|
+
}
|
|
299
|
+
function sentenceOf(issue) {
|
|
300
|
+
const path2 = issue.path.join(".");
|
|
301
|
+
return path2 === "" ? issue.message : `${path2}: ${issue.message}`;
|
|
302
|
+
}
|
|
241
303
|
|
|
242
304
|
export {
|
|
243
305
|
seedPayloadForInstallation,
|
|
244
306
|
skillsAuthoredHere,
|
|
245
307
|
publishSeedConfig
|
|
246
308
|
};
|
|
247
|
-
//# sourceMappingURL=chunk-
|
|
309
|
+
//# sourceMappingURL=chunk-ZFPQM63K.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/seed/installation-payload.ts","../src/cli/lib/seed/config-to-seed.ts","../src/cli/lib/seed/publish-seed.ts"],"sourcesContent":["import path from \"path\";\n\nimport { configToSeedPayload, isInstalled } from \"./config-to-seed.js\";\nimport { readCarriedSkills } from \"./external-skills.js\";\nimport { EJECT_SOURCE } from \"../../consts.js\";\nimport { loadProjectConfig } from \"../configuration/project-config.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { readForkedFromMetadata } from \"../skills/skill-metadata.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { directoryExists } from \"../../utils/fs.js\";\nimport { ERROR_MESSAGES } from \"../../utils/messages.js\";\n\nimport type { ContentReading, OwnedSkillDir } from \"./external-skills.js\";\nimport type { ProjectConfig, SkillConfig, SkillId } from \"../../types/index.js\";\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/**\n * A payload ready to post, and what it will install — counted the way the sharer's own screens\n * count it, off the payload rather than off the config, so what a caller announces and what it\n * posts cannot disagree.\n */\nexport type InstallationPayload =\n { ok: true; payload: SeedPayload; skills: number; agents: number } | { ok: false; error: string };\n\n/** The config to map, or the sentence explaining why there is none to map. */\ntype InstalledConfig = { ok: true; config: ProjectConfig } | { ok: false; error: string };\n\n/** The mapped payload, or every line naming something the contract cannot carry. */\ntype MappedPayload = { ok: true; payload: SeedPayload } | { ok: false; error: string };\n\n/** The installation as the round trip sees it: what it owns, and what it has to carry with it. */\ntype RoundTrip = { config: ProjectConfig; content: ContentReading };\n\n/**\n * What the round trip makes of one installed entry: whether it travels at all, and whether its\n * bytes travel with it.\n */\ntype SkillJudgement = { skill: SkillConfig; owned: boolean; carried: OwnedSkillDir | null };\n\n/**\n * Read, map, refuse — everything that can fail locally, failing before anybody spends a write.\n *\n * Shared by the two commands that mint an id for what is installed here: `share`, which reports\n * the id, and `edit --ui`, which opens it. They are one operation with two endings, and this is\n * the half that has to be identical — two spellings of \"the installation in this directory\"\n * would mint two different ids for one project, and only one of them would be true.\n *\n * Every failure is a message rather than a throw, because nothing has been written by the time\n * it runs: the caller's only job is to explain, and both callers explain the same way.\n */\nexport async function seedPayloadForInstallation(projectDir: string): Promise<InstallationPayload> {\n const installed = await readInstalledConfig(projectDir);\n if (!installed.ok) return installed;\n\n const mapped = mapOrRefuse(await readRoundTrip(installed.config, projectDir));\n if (!mapped.ok) return mapped;\n\n const { payload } = mapped;\n const skills = Object.keys(payload.skills).length;\n const agents = Object.keys(payload.agents).length;\n\n // The same guard `init --from` applies on arrival, applied here before the write instead of\n // there after it. A sub-agent is installable on its own — it has front-matter, a prompt and a\n // compiled file without owning a single skill — so only a configuration with neither skills\n // nor sub-agents is nothing to carry.\n if (skills === 0 && agents === 0) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n\n return { ok: true, payload, skills, agents };\n}\n\n/**\n * The installation this directory has: its own configuration, or the global one it inherits.\n *\n * That is the config every other command reads here, and it carries the entries of BOTH scopes\n * with each entry's own scope on it — which is exactly what the wire keys by. So a payload minted\n * from a project describes the whole of what is installed for it rather than half of it, and the\n * receiver puts each entry back where this one had it.\n *\n * A config file that exists but cannot be loaded is a fault, not an absence, so its own message\n * is reported rather than read as \"not installed\".\n */\nasync function readInstalledConfig(projectDir: string): Promise<InstalledConfig> {\n try {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n return { ok: true, config: loaded.config };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n\n/**\n * The installation minus what the round trip does not own, plus the content it has to take along.\n *\n * `forkedFrom` decides ownership, and the round trip leaves what it does not own alone. The CLI\n * stamps that key into every skill directory it writes — an ejected catalogue skill, and a skill\n * a payload carried inline — while a skill the user wrote by hand into `.claude/skills/` carries\n * none. So absence of the key is not the whole answer and provenance is: what the CLI put there\n * says so on disk, and what a person put there says nothing because nothing forked it.\n *\n * A user-authored skill is therefore neither carried nor refused — it is simply outside the\n * round trip, and nothing about leaving it home is lossy because it was never in scope. Dropping\n * it here rather than in a command is what keeps `share` and `edit --ui`, which mint an id from\n * the same directory, from disagreeing about a single project.\n *\n * The stack rows naming a dropped skill go with it: `configToSeedPayload` keys assignments by\n * the skills it carries, so a row whose skill is gone is gone too.\n *\n * One walk answers both questions, because they are asked of the same file: whether the CLI put\n * this directory here, and — for the one kind of skill no catalogue can resolve — where its bytes\n * came from, so they can travel a second time.\n */\nasync function readRoundTrip(config: ProjectConfig, projectDir: string): Promise<RoundTrip> {\n const owned = (await judgeSkills(config, projectDir)).filter((entry) => entry.owned);\n\n return {\n config: { ...config, skills: owned.map((entry) => entry.skill) },\n content: await readCarriedSkills(owned.flatMap((entry) => entry.carried ?? [])),\n };\n}\n\n/** Every installed entry, judged. One walk of the disk, whichever half of the trip is asking. */\nfunction judgeSkills(config: ProjectConfig, projectDir: string): Promise<SkillJudgement[]> {\n return Promise.all(config.skills.map((skill) => judgeSkill(skill, projectDir)));\n}\n\n/**\n * The installed skills the round trip does NOT own — the user's own work, sitting in\n * `.claude/skills/` with no `forkedFrom` to say the CLI put it there.\n *\n * The producer already drops these on the way out, so no payload minted here ever named one.\n * This is the same judgement read by the other half: `edit --from` applies a payload\n * destructively, and a payload that made no statement about a skill cannot be read as an\n * instruction to delete it. Both halves ask {@link judgeSkill}, so \"outside the round trip\" has\n * one definition and cannot come to mean two things on one machine.\n */\nexport async function skillsAuthoredHere(\n config: ProjectConfig,\n projectDir: string,\n): Promise<Set<SkillId>> {\n const judged = await judgeSkills(config, projectDir);\n return new Set(judged.filter((entry) => !entry.owned).map((entry) => entry.skill.id));\n}\n\n/** The entry travels and no directory is read for it: a row naming an id is the whole of it. */\nfunction travelsAsAnId(skill: SkillConfig): SkillJudgement {\n return { skill, owned: true, carried: null };\n}\n\n/**\n * How one installed entry answers to the round trip — asked of the disk, offline, exactly as\n * `uninstall` asks it before removing anything.\n *\n * Only a directory that EXISTS and carries no provenance is somebody's own work, and that is the\n * one thing this excludes; each guard below says why the case above it never gets that far.\n */\nasync function judgeSkill(skill: SkillConfig, projectDir: string): Promise<SkillJudgement> {\n // A marketplace skill has no local directory to hold provenance and needs none: the marketplace\n // is what installs it again.\n if (skill.origin !== EJECT_SOURCE) return travelsAsAnId(skill);\n // A tombstone is a statement about something that is NOT installed here, so there are no bytes\n // of it to carry — and a refusal raised over them would refuse a share for a skill it is not\n // sharing.\n if (!isInstalled(skill)) return travelsAsAnId(skill);\n\n const skillsDir = resolveInstallPaths(projectDir, skill.scope).skillsDir;\n const skillDir = path.join(skillsDir, skill.id);\n // A configuration recording an install that is not there is evidence of nothing rather than\n // evidence of authorship, so it travels as the configuration records it.\n if (!(await directoryExists(skillDir))) return travelsAsAnId(skill);\n\n const provenance = await readForkedFromMetadata(skillDir);\n if (provenance === null) return { skill, owned: false, carried: null };\n\n return { skill, owned: true, carried: { id: skill.id, skillDir, provenance } };\n}\n\n/**\n * The mapping, with its refusals turned into this module's own currency.\n *\n * `configToSeedPayload` throws, and what it throws is a list: every line names something this\n * installation has that a shared configuration cannot say. That is a message for the user, not a\n * fault to propagate — the alternative is worse than a failed command, because a payload quietly\n * missing what it could not say still mints an id, and that id installs a configuration nobody\n * chose.\n */\nfunction mapOrRefuse({ config, content }: RoundTrip): MappedPayload {\n try {\n return { ok: true, payload: configToSeedPayload(config, content) };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n","import { MATRIX_VERSION } from \"@workspace/matrix\";\nimport {\n SEED_VERSION,\n installableSeedPayloadSchema,\n seedModelSchema,\n} from \"@workspace/matrix/seed\";\n\nimport { DEFAULT_PUBLIC_SOURCE_NAME, EJECT_SOURCE } from \"../../consts.js\";\nimport { isScopePairCompatible } from \"../configuration/config-generator.js\";\nimport { typedEntries, typedValues } from \"../../utils/typed-object.js\";\n\nimport type { ContentReading } from \"./external-skills.js\";\nimport type {\n AgentScopeConfig,\n ProjectConfig,\n SkillConfig,\n SkillScope,\n} from \"../../types/config.js\";\nimport type { ModelName } from \"../../types/matrix.js\";\nimport type { SkillId } from \"../../types/skills.js\";\nimport type {\n SeedAgent,\n SeedLoadState,\n SeedModel,\n SeedPayload,\n SeedSkill,\n} from \"@workspace/matrix/seed\";\n\n/** Sub-agent name -> load state for one skill: the shape the wire keys by skill. */\ntype SeedAssignments = Record<string, SeedLoadState>;\n\n/** What one walk of `config.stack` yields: the wire's assignments, and the rows that cannot be one. */\ntype StackReading = {\n assignments: Map<SkillId, SeedAssignments>;\n /** Pairs the config model has nowhere to write, worded for the refusal. */\n unwritable: string[];\n};\n\n/**\n * An installed entry. An excluded one is a tombstone — a statement about something that is NOT\n * installed here — and presence is selection on the wire, so it has nothing to say. Nothing is\n * lost by leaving it home either: `init --from` installs into a clean setup, where there is no\n * global install for a tombstone to mask.\n *\n * Exported because the reader that gathers what an installation CARRIES has to agree with the\n * mapper about what it installs: content read for an entry this payload will not name is content\n * paid for by nobody, and a refusal raised over it would refuse a share for a skill it is not\n * sharing.\n */\nexport function isInstalled(entry: { excluded?: boolean }): boolean {\n return !entry.excluded;\n}\n\n/**\n * Whether a skill from this origin obliges the payload to name a marketplace.\n *\n * Two do not. An ejected copy travels with the project, and the default public catalogue is what\n * an absent ref already means — so neither puts a ref on the wire, and two identical selections\n * cannot mint two different ids over one.\n */\nfunction needsMarketplaceNamed(origin: string): boolean {\n return origin !== EJECT_SOURCE && origin !== DEFAULT_PUBLIC_SOURCE_NAME;\n}\n\n/**\n * Asked of the contract's own enum rather than spelled out here, so widening `MODEL_NAMES`\n * without widening the wire cannot slip past as a silently dropped pin.\n */\nfunction isSeedModel(model: ModelName): model is SeedModel {\n return seedModelSchema.safeParse(model).success;\n}\n\n/** The wire spells as an enum what a stack entry spells as a boolean, and an absent flag is lazy. */\nfunction seedLoadState(preloaded: boolean | undefined): SeedLoadState {\n return preloaded === true ? \"preloaded\" : \"lazy\";\n}\n\nfunction unnameableOriginMessage(skill: SkillConfig): string {\n return `${skill.id} comes from the marketplace '${skill.origin}', and this installation does not record where that marketplace is fetched from`;\n}\n\nfunction unnameableModelMessage(agent: AgentScopeConfig[\"name\"], model: ModelName): string {\n return `${agent} pins model '${model}', which this contract has no word for — leaving it out would say \"keep the sub-agent's own metadata\", which is a different instruction`;\n}\n\nfunction unwritablePairMessage(skillId: SkillId, agent: string): string {\n return `${skillId} -> ${agent}: a project-scoped skill never reaches a sub-agent that rests at global scope`;\n}\n\n/**\n * Names everything the contract cannot carry at once, not one thing at a time: a sharer who fixes\n * one only to be refused for the next learns nothing the first message could not have told them.\n *\n * The refusal exists because the alternative is worse than a failed command. A payload quietly\n * missing what it could not say still mints an id, and that id installs a configuration nobody\n * chose — with nothing on either side saying so.\n */\nfunction unshareableConfigError(unshareable: string[]): string {\n return [\n \"This installation cannot be shared as it stands — a shared configuration has no way to carry:\",\n ...unshareable.map((line) => ` ${line}`),\n \"Sharing it anyway would mint an id that installs something else.\",\n ].join(\"\\n\");\n}\n\n/** The ref a payload has to carry, and the skills no ref this config holds can account for. */\ntype MarketplaceReading = {\n /** Absent when nothing installed here came from a marketplace. */\n ref: string | undefined;\n unnameable: string[];\n};\n\n/**\n * Whether the marketplace this installation reads is the one `skill` came from.\n *\n * A skill's `origin` is a marketplace's NAME, `config.marketplace` is the ref it was fetched from,\n * and `marketplaceName` is what joins them — the name the install read out of that repository's\n * own manifest. Without both halves agreeing, the ref would send the receiver to a repository that\n * never served this skill, which is the same silent swap under a different spelling.\n */\nfunction isRecordedMarketplace(config: ProjectConfig, skill: SkillConfig): boolean {\n return config.marketplace !== undefined && skill.origin === config.marketplaceName;\n}\n\n/** Which marketplace the payload names, decided by the skills that oblige it to name one. */\nfunction readMarketplace(config: ProjectConfig, skills: SkillConfig[]): MarketplaceReading {\n const served = skills.filter((skill) => needsMarketplaceNamed(skill.origin));\n if (served.length === 0) return { ref: undefined, unnameable: [] };\n\n const unaccounted = served.filter((skill) => !isRecordedMarketplace(config, skill));\n if (unaccounted.length > 0) {\n return { ref: undefined, unnameable: unaccounted.map(unnameableOriginMessage) };\n }\n\n return { ref: config.marketplace, unnameable: [] };\n}\n\nfunction unnameableModels(agents: AgentScopeConfig[]): string[] {\n return agents.flatMap((agent) =>\n agent.model !== undefined && !isSeedModel(agent.model)\n ? [unnameableModelMessage(agent.name, agent.model)]\n : [],\n );\n}\n\n/**\n * Turns `config.stack` inside out: it is keyed by sub-agent and this contract is keyed by skill.\n *\n * Rows naming a sub-agent or a skill this configuration does not install are dropped rather than\n * refused, because they are already no part of what is installed — `compile` warns about exactly\n * those and leaves them out of the agents it writes, so carrying them would share more than this\n * project has.\n *\n * A row the config model cannot write is the opposite case and is collected for the refusal: the\n * decoder turns the same pair away on the way back in, so minting it would produce an id that\n * cannot be installed.\n */\nfunction readStack(\n stack: ProjectConfig[\"stack\"],\n skillScopes: Map<SkillId, SkillScope>,\n agentScopes: Map<string, SkillScope>,\n): StackReading {\n const assignments = new Map<SkillId, SeedAssignments>();\n const unwritable: string[] = [];\n\n for (const [agent, agentStack] of typedEntries(stack ?? {})) {\n const agentScope = agentScopes.get(agent);\n if (agentScope === undefined) continue;\n\n for (const categoryAssignments of typedValues(agentStack)) {\n for (const { id, preloaded } of categoryAssignments) {\n const skillScope = skillScopes.get(id);\n if (skillScope === undefined) continue;\n\n if (!isScopePairCompatible(skillScope, agentScope)) {\n unwritable.push(unwritablePairMessage(id, agent));\n continue;\n }\n\n const forSkill = assignments.get(id) ?? {};\n forSkill[agent] = seedLoadState(preloaded);\n assignments.set(id, forSkill);\n }\n }\n }\n\n return { assignments, unwritable };\n}\n\nfunction toSeedSkill(skill: SkillConfig, assignments: SeedAssignments | undefined): SeedSkill {\n return {\n // \"eject\" is the project's own copy; anything else is a plugin the marketplace serves, and\n // which marketplace that is has already had to be one the envelope's ref accounts for.\n install: skill.origin === EJECT_SOURCE ? \"eject\" : \"plugin\",\n scope: skill.scope,\n assignments: assignments ?? {},\n };\n}\n\n/**\n * A sub-agent's own row, and it always says `on`.\n *\n * The web app pins `on` only where a person did, because there an agent switched on by its rows is\n * already implied by them. An installed config is not an inference — every sub-agent it names was\n * chosen and has a compiled file on disk — so saying so outright is what carries the one that owns\n * no skill, which is the only thing the agents map can do that assignments cannot.\n */\nfunction toSeedAgent(agent: AgentScopeConfig): SeedAgent {\n return {\n on: true,\n scope: agent.scope,\n ...(agent.model !== undefined && isSeedModel(agent.model) && { model: agent.model }),\n ...(agent.effort !== undefined && { effort: agent.effort }),\n };\n}\n\n/**\n * Turns the installation this directory records into the payload the config store holds, so the\n * CLI can mint an id rather than only consume one.\n *\n * The inverse of `seedToWizardResult` in `seed-to-wizard.ts`, and held to it: a\n * payload minted here and decoded there has to describe the same install. That is why the scope\n * of every skill and sub-agent travels per entry rather than being implied, why the whole stack\n * is carried as per-`(skill, sub-agent)` assignments, and why nothing here leans on a wire default\n * the decoder would have to guess back.\n *\n * What it will not do is share a thinner configuration than the one installed. Anything the\n * contract cannot state is refused by name — see {@link unshareableConfigError} — because the\n * failure mode of the alternative is an id that silently installs something else.\n *\n * `stackId` is always null. A saved config records a stack's expansion and never the id it came\n * from, and the assignments above carry that expansion in full; naming an id this module invented\n * would make the receiver overlay a stack's own preload flags over the curation being shared.\n *\n * `description` is what a resolvable id would have supplied that the assignments do not, so it is\n * carried directly instead. That is the whole of the trade: the sentence travels, the roster the id\n * would have dragged behind it does not.\n *\n * `marketplace` is the one field carried for the payload rather than for an entry, because the\n * receiver loads one catalogue before it reads a single skill row — see {@link readMarketplace}.\n *\n * `carried` arrives as an argument because it is read off disk and this mapping touches none:\n * every id above is resolved by the receiver against a catalogue it already has, and the entries\n * in `carried` are the ones that answer to no catalogue in either direction. Stated rather than\n * defaulted, because a producer that forgot the content is exactly the defect this closed.\n */\nexport function configToSeedPayload(config: ProjectConfig, carried: ContentReading): SeedPayload {\n const skills = config.skills.filter(isInstalled);\n const agents = config.agents.filter(isInstalled);\n const skillScopes = new Map(skills.map((skill) => [skill.id, skill.scope]));\n const agentScopes = new Map<string, SkillScope>(agents.map((agent) => [agent.name, agent.scope]));\n\n const { assignments, unwritable } = readStack(config.stack, skillScopes, agentScopes);\n const marketplace = readMarketplace(config, skills);\n\n const unshareable = [\n ...marketplace.unnameable,\n ...unnameableModels(agents),\n ...unwritable,\n ...carried.uncarryable,\n ];\n if (unshareable.length > 0) throw new Error(unshareableConfigError(unshareable));\n\n // Parsed rather than merely assembled, exactly as the web app's encoder is: it makes \"the JSON\n // the store will hold\" literal, and it is the one gate that catches a field whose values have\n // drifted out of the wire's enums since this module last named them.\n //\n // The INSTALLABLE half of the contract, which is the schema the store's POST route declares —\n // the lenient one exists for READING links already out in the world, and this module only ever\n // mints. It refuses nothing the refusal above permits, and that is the point: it is the belt\n // over those braces, so the day this module's own rule and the wire's disagree, the mint fails\n // loudly here instead of minting an id that cannot be installed.\n return installableSeedPayloadSchema.parse({\n v: SEED_VERSION,\n matrixVersion: MATRIX_VERSION,\n stackId: null,\n // Absent rather than empty, for the reason the marketplace ref is: an id is the hash of its\n // body, so a key meaning what its absence already means would remint every ordinary payload.\n ...(config.description !== undefined && { description: config.description }),\n ...(marketplace.ref !== undefined && { marketplace: marketplace.ref }),\n skills: Object.fromEntries(\n skills.map((skill) => [skill.id, toSeedSkill(skill, assignments.get(skill.id))]),\n ),\n // Absent rather than empty, for the reason the marketplace ref is: an id is the hash of its\n // body, so a key meaning what its absence already means would remint every ordinary payload.\n ...(Object.keys(carried.external).length > 0 && { external: carried.external }),\n agents: Object.fromEntries(agents.map((agent) => [agent.name, toSeedAgent(agent)])),\n });\n}\n","import { z } from \"zod\";\n\nimport { SEED_API_URL, SEED_USER_AGENT } from \"./fetch-seed.js\";\n\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/**\n * The store answers a stored configuration with its content-addressed id and nothing else.\n * Revalidated rather than read off the response type, because that type describes the worker this\n * CLI was built against and what answers is whatever is deployed.\n */\nconst mintedSchema = z.object({ id: z.string().min(1) });\n\nexport type PublishSeedResult = { ok: true; id: string } | { ok: false; error: string };\n\n/**\n * Stores a configuration and returns the id it was given.\n *\n * The outbound half of the boundary `fetchSeedConfig` in `fetch-seed.ts` owns the inbound half\n * of, and it keeps the same posture: every failure is a message rather than a throw.\n * Nothing local has been written by the time this runs, so there is nothing to roll back and the\n * caller's only job is to explain.\n *\n * The id is the payload's own hash, so re-sharing an unchanged configuration returns the id it\n * had — the store spends no write, and a caller can share as often as it likes.\n */\nexport async function publishSeedConfig(payload: SeedPayload): Promise<PublishSeedResult> {\n const url = `${SEED_API_URL}/configs`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n // The same signal the fetch half sends: it is the only thing that tells the store a\n // configuration came from the CLI rather than from a browser.\n \"user-agent\": SEED_USER_AGENT,\n },\n body: JSON.stringify(payload),\n });\n } catch {\n return { ok: false, error: `Could not reach ${SEED_API_URL} — check your connection.` };\n }\n\n if (!response.ok) {\n return { ok: false, error: `Sharing this configuration failed (HTTP ${response.status}).` };\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 minted = mintedSchema.safeParse(body);\n if (!minted.success) {\n // Reporting success here would print an id nobody can install and tell the user to use it.\n return { ok: false, error: \"The configuration store did not return an id for this share.\" };\n }\n\n return { ok: true, id: minted.data.id };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/lib/seed/installation-payload.ts","../src/cli/lib/seed/config-to-seed.ts","../src/cli/lib/seed/publish-seed.ts"],"sourcesContent":["import path from \"path\";\n\nimport { configToSeedPayload, isInstalled } from \"./config-to-seed.js\";\nimport { readCarriedSkills } from \"./external-skills.js\";\nimport { EJECT_SOURCE } from \"../../consts.js\";\nimport { loadProjectConfig } from \"../configuration/project-config.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { readForkedFromMetadata } from \"../skills/skill-metadata.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { directoryExists } from \"../../utils/fs.js\";\nimport { ERROR_MESSAGES } from \"../../utils/messages.js\";\n\nimport type { ContentReading, OwnedSkillDir } from \"./external-skills.js\";\nimport type { ProjectConfig, SkillConfig, SkillId } from \"../../types/index.js\";\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/**\n * A payload ready to post, and what it will install — counted the way the sharer's own screens\n * count it, off the payload rather than off the config, so what a caller announces and what it\n * posts cannot disagree.\n */\nexport type InstallationPayload =\n { ok: true; payload: SeedPayload; skills: number; agents: number } | { ok: false; error: string };\n\n/** The config to map, or the sentence explaining why there is none to map. */\ntype InstalledConfig = { ok: true; config: ProjectConfig } | { ok: false; error: string };\n\n/** The mapped payload, or every line naming something the contract cannot carry. */\ntype MappedPayload = { ok: true; payload: SeedPayload } | { ok: false; error: string };\n\n/** The installation as the round trip sees it: what it owns, and what it has to carry with it. */\ntype RoundTrip = { config: ProjectConfig; content: ContentReading };\n\n/**\n * What the round trip makes of one installed entry: whether it travels at all, and whether its\n * bytes travel with it.\n */\ntype SkillJudgement = { skill: SkillConfig; owned: boolean; carried: OwnedSkillDir | null };\n\n/**\n * Read, map, refuse — everything that can fail locally, failing before anybody spends a write.\n *\n * Shared by the two commands that mint an id for what is installed here: `share`, which reports\n * the id, and `edit --ui`, which opens it. They are one operation with two endings, and this is\n * the half that has to be identical — two spellings of \"the installation in this directory\"\n * would mint two different ids for one project, and only one of them would be true.\n *\n * Every failure is a message rather than a throw, because nothing has been written by the time\n * it runs: the caller's only job is to explain, and both callers explain the same way.\n */\nexport async function seedPayloadForInstallation(projectDir: string): Promise<InstallationPayload> {\n const installed = await readInstalledConfig(projectDir);\n if (!installed.ok) return installed;\n\n const mapped = mapOrRefuse(await readRoundTrip(installed.config, projectDir));\n if (!mapped.ok) return mapped;\n\n const { payload } = mapped;\n const skills = Object.keys(payload.skills).length;\n const agents = Object.keys(payload.agents).length;\n\n // The same guard `init --from` applies on arrival, applied here before the write instead of\n // there after it. A sub-agent is installable on its own — it has front-matter, a prompt and a\n // compiled file without owning a single skill — so only a configuration with neither skills\n // nor sub-agents is nothing to carry.\n if (skills === 0 && agents === 0) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n\n return { ok: true, payload, skills, agents };\n}\n\n/**\n * The installation this directory has: its own configuration, or the global one it inherits.\n *\n * That is the config every other command reads here, and it carries the entries of BOTH scopes\n * with each entry's own scope on it — which is exactly what the wire keys by. So a payload minted\n * from a project describes the whole of what is installed for it rather than half of it, and the\n * receiver puts each entry back where this one had it.\n *\n * A config file that exists but cannot be loaded is a fault, not an absence, so its own message\n * is reported rather than read as \"not installed\".\n */\nasync function readInstalledConfig(projectDir: string): Promise<InstalledConfig> {\n try {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n return { ok: true, config: loaded.config };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n\n/**\n * The installation minus what the round trip does not own, plus the content it has to take along.\n *\n * `forkedFrom` decides ownership, and the round trip leaves what it does not own alone. The CLI\n * stamps that key into every skill directory it writes — an ejected catalogue skill, and a skill\n * a payload carried inline — while a skill the user wrote by hand into `.claude/skills/` carries\n * none. So absence of the key is not the whole answer and provenance is: what the CLI put there\n * says so on disk, and what a person put there says nothing because nothing forked it.\n *\n * A user-authored skill is therefore neither carried nor refused — it is simply outside the\n * round trip, and nothing about leaving it home is lossy because it was never in scope. Dropping\n * it here rather than in a command is what keeps `share` and `edit --ui`, which mint an id from\n * the same directory, from disagreeing about a single project.\n *\n * The stack rows naming a dropped skill go with it: `configToSeedPayload` keys assignments by\n * the skills it carries, so a row whose skill is gone is gone too.\n *\n * One walk answers both questions, because they are asked of the same file: whether the CLI put\n * this directory here, and — for the one kind of skill no catalogue can resolve — where its bytes\n * came from, so they can travel a second time.\n */\nasync function readRoundTrip(config: ProjectConfig, projectDir: string): Promise<RoundTrip> {\n const owned = (await judgeSkills(config, projectDir)).filter((entry) => entry.owned);\n\n return {\n config: { ...config, skills: owned.map((entry) => entry.skill) },\n content: await readCarriedSkills(owned.flatMap((entry) => entry.carried ?? [])),\n };\n}\n\n/** Every installed entry, judged. One walk of the disk, whichever half of the trip is asking. */\nfunction judgeSkills(config: ProjectConfig, projectDir: string): Promise<SkillJudgement[]> {\n return Promise.all(config.skills.map((skill) => judgeSkill(skill, projectDir)));\n}\n\n/**\n * The installed skills the round trip does NOT own — the user's own work, sitting in\n * `.claude/skills/` with no `forkedFrom` to say the CLI put it there.\n *\n * The producer already drops these on the way out, so no payload minted here ever named one.\n * This is the same judgement read by the other half: `edit --from` applies a payload\n * destructively, and a payload that made no statement about a skill cannot be read as an\n * instruction to delete it. Both halves ask {@link judgeSkill}, so \"outside the round trip\" has\n * one definition and cannot come to mean two things on one machine.\n */\nexport async function skillsAuthoredHere(\n config: ProjectConfig,\n projectDir: string,\n): Promise<Set<SkillId>> {\n const judged = await judgeSkills(config, projectDir);\n return new Set(judged.filter((entry) => !entry.owned).map((entry) => entry.skill.id));\n}\n\n/** The entry travels and no directory is read for it: a row naming an id is the whole of it. */\nfunction travelsAsAnId(skill: SkillConfig): SkillJudgement {\n return { skill, owned: true, carried: null };\n}\n\n/**\n * How one installed entry answers to the round trip — asked of the disk, offline, exactly as\n * `uninstall` asks it before removing anything.\n *\n * Only a directory that EXISTS and carries no provenance is somebody's own work, and that is the\n * one thing this excludes; each guard below says why the case above it never gets that far.\n */\nasync function judgeSkill(skill: SkillConfig, projectDir: string): Promise<SkillJudgement> {\n // A marketplace skill has no local directory to hold provenance and needs none: the marketplace\n // is what installs it again.\n if (skill.origin !== EJECT_SOURCE) return travelsAsAnId(skill);\n // A tombstone is a statement about something that is NOT installed here, so there are no bytes\n // of it to carry — and a refusal raised over them would refuse a share for a skill it is not\n // sharing.\n if (!isInstalled(skill)) return travelsAsAnId(skill);\n\n const skillsDir = resolveInstallPaths(projectDir, skill.scope).skillsDir;\n const skillDir = path.join(skillsDir, skill.id);\n // A configuration recording an install that is not there is evidence of nothing rather than\n // evidence of authorship, so it travels as the configuration records it.\n if (!(await directoryExists(skillDir))) return travelsAsAnId(skill);\n\n const provenance = await readForkedFromMetadata(skillDir);\n if (provenance === null) return { skill, owned: false, carried: null };\n\n return { skill, owned: true, carried: { id: skill.id, skillDir, provenance } };\n}\n\n/**\n * The mapping, with its refusals turned into this module's own currency.\n *\n * `configToSeedPayload` throws, and what it throws is a list: every line names something this\n * installation has that a shared configuration cannot say. That is a message for the user, not a\n * fault to propagate — the alternative is worse than a failed command, because a payload quietly\n * missing what it could not say still mints an id, and that id installs a configuration nobody\n * chose.\n */\nfunction mapOrRefuse({ config, content }: RoundTrip): MappedPayload {\n try {\n return { ok: true, payload: configToSeedPayload(config, content) };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n","import { MATRIX_VERSION } from \"@workspace/matrix\";\nimport {\n SEED_VERSION,\n installableSeedPayloadSchema,\n seedModelSchema,\n} from \"@workspace/matrix/seed\";\n\nimport { DEFAULT_PUBLIC_SOURCE_NAME, EJECT_SOURCE } from \"../../consts.js\";\nimport { isScopePairCompatible } from \"../configuration/config-generator.js\";\nimport { typedEntries, typedValues } from \"../../utils/typed-object.js\";\n\nimport type { ContentReading } from \"./external-skills.js\";\nimport type {\n AgentScopeConfig,\n ProjectConfig,\n SkillConfig,\n SkillScope,\n} from \"../../types/config.js\";\nimport type { ModelName } from \"../../types/matrix.js\";\nimport type { SkillId } from \"../../types/skills.js\";\nimport type {\n SeedAgent,\n SeedLoadState,\n SeedModel,\n SeedPayload,\n SeedSkill,\n} from \"@workspace/matrix/seed\";\n\n/** Sub-agent name -> load state for one skill: the shape the wire keys by skill. */\ntype SeedAssignments = Record<string, SeedLoadState>;\n\n/** What one walk of `config.stack` yields: the wire's assignments, and the rows that cannot be one. */\ntype StackReading = {\n assignments: Map<SkillId, SeedAssignments>;\n /** Pairs the config model has nowhere to write, worded for the refusal. */\n unwritable: string[];\n};\n\n/**\n * An installed entry. An excluded one is a tombstone — a statement about something that is NOT\n * installed here — and presence is selection on the wire, so it has nothing to say. Nothing is\n * lost by leaving it home either: `init --from` installs into a clean setup, where there is no\n * global install for a tombstone to mask.\n *\n * Exported because the reader that gathers what an installation CARRIES has to agree with the\n * mapper about what it installs: content read for an entry this payload will not name is content\n * paid for by nobody, and a refusal raised over it would refuse a share for a skill it is not\n * sharing.\n */\nexport function isInstalled(entry: { excluded?: boolean }): boolean {\n return !entry.excluded;\n}\n\n/**\n * Whether a skill from this origin obliges the payload to name a marketplace.\n *\n * Two do not. An ejected copy travels with the project, and the default public catalogue is what\n * an absent ref already means — so neither puts a ref on the wire, and two identical selections\n * cannot mint two different ids over one.\n */\nfunction needsMarketplaceNamed(origin: string): boolean {\n return origin !== EJECT_SOURCE && origin !== DEFAULT_PUBLIC_SOURCE_NAME;\n}\n\n/**\n * Asked of the contract's own enum rather than spelled out here, so widening `MODEL_NAMES`\n * without widening the wire cannot slip past as a silently dropped pin.\n */\nfunction isSeedModel(model: ModelName): model is SeedModel {\n return seedModelSchema.safeParse(model).success;\n}\n\n/** The wire spells as an enum what a stack entry spells as a boolean, and an absent flag is lazy. */\nfunction seedLoadState(preloaded: boolean | undefined): SeedLoadState {\n return preloaded === true ? \"preloaded\" : \"lazy\";\n}\n\nfunction unnameableOriginMessage(skill: SkillConfig): string {\n return `${skill.id} comes from the marketplace '${skill.origin}', and this installation does not record where that marketplace is fetched from`;\n}\n\nfunction unnameableModelMessage(agent: AgentScopeConfig[\"name\"], model: ModelName): string {\n return `${agent} pins model '${model}', which this contract has no word for — leaving it out would say \"keep the sub-agent's own metadata\", which is a different instruction`;\n}\n\nfunction unwritablePairMessage(skillId: SkillId, agent: string): string {\n return `${skillId} -> ${agent}: a project-scoped skill never reaches a sub-agent that rests at global scope`;\n}\n\n/**\n * Names everything the contract cannot carry at once, not one thing at a time: a sharer who fixes\n * one only to be refused for the next learns nothing the first message could not have told them.\n *\n * The refusal exists because the alternative is worse than a failed command. A payload quietly\n * missing what it could not say still mints an id, and that id installs a configuration nobody\n * chose — with nothing on either side saying so.\n */\nfunction unshareableConfigError(unshareable: string[]): string {\n return [\n \"This installation cannot be shared as it stands — a shared configuration has no way to carry:\",\n ...unshareable.map((line) => ` ${line}`),\n \"Sharing it anyway would mint an id that installs something else.\",\n ].join(\"\\n\");\n}\n\n/** The ref a payload has to carry, and the skills no ref this config holds can account for. */\ntype MarketplaceReading = {\n /** Absent when nothing installed here came from a marketplace. */\n ref: string | undefined;\n unnameable: string[];\n};\n\n/**\n * Whether the marketplace this installation reads is the one `skill` came from.\n *\n * A skill's `origin` is a marketplace's NAME, `config.marketplace` is the ref it was fetched from,\n * and `marketplaceName` is what joins them — the name the install read out of that repository's\n * own manifest. Without both halves agreeing, the ref would send the receiver to a repository that\n * never served this skill, which is the same silent swap under a different spelling.\n */\nfunction isRecordedMarketplace(config: ProjectConfig, skill: SkillConfig): boolean {\n return config.marketplace !== undefined && skill.origin === config.marketplaceName;\n}\n\n/** Which marketplace the payload names, decided by the skills that oblige it to name one. */\nfunction readMarketplace(config: ProjectConfig, skills: SkillConfig[]): MarketplaceReading {\n const served = skills.filter((skill) => needsMarketplaceNamed(skill.origin));\n if (served.length === 0) return { ref: undefined, unnameable: [] };\n\n const unaccounted = served.filter((skill) => !isRecordedMarketplace(config, skill));\n if (unaccounted.length > 0) {\n return { ref: undefined, unnameable: unaccounted.map(unnameableOriginMessage) };\n }\n\n return { ref: config.marketplace, unnameable: [] };\n}\n\nfunction unnameableModels(agents: AgentScopeConfig[]): string[] {\n return agents.flatMap((agent) =>\n agent.model !== undefined && !isSeedModel(agent.model)\n ? [unnameableModelMessage(agent.name, agent.model)]\n : [],\n );\n}\n\n/**\n * Turns `config.stack` inside out: it is keyed by sub-agent and this contract is keyed by skill.\n *\n * Rows naming a sub-agent or a skill this configuration does not install are dropped rather than\n * refused, because they are already no part of what is installed — `compile` warns about exactly\n * those and leaves them out of the agents it writes, so carrying them would share more than this\n * project has.\n *\n * A row the config model cannot write is the opposite case and is collected for the refusal: the\n * decoder turns the same pair away on the way back in, so minting it would produce an id that\n * cannot be installed.\n */\nfunction readStack(\n stack: ProjectConfig[\"stack\"],\n skillScopes: Map<SkillId, SkillScope>,\n agentScopes: Map<string, SkillScope>,\n): StackReading {\n const assignments = new Map<SkillId, SeedAssignments>();\n const unwritable: string[] = [];\n\n for (const [agent, agentStack] of typedEntries(stack ?? {})) {\n const agentScope = agentScopes.get(agent);\n if (agentScope === undefined) continue;\n\n for (const categoryAssignments of typedValues(agentStack)) {\n for (const { id, preloaded } of categoryAssignments) {\n const skillScope = skillScopes.get(id);\n if (skillScope === undefined) continue;\n\n if (!isScopePairCompatible(skillScope, agentScope)) {\n unwritable.push(unwritablePairMessage(id, agent));\n continue;\n }\n\n const forSkill = assignments.get(id) ?? {};\n forSkill[agent] = seedLoadState(preloaded);\n assignments.set(id, forSkill);\n }\n }\n }\n\n return { assignments, unwritable };\n}\n\nfunction toSeedSkill(skill: SkillConfig, assignments: SeedAssignments | undefined): SeedSkill {\n return {\n // \"eject\" is the project's own copy; anything else is a plugin the marketplace serves, and\n // which marketplace that is has already had to be one the envelope's ref accounts for.\n install: skill.origin === EJECT_SOURCE ? \"eject\" : \"plugin\",\n scope: skill.scope,\n assignments: assignments ?? {},\n };\n}\n\n/**\n * A sub-agent's own row, and it always says `on`.\n *\n * The web app pins `on` only where a person did, because there an agent switched on by its rows is\n * already implied by them. An installed config is not an inference — every sub-agent it names was\n * chosen and has a compiled file on disk — so saying so outright is what carries the one that owns\n * no skill, which is the only thing the agents map can do that assignments cannot.\n */\nfunction toSeedAgent(agent: AgentScopeConfig): SeedAgent {\n return {\n on: true,\n scope: agent.scope,\n ...(agent.model !== undefined && isSeedModel(agent.model) && { model: agent.model }),\n ...(agent.effort !== undefined && { effort: agent.effort }),\n };\n}\n\n/**\n * Turns the installation this directory records into the payload the config store holds, so the\n * CLI can mint an id rather than only consume one.\n *\n * The inverse of `seedToWizardResult` in `seed-to-wizard.ts`, and held to it: a\n * payload minted here and decoded there has to describe the same install. That is why the scope\n * of every skill and sub-agent travels per entry rather than being implied, why the whole stack\n * is carried as per-`(skill, sub-agent)` assignments, and why nothing here leans on a wire default\n * the decoder would have to guess back.\n *\n * What it will not do is share a thinner configuration than the one installed. Anything the\n * contract cannot state is refused by name — see {@link unshareableConfigError} — because the\n * failure mode of the alternative is an id that silently installs something else.\n *\n * `stackId` is always null. A saved config records a stack's expansion and never the id it came\n * from, and the assignments above carry that expansion in full; naming an id this module invented\n * would make the receiver overlay a stack's own preload flags over the curation being shared.\n *\n * `description` is what a resolvable id would have supplied that the assignments do not, so it is\n * carried directly instead. That is the whole of the trade: the sentence travels, the roster the id\n * would have dragged behind it does not.\n *\n * `marketplace` is the one field carried for the payload rather than for an entry, because the\n * receiver loads one catalogue before it reads a single skill row — see {@link readMarketplace}.\n *\n * `carried` arrives as an argument because it is read off disk and this mapping touches none:\n * every id above is resolved by the receiver against a catalogue it already has, and the entries\n * in `carried` are the ones that answer to no catalogue in either direction. Stated rather than\n * defaulted, because a producer that forgot the content is exactly the defect this closed.\n */\nexport function configToSeedPayload(config: ProjectConfig, carried: ContentReading): SeedPayload {\n const skills = config.skills.filter(isInstalled);\n const agents = config.agents.filter(isInstalled);\n const skillScopes = new Map(skills.map((skill) => [skill.id, skill.scope]));\n const agentScopes = new Map<string, SkillScope>(agents.map((agent) => [agent.name, agent.scope]));\n\n const { assignments, unwritable } = readStack(config.stack, skillScopes, agentScopes);\n const marketplace = readMarketplace(config, skills);\n\n const unshareable = [\n ...marketplace.unnameable,\n ...unnameableModels(agents),\n ...unwritable,\n ...carried.uncarryable,\n ];\n if (unshareable.length > 0) throw new Error(unshareableConfigError(unshareable));\n\n // Parsed rather than merely assembled, exactly as the web app's encoder is: it makes \"the JSON\n // the store will hold\" literal, and it is the one gate that catches a field whose values have\n // drifted out of the wire's enums since this module last named them.\n //\n // The INSTALLABLE half of the contract, which is the schema the store's POST route declares —\n // the lenient one exists for READING links already out in the world, and this module only ever\n // mints. It refuses nothing the refusal above permits, and that is the point: it is the belt\n // over those braces, so the day this module's own rule and the wire's disagree, the mint fails\n // loudly here instead of minting an id that cannot be installed.\n return installableSeedPayloadSchema.parse({\n v: SEED_VERSION,\n matrixVersion: MATRIX_VERSION,\n stackId: null,\n // Absent rather than empty, for the reason the marketplace ref is: an id is the hash of its\n // body, so a key meaning what its absence already means would remint every ordinary payload.\n ...(config.description !== undefined && { description: config.description }),\n ...(marketplace.ref !== undefined && { marketplace: marketplace.ref }),\n skills: Object.fromEntries(\n skills.map((skill) => [skill.id, toSeedSkill(skill, assignments.get(skill.id))]),\n ),\n // Absent rather than empty, for the reason the marketplace ref is: an id is the hash of its\n // body, so a key meaning what its absence already means would remint every ordinary payload.\n ...(Object.keys(carried.external).length > 0 && { external: carried.external }),\n agents: Object.fromEntries(agents.map((agent) => [agent.name, toSeedAgent(agent)])),\n });\n}\n","import { STATUS_CODES } from \"node:http\";\n\nimport { z } from \"zod\";\n\nimport { SEED_API_URL, SEED_USER_AGENT } from \"./fetch-seed.js\";\nimport { CLI_INVOKE_COMMAND } from \"../../consts.js\";\nimport { truncateText } from \"../../utils/string.js\";\n\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/**\n * The store answers a stored configuration with its content-addressed id and nothing else.\n * Revalidated rather than read off the response type, because that type describes the worker this\n * CLI was built against and what answers is whatever is deployed.\n */\nconst mintedSchema = z.object({ id: z.string().min(1) });\n\n/**\n * The envelope a refused POST arrives in.\n *\n * `apps/server` registers no `defaultHook` and its own hook narrows only the seed-version case,\n * so every other refused body falls through to `@hono/zod-validator`, which answers\n * `c.json(result, 400)` — the whole `safeParse` result. A `ZodError` has no own enumerable fields\n * beyond `name` and `message`, so `{ success: false, error: { name, message } }` is what crosses\n * the wire. Only that string is read here; everything else is shape to match against.\n */\nconst refusalSchema = z.object({ error: z.object({ message: z.string() }) });\n\n/**\n * What that string really is, which is the part worth knowing: Zod renders its ISSUES into\n * `message` as a JSON document, so the field named `message` is not something to show a person.\n * The sentences the store's own schema wrote are one level further in, and reading them back out\n * is the whole difference between a bare `HTTP 400` and a refusal that names what is wrong.\n */\nconst refusedIssuesSchema = z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string().min(1),\n }),\n )\n .min(1);\n\n/**\n * How much of the store's account of a refusal to quote back.\n *\n * The refusal it really writes is one sentence naming a skill and a sub-agent — around 150\n * characters — so this holds that whole, and a second beside it. Past that a body has stopped\n * being an explanation, and a store replaced by a proxy, a captive portal or something worse must\n * not get to paint the terminal. The same reasoning as `EXCERPT` in `read-piped-payload.ts`, at\n * the length this quote needs: that one bounds unreadable bytes shown so a user recognises them,\n * where this one bounds prose the user has to be able to finish reading.\n *\n * ONE budget for both shapes this route answers in, rather than one apiece, because a budget is a\n * measurement of a ROUTE and both are `POST /configs`. The plain-text refusals it writes are far\n * shorter than a list of schema issues — the longest is `Could not store this config` — so the\n * number sized on the longer shape holds the shorter one with room to spare. `fetch-seed.ts` sets\n * 120 for its own route and neither number travels between them; see the 2026-09-01 finding on\n * quoting a refusal's body.\n */\nconst EXPLANATION_BUDGET = 300;\n\n/** The content type the store's own sentences arrive as — the only one worth reading as prose. */\nconst QUOTABLE_TYPE = \"text/plain\";\n\n/** The status the store spends on a payload naming a version of the contract it does not serve. */\nconst CONTRACT_MISMATCH = 409;\n\n/**\n * What a 409 means from a terminal, said in the CLI's own words rather than the store's.\n *\n * This is the one refusal whose entire purpose is naming a remedy, and the store's body names one\n * a terminal cannot carry out: `refuseAnotherSeedVersion` in `apps/server/src/index.ts` answers\n * `Reload the page: ...`, written for the caller that refusal was designed around — a browser tab\n * minting from a bundle older than the last deploy, for which one reload really is the whole fix.\n * There is no page here. Quoting it would be worse than the bare status it replaced, because the\n * bare status at least does not send the reader somewhere that does not exist.\n *\n * The fact underneath is the same one, and from a terminal it is actionable: `SEED_VERSION` is a\n * `z.literal` imported from `@workspace/matrix/seed` and bundled into this binary, so the version\n * written here travels INSIDE the CLI. Nothing about the configuration, the directory it was read\n * from or the pipe it arrived on can change it, and a newer CLI is the only thing that can.\n *\n * It cannot be the payload's fault by either door: `read-piped-payload.ts` validates a piped\n * configuration against `installableSeedPayloadSchema` before this runs, and `config-to-seed.ts`\n * writes `SEED_VERSION` into one it builds — so a `v` this CLI does not itself name never reaches\n * the wire, and a 409 can only be the two ends disagreeing.\n *\n * It names no sub-command, which is deliberate twice over. `publishSeedConfig` is called by both\n * `share` and `edit --ui`, so there is no one command to re-run; and an invocation written after\n * `@latest` is invisible to `handed-out-invocations.ts`, whose reader matches\n * `${CLI_INVOKE_COMMAND}` followed by a SPACE — so naming one here would hand out a command the\n * gate that runs every handed-out command could not see.\n */\nconst OUT_OF_DATE_AGAINST_STORE =\n `This CLI is out of date against the configuration store: it writes a version of the sharing ` +\n `contract the store does not serve, and that version travels inside the CLI rather than with ` +\n `the configuration. Re-run this command through '${CLI_INVOKE_COMMAND}@latest'.`;\n\nexport type PublishSeedResult = { ok: true; id: string } | { ok: false; error: string };\n\n/**\n * Stores a configuration and returns the id it was given.\n *\n * The outbound half of the boundary `fetchSeedConfig` in `fetch-seed.ts` owns the inbound half\n * of, and it keeps the same posture: every failure is a message rather than a throw.\n * Nothing local has been written by the time this runs, so there is nothing to roll back and the\n * caller's only job is to explain.\n *\n * The id is the payload's own hash, so re-sharing an unchanged configuration returns the id it\n * had — the store spends no write, and a caller can share as often as it likes.\n */\nexport async function publishSeedConfig(payload: SeedPayload): Promise<PublishSeedResult> {\n const url = `${SEED_API_URL}/configs`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n // The same signal the fetch half sends: it is the only thing that tells the store a\n // configuration came from the CLI rather than from a browser.\n \"user-agent\": SEED_USER_AGENT,\n },\n body: JSON.stringify(payload),\n });\n } catch {\n return { ok: false, error: `Could not reach ${SEED_API_URL} — check your connection.` };\n }\n\n if (!response.ok) return { ok: false, error: await refusalMessage(response) };\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 minted = mintedSchema.safeParse(body);\n if (!minted.success) {\n // Reporting success here would print an id nobody can install and tell the user to use it.\n return { ok: false, error: \"The configuration store did not return an id for this share.\" };\n }\n\n return { ok: true, id: minted.data.id };\n}\n\n/**\n * A refusal, carrying the store's own account of it wherever there is one to have.\n *\n * The status is never given up, because it is the only thing that separates a bad payload (400)\n * from a stale contract (409), a body over the cap (413), a rate limit (429) and a store that\n * refused the write (503). What it cannot do is say WHY a payload was bad, and the store already\n * knows: a refused POST answers with the issues its own schema raised, in plain English, naming\n * the skill and the sub-agent. Discarding that cost a real user a debugging session for a fault\n * the store had already described.\n *\n * Read for every status rather than for 400 alone — except the one status whose body is answering\n * somebody else. Which statuses carry which shape is the deployed worker's business, so both\n * shapes are tried against every body, and one that is neither degrades to the status anyway.\n */\nasync function refusalMessage(response: Response): Promise<string> {\n const refused = `Sharing this configuration failed (HTTP ${response.status}).`;\n\n // Branched on the status rather than on the body, because the status is the whole of the fact:\n // what a 409 says is that the two ends name different contract versions, and no body the store\n // could send makes that any more actionable from a terminal than the sentence above does.\n if (response.status === CONTRACT_MISMATCH) return `${refused} ${OUT_OF_DATE_AGAINST_STORE}`;\n\n const explanation = explanationOf(response, await refusalBody(response));\n\n return explanation === undefined ? refused : `${refused} The store said: ${explanation}`;\n}\n\n/**\n * Whatever the store sent, as text and unjudged.\n *\n * Deliberately NOT gated on the content type the way the function of this name in `fetch-seed.ts`\n * is, and the difference is the routes rather than a disagreement: that one answers every refusal\n * with `c.text`, where this one answers in two shapes under two types — the validator's envelope\n * as `application/json`, the worker's own sentences as `text/plain`. A gate here would throw one\n * of them away. It belongs on the prose arm alone, which is where {@link arrivedAsText} is.\n *\n * Nothing below this line is worth failing over: the message being assembled is already a\n * failure, and a body that cannot be read is one more thing the status will have to cover on its\n * own. Draining the stream can throw in its own right — a connection dropped mid-body — which is\n * why this is a `try` around the read.\n */\nasync function refusalBody(response: Response): Promise<string | undefined> {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n}\n\n/** `JSON.parse` as a value rather than a throw, since a body that is not JSON is expected here. */\nfunction jsonOf(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * The store's account of a refusal, in whichever of the two shapes this route answers in.\n *\n * The envelope is read first because it is the more specific of the two, and the order costs\n * nothing either way: an envelope arrives as JSON and could never satisfy the prose arm's\n * content-type gate, and prose has no shape for `refusalSchema` to match.\n *\n * The budget is spent here rather than inside either arm, so that whatever leaves this module is\n * bounded once, by one number belonging to one route.\n *\n * The body travels beside the response it came from rather than being taken off it, because by\n * the time this runs the stream has been drained and a second read would answer nothing.\n */\nfunction explanationOf(response: Response, body: string | undefined): string | undefined {\n if (body === undefined) return undefined;\n\n const said = schemaIssuesIn(body) ?? quotableProseIn(response, body);\n\n return said === undefined ? undefined : truncateText(said, EXPLANATION_BUDGET);\n}\n\n/** The sentences the store's own schema wrote, read back out of the validator's envelope. */\nfunction schemaIssuesIn(body: string): string | undefined {\n const refusal = refusalSchema.safeParse(jsonOf(body));\n if (!refusal.success) return undefined;\n\n const issues = refusedIssuesSchema.safeParse(jsonOf(refusal.data.error.message));\n if (!issues.success) return undefined;\n\n return issues.data.map(sentenceOf).join(\"; \");\n}\n\n/**\n * The store's own words, where the wire says the store wrote them and they say something.\n *\n * The three refusals this route writes with `c.text` — 413, 429 and 503 — reach a terminal by no\n * other arm, and before this they reached it by none at all. Two of the three are then discarded\n * again by {@link restatesItsOwnStatus}, which is the whole shape of the rule: what earns a quote\n * is not a body, it is a body that adds something to the status printed beside it.\n */\nfunction quotableProseIn(response: Response, body: string): string | undefined {\n if (!arrivedAsText(response)) return undefined;\n\n const said = body.trim();\n if (said === \"\") return undefined;\n if (restatesItsOwnStatus(said, response.status)) return undefined;\n\n return said;\n}\n\n/**\n * Whether what arrived is the store speaking, as far as the wire says it is.\n *\n * `c.text(...)` is how this route writes every refusal that is not the validator's, so `text/plain`\n * is the shape the store's own words take. What arrives as anything else did not come from it: a\n * proxy, a WAF, a captive portal or a gateway answering in its place — and their answer is markup\n * rather than prose, which quoted into a terminal is a screenful of tags that explains nothing and\n * buries the status that does.\n *\n * A sentence has no shape to validate, so the wire's own statement of what it sent is the only\n * discriminator prose has — where the envelope beside it has `refusalSchema`, a shape a foreign\n * body fails to be. It is not proof, since a hostile answer may claim any type it likes, which is\n * what {@link EXPLANATION_BUDGET} is for and why what survives both is attributed to the store\n * 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/**\n * Whether the body says only what the status line printed beside it has already said.\n *\n * `node:http`'s `STATUS_CODES` is the registry of reason phrases a status line carries, so holding\n * a body against it is a rule about the whole class rather than a list of the statuses it happens\n * to catch today. It catches two: `Too many requests` is 429's `Too Many Requests` re-cased and\n * `Payload too large` is 413's, so neither is named here and a fourth refusal written the same way\n * is suppressed the day it ships. `Could not store this config` is not `Service Unavailable`, which\n * is why the one refusal on this route that names a cause is the one that survives.\n *\n * Compared case-insensitively, and against the trimmed body, because the worker writes sentence\n * case where the registry writes title case and that is not a difference in meaning.\n */\nfunction restatesItsOwnStatus(said: string, status: number): boolean {\n const reason = STATUS_CODES[status];\n\n return reason !== undefined && said.toLowerCase() === reason.toLowerCase();\n}\n\n/** One issue as it arrives, read off the schema above so the two cannot drift apart. */\ntype RefusedIssue = z.infer<typeof refusedIssuesSchema>[number];\n\n/**\n * One issue, path first — the same rendering `formatZodIssue` in `lib/schema-validator.ts` gives\n * a local one, and deliberately the same sentence a user sees from `share --stdin`.\n *\n * It cannot call that function: this issue was read off a wire and is a plain object, where\n * `formatZodIssue` takes a `z.ZodIssue`, a discriminated union nothing arriving over HTTP can be\n * narrowed to without a cast. The path is what the sentence itself cannot carry — the store's\n * message names the sub-agent and the path names the skill.\n */\nfunction sentenceOf(issue: RefusedIssue): string {\n const path = issue.path.join(\".\");\n return path === \"\" ? issue.message : `${path}: ${issue.message}`;\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
validateMarketplaceName,
|
|
6
6
|
validateSkillIdNamespace,
|
|
7
7
|
writeMarketplace
|
|
8
|
-
} from "../../chunk-
|
|
8
|
+
} from "../../chunk-VEONZFTL.js";
|
|
9
9
|
import {
|
|
10
10
|
BaseCommand,
|
|
11
11
|
EXIT_CODES
|
|
12
|
-
} from "../../chunk-
|
|
13
|
-
import "../../chunk-
|
|
14
|
-
import "../../chunk-
|
|
12
|
+
} from "../../chunk-H2MDPOLG.js";
|
|
13
|
+
import "../../chunk-2IMHZEIK.js";
|
|
14
|
+
import "../../chunk-77YZFVQD.js";
|
|
15
15
|
import {
|
|
16
16
|
getErrorMessage,
|
|
17
17
|
loadMarketplaceMatrix,
|
|
@@ -23,8 +23,8 @@ import {
|
|
|
23
23
|
validateKebabCaseName,
|
|
24
24
|
warn,
|
|
25
25
|
writeFile
|
|
26
|
-
} from "../../chunk-
|
|
27
|
-
import "../../chunk-
|
|
26
|
+
} from "../../chunk-UNASGGW2.js";
|
|
27
|
+
import "../../chunk-3QBOVV6A.js";
|
|
28
28
|
import {
|
|
29
29
|
CATALOG_JSON,
|
|
30
30
|
CLI_INVOKE_COMMAND,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
PLUGINS_DIST_PATH,
|
|
34
34
|
PLUGIN_MANIFEST_DIR,
|
|
35
35
|
STANDARD_FILES
|
|
36
|
-
} from "../../chunk-
|
|
36
|
+
} from "../../chunk-IV42Z63R.js";
|
|
37
37
|
import "../../chunk-OI2H6M5I.js";
|
|
38
38
|
|
|
39
39
|
// src/cli/commands/build/marketplace.ts
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileAllAgentPlugins,
|
|
4
4
|
printAgentCompilationSummary
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-GFO55TMY.js";
|
|
6
6
|
import {
|
|
7
7
|
BaseCommand
|
|
8
|
-
} from "../../chunk-
|
|
9
|
-
import "../../chunk-
|
|
10
|
-
import "../../chunk-
|
|
8
|
+
} from "../../chunk-H2MDPOLG.js";
|
|
9
|
+
import "../../chunk-2IMHZEIK.js";
|
|
10
|
+
import "../../chunk-77YZFVQD.js";
|
|
11
11
|
import {
|
|
12
12
|
compileAllSkillPlugins,
|
|
13
13
|
compileSkillPlugin,
|
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
readPluginManifest,
|
|
17
17
|
remove,
|
|
18
18
|
setVerbose
|
|
19
|
-
} from "../../chunk-
|
|
20
|
-
import "../../chunk-
|
|
19
|
+
} from "../../chunk-UNASGGW2.js";
|
|
20
|
+
import "../../chunk-3QBOVV6A.js";
|
|
21
21
|
import {
|
|
22
22
|
DIRS,
|
|
23
23
|
PLUGINS_DIST_PATH
|
|
24
|
-
} from "../../chunk-
|
|
24
|
+
} from "../../chunk-IV42Z63R.js";
|
|
25
25
|
import "../../chunk-OI2H6M5I.js";
|
|
26
26
|
|
|
27
27
|
// src/cli/commands/build/plugins.ts
|
package/dist/commands/compile.js
CHANGED
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectBothInstallations,
|
|
4
4
|
reconcileTypesFromDisk
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-C53RJ7AA.js";
|
|
6
6
|
import {
|
|
7
7
|
compileAgents,
|
|
8
8
|
discoverInstalledSkills
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-HRVPZMKK.js";
|
|
10
10
|
import {
|
|
11
11
|
loadAgentDefs
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-ES7WGE32.js";
|
|
13
|
+
import "../chunk-GFO55TMY.js";
|
|
14
14
|
import {
|
|
15
15
|
BaseCommand,
|
|
16
16
|
EXIT_CODES
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-H2MDPOLG.js";
|
|
18
|
+
import "../chunk-2IMHZEIK.js";
|
|
19
|
+
import "../chunk-77YZFVQD.js";
|
|
20
20
|
import {
|
|
21
21
|
ConfigLoadError,
|
|
22
22
|
ERROR_MESSAGES,
|
|
@@ -38,13 +38,13 @@ import {
|
|
|
38
38
|
skillMetadataUnusableDetail,
|
|
39
39
|
skillMetadataUnusableError,
|
|
40
40
|
verbose
|
|
41
|
-
} from "../chunk-
|
|
42
|
-
import "../chunk-
|
|
41
|
+
} from "../chunk-UNASGGW2.js";
|
|
42
|
+
import "../chunk-3QBOVV6A.js";
|
|
43
43
|
import {
|
|
44
44
|
STANDARD_FILES,
|
|
45
45
|
effectivelyExcludedSkillIds,
|
|
46
46
|
isActiveAt
|
|
47
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-IV42Z63R.js";
|
|
48
48
|
import "../chunk-OI2H6M5I.js";
|
|
49
49
|
|
|
50
50
|
// src/cli/commands/compile.ts
|
package/dist/commands/doctor.js
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectProject,
|
|
4
4
|
loadSource
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-C53RJ7AA.js";
|
|
6
|
+
import "../chunk-HRVPZMKK.js";
|
|
7
|
+
import "../chunk-ES7WGE32.js";
|
|
8
8
|
import {
|
|
9
9
|
filterExcludedEntries,
|
|
10
10
|
listAgentMdFiles,
|
|
11
11
|
splitAgentsByProvenance
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-GFO55TMY.js";
|
|
13
13
|
import {
|
|
14
14
|
BaseCommand,
|
|
15
15
|
EXIT_CODES
|
|
16
|
-
} from "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-H2MDPOLG.js";
|
|
17
|
+
import "../chunk-2IMHZEIK.js";
|
|
18
|
+
import "../chunk-77YZFVQD.js";
|
|
19
19
|
import {
|
|
20
20
|
ConfigDefaultExportError,
|
|
21
21
|
MarketplaceNameRefusedError,
|
|
@@ -66,10 +66,10 @@ import {
|
|
|
66
66
|
validateProjectConfig,
|
|
67
67
|
validateSkillFrontmatter,
|
|
68
68
|
validateSkillMetadata
|
|
69
|
-
} from "../chunk-
|
|
69
|
+
} from "../chunk-UNASGGW2.js";
|
|
70
70
|
import {
|
|
71
71
|
matrix
|
|
72
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-3QBOVV6A.js";
|
|
73
73
|
import {
|
|
74
74
|
CLAUDE_SRC_DIR,
|
|
75
75
|
CLI_INVOKE_COMMAND,
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
STANDARD_FILES,
|
|
87
87
|
UI_SYMBOLS,
|
|
88
88
|
effectivelyExcludedSkillIds
|
|
89
|
-
} from "../chunk-
|
|
89
|
+
} from "../chunk-IV42Z63R.js";
|
|
90
90
|
import "../chunk-OI2H6M5I.js";
|
|
91
91
|
|
|
92
92
|
// src/cli/commands/doctor.ts
|