agents-inc 0.172.0 → 0.174.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 +68 -0
- package/dist/{chunk-6LUTY35Q.js → chunk-3PJZ4QNJ.js} +7 -7
- package/dist/{chunk-255DGUCH.js → chunk-6PGXTLA4.js} +12 -6
- package/dist/{chunk-255DGUCH.js.map → chunk-6PGXTLA4.js.map} +1 -1
- package/dist/{chunk-KCLBLK3F.js → chunk-7BHDKEGK.js} +3 -3
- package/dist/{chunk-7OG635DK.js → chunk-AIBVAYHS.js} +6 -2
- package/dist/{chunk-7OG635DK.js.map → chunk-AIBVAYHS.js.map} +1 -1
- package/dist/{chunk-5MGRHS2G.js → chunk-APWMMZOK.js} +42 -25
- package/dist/chunk-APWMMZOK.js.map +1 -0
- package/dist/{chunk-VILFCMRN.js → chunk-E45IT3HC.js} +368 -123
- package/dist/chunk-E45IT3HC.js.map +1 -0
- package/dist/{chunk-MOL2J5HS.js → chunk-ECPFYHDX.js} +2 -2
- package/dist/{chunk-LUKDDHSI.js → chunk-EFXVYQGT.js} +4 -4
- package/dist/{chunk-G7NUK3BF.js → chunk-FQF6VHO3.js} +29 -19
- package/dist/chunk-FQF6VHO3.js.map +1 -0
- package/dist/chunk-H5E6IO2L.js +116 -0
- package/dist/chunk-H5E6IO2L.js.map +1 -0
- package/dist/{chunk-3R3LHA4Q.js → chunk-I3WF6L43.js} +2 -2
- package/dist/{chunk-7ZOWSCAO.js → chunk-IAQFZFWD.js} +4 -4
- package/dist/{chunk-NISWBQNS.js → chunk-IXVGBUWI.js} +5 -5
- package/dist/{chunk-MBIOZ5LW.js → chunk-ORO2T4K2.js} +19 -5
- package/dist/chunk-ORO2T4K2.js.map +1 -0
- package/dist/{chunk-A3ZAXL5T.js → chunk-QCX66KBM.js} +3 -3
- package/dist/{chunk-6CRA46YO.js → chunk-R7GKQBZJ.js} +44 -21
- package/dist/chunk-R7GKQBZJ.js.map +1 -0
- package/dist/{chunk-Y23MP2OC.js → chunk-REHVGFJE.js} +5 -5
- package/dist/{chunk-5PPB6HT6.js → chunk-TVEDNGVP.js} +2 -2
- package/dist/{chunk-MHAQWMNJ.js → chunk-WUSEZFER.js} +1 -5
- package/dist/{chunk-MHAQWMNJ.js.map → chunk-WUSEZFER.js.map} +1 -1
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +12 -12
- package/dist/commands/doctor.js +33 -15
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +56 -59
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +25 -30
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +17 -18
- package/dist/commands/list.js +41 -16
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/search.js +9 -9
- package/dist/commands/share.js +9 -9
- package/dist/commands/uninstall.js +61 -56
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +3 -3
- package/dist/components/common/summary-panel.js +4 -7
- package/dist/hooks/init.js +57 -33
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-5U5KAURA.js +14 -0
- package/dist/{recompile-project-agents-5A44NJRD.js → recompile-project-agents-KYK44C24.js} +8 -8
- package/dist/{source-loader-LQNRI5UZ.js → source-loader-G5I4RNUP.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-33JICQD5.js +0 -196
- package/dist/chunk-33JICQD5.js.map +0 -1
- package/dist/chunk-5MGRHS2G.js.map +0 -1
- package/dist/chunk-6CRA46YO.js.map +0 -1
- package/dist/chunk-G7NUK3BF.js.map +0 -1
- package/dist/chunk-MBIOZ5LW.js.map +0 -1
- package/dist/chunk-N33AKFLR.js +0 -24
- package/dist/chunk-N33AKFLR.js.map +0 -1
- package/dist/chunk-VILFCMRN.js.map +0 -1
- package/dist/components/common/scroll-affordance.js +0 -9
- package/dist/load-agent-defs-54VIKN4T.js +0 -14
- package/dist/source-loader-LQNRI5UZ.js.map +0 -1
- /package/dist/{chunk-6LUTY35Q.js.map → chunk-3PJZ4QNJ.js.map} +0 -0
- /package/dist/{chunk-KCLBLK3F.js.map → chunk-7BHDKEGK.js.map} +0 -0
- /package/dist/{chunk-MOL2J5HS.js.map → chunk-ECPFYHDX.js.map} +0 -0
- /package/dist/{chunk-LUKDDHSI.js.map → chunk-EFXVYQGT.js.map} +0 -0
- /package/dist/{chunk-3R3LHA4Q.js.map → chunk-I3WF6L43.js.map} +0 -0
- /package/dist/{chunk-7ZOWSCAO.js.map → chunk-IAQFZFWD.js.map} +0 -0
- /package/dist/{chunk-NISWBQNS.js.map → chunk-IXVGBUWI.js.map} +0 -0
- /package/dist/{chunk-A3ZAXL5T.js.map → chunk-QCX66KBM.js.map} +0 -0
- /package/dist/{chunk-Y23MP2OC.js.map → chunk-REHVGFJE.js.map} +0 -0
- /package/dist/{chunk-5PPB6HT6.js.map → chunk-TVEDNGVP.js.map} +0 -0
- /package/dist/{components/common/scroll-affordance.js.map → load-agent-defs-5U5KAURA.js.map} +0 -0
- /package/dist/{recompile-project-agents-5A44NJRD.js.map → recompile-project-agents-KYK44C24.js.map} +0 -0
- /package/dist/{load-agent-defs-54VIKN4T.js.map → source-loader-G5I4RNUP.js.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BUILT_IN_MATRIX,
|
|
4
4
|
getSkillById,
|
|
5
|
-
|
|
5
|
+
getSkillEntryDisplayName,
|
|
6
6
|
inertLine,
|
|
7
7
|
initializeMatrix,
|
|
8
8
|
matrix,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
typedFromEntries,
|
|
14
14
|
typedKeys,
|
|
15
15
|
typedValues
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AIBVAYHS.js";
|
|
17
17
|
import {
|
|
18
18
|
AGENT_NAMES,
|
|
19
19
|
AUTHOR_HANDLE_PATTERN,
|
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
seedAgentScope,
|
|
83
83
|
sourceDirName,
|
|
84
84
|
validateSelection
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-WUSEZFER.js";
|
|
86
86
|
import {
|
|
87
87
|
defaultCategories,
|
|
88
88
|
defaultRules,
|
|
@@ -490,8 +490,9 @@ function sourceRootOf(root) {
|
|
|
490
490
|
return { dir: path.join(root, SOURCE_ROOT_DIR), relName: SOURCE_ROOT_DIR };
|
|
491
491
|
}
|
|
492
492
|
var RETIRED_SOURCE_FOLDER = ".claude-src";
|
|
493
|
-
function
|
|
494
|
-
|
|
493
|
+
function rootsHoldingTheRetiredSourceFolder(cwd) {
|
|
494
|
+
const roots = isHomeDirectory(cwd) ? [os2.homedir()] : [os2.homedir(), cwd];
|
|
495
|
+
return roots.filter(holdsTheRetiredSourceFolder);
|
|
495
496
|
}
|
|
496
497
|
function holdsTheRetiredSourceFolder(root) {
|
|
497
498
|
return directoryExists(path.join(root, RETIRED_SOURCE_FOLDER));
|
|
@@ -504,6 +505,9 @@ var providerChosenForThisRun;
|
|
|
504
505
|
function chooseProviderForThisRun(provider) {
|
|
505
506
|
providerChosenForThisRun = provider;
|
|
506
507
|
}
|
|
508
|
+
function forgetTheProviderChosenForThisRun() {
|
|
509
|
+
providerChosenForThisRun = void 0;
|
|
510
|
+
}
|
|
507
511
|
function providerInUse(root) {
|
|
508
512
|
if (providerChosenForThisRun !== void 0) return providerChosenForThisRun;
|
|
509
513
|
if (root === void 0) return PROVIDER_OF_A_NEW_INSTALLATION;
|
|
@@ -744,8 +748,8 @@ async function fileExists(filePath) {
|
|
|
744
748
|
}
|
|
745
749
|
async function directoryExists2(dirPath) {
|
|
746
750
|
try {
|
|
747
|
-
const
|
|
748
|
-
return
|
|
751
|
+
const stat2 = await fs3.stat(dirPath);
|
|
752
|
+
return stat2.isDirectory();
|
|
749
753
|
} catch {
|
|
750
754
|
return false;
|
|
751
755
|
}
|
|
@@ -953,6 +957,8 @@ var INFO_MESSAGES = {
|
|
|
953
957
|
CONFIG_TYPES_REFRESHED: `Refreshed ${STANDARD_FILES.CONFIG_TYPES_TS}`,
|
|
954
958
|
EJECTED_SKILLS_USER_OWNED: `Ejected skills are yours to own \u2014 '${CLI_INVOKE_COMMAND} update' does not change them.`,
|
|
955
959
|
NO_PLUGIN_MARKETPLACES: "No plugin marketplaces are configured \u2014 nothing to refresh.",
|
|
960
|
+
/** Under doctor's marketplace row, when its download replaced a saved copy whose files differed. */
|
|
961
|
+
SAVED_COPY_REPLACED: "The saved copy differed from the marketplace and has been replaced",
|
|
956
962
|
/** Printed under the destination already named, so it names files only. */
|
|
957
963
|
AGENT_PARTIALS_CUSTOMIZABLE: `Each sub-agent directory there holds ${AGENT_PARTIAL_FILES.join(", ")} \u2014 edit those to customize that sub-agent.`
|
|
958
964
|
};
|
|
@@ -1010,6 +1016,9 @@ function marketplaceRefreshFailed(marketplace, reason) {
|
|
|
1010
1016
|
function sourceUnreachableUsingCache(source) {
|
|
1011
1017
|
return `Could not reach ${source} \u2014 using the cached copy, which may be out of date.`;
|
|
1012
1018
|
}
|
|
1019
|
+
function sourceRefusedUsingCache(source, status) {
|
|
1020
|
+
return `${source} refused the request (${status}) \u2014 using the cached copy, which may be out of date.`;
|
|
1021
|
+
}
|
|
1013
1022
|
function marketplacesRefreshFailed(marketplaces) {
|
|
1014
1023
|
return `${plural(marketplaces.length, "marketplace")} could not be updated: ${marketplaces.join(", ")}`;
|
|
1015
1024
|
}
|
|
@@ -1213,8 +1222,9 @@ function keptAsInstalledGlobally(skillIds, agentNames, idAppliedAtHome, provider
|
|
|
1213
1222
|
]
|
|
1214
1223
|
].join("\n");
|
|
1215
1224
|
}
|
|
1216
|
-
function skillsMoved(verb, skillIds) {
|
|
1217
|
-
|
|
1225
|
+
function skillsMoved(verb, skillIds, namedBy) {
|
|
1226
|
+
const names = skillIds.map((id) => getSkillEntryDisplayName(namedBy[id] ?? { id }));
|
|
1227
|
+
return names.length === 0 ? [] : [`${verb} ${listed(names)}`];
|
|
1218
1228
|
}
|
|
1219
1229
|
function settingMoved({ setting, from, to }) {
|
|
1220
1230
|
return `${setting} ${from ?? "default"} \u2192 ${to ?? "default"}`;
|
|
@@ -1224,10 +1234,17 @@ function listed(names) {
|
|
|
1224
1234
|
return `${names.slice(0, -1).join(", ")} and ${names.at(-1)}`;
|
|
1225
1235
|
}
|
|
1226
1236
|
var SKILLS_REASSIGNED = "skills reassigned";
|
|
1227
|
-
function subAgentChanged({
|
|
1237
|
+
function subAgentChanged({
|
|
1238
|
+
name,
|
|
1239
|
+
scope,
|
|
1240
|
+
gains,
|
|
1241
|
+
loses,
|
|
1242
|
+
settings,
|
|
1243
|
+
namedBy = {}
|
|
1244
|
+
}) {
|
|
1228
1245
|
const details = [
|
|
1229
|
-
...skillsMoved("gains", gains),
|
|
1230
|
-
...skillsMoved("loses", loses),
|
|
1246
|
+
...skillsMoved("gains", gains, namedBy),
|
|
1247
|
+
...skillsMoved("loses", loses, namedBy),
|
|
1231
1248
|
...settings.map(settingMoved)
|
|
1232
1249
|
];
|
|
1233
1250
|
const where = scope === "global" ? " (global)" : "";
|
|
@@ -1316,8 +1333,9 @@ function sentenceCase(text) {
|
|
|
1316
1333
|
function layoutIsCurrent(label, to) {
|
|
1317
1334
|
return `${label} is on ${to}/`;
|
|
1318
1335
|
}
|
|
1319
|
-
function
|
|
1320
|
-
|
|
1336
|
+
function retiredSourceFolderIgnored(root, provider) {
|
|
1337
|
+
const named = isHomeDirectory(root) ? "~" : root;
|
|
1338
|
+
return `${path3.join(named, RETIRED_SOURCE_FOLDER)}/ is ignored; agents-inc reads ${path3.join(named, sourceDirName(provider))}/. Delete the old folder once you have kept anything you need from it.`;
|
|
1321
1339
|
}
|
|
1322
1340
|
|
|
1323
1341
|
// src/cli/types/generated/source-types.ts
|
|
@@ -2139,6 +2157,7 @@ var projectConfigFields = z2.object({
|
|
|
2139
2157
|
id: z2.string(),
|
|
2140
2158
|
scope: z2.enum(["project", "global"]),
|
|
2141
2159
|
origin: z2.string(),
|
|
2160
|
+
displayName: z2.string().exactOptional(),
|
|
2142
2161
|
excluded: z2.boolean().exactOptional()
|
|
2143
2162
|
})
|
|
2144
2163
|
).exactOptional(),
|
|
@@ -2549,14 +2568,12 @@ async function loadConfig(configPath, schema) {
|
|
|
2549
2568
|
if (declaresNoDefaultExport(namespace)) {
|
|
2550
2569
|
throw new ConfigDefaultExportError(configPath);
|
|
2551
2570
|
}
|
|
2552
|
-
if (schema)
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
}
|
|
2557
|
-
return result.data;
|
|
2571
|
+
if (!schema) return raw;
|
|
2572
|
+
const result = schema.safeParse(raw);
|
|
2573
|
+
if (!result.success) {
|
|
2574
|
+
throw new ConfigSchemaError(configPath, formatZodIssues(result.error.issues));
|
|
2558
2575
|
}
|
|
2559
|
-
return
|
|
2576
|
+
return result.data;
|
|
2560
2577
|
}
|
|
2561
2578
|
async function importConfigModule(configPath) {
|
|
2562
2579
|
try {
|
|
@@ -3177,7 +3194,16 @@ function brokenUnionLayout(members, bodyIndent) {
|
|
|
3177
3194
|
}
|
|
3178
3195
|
function renderUnionBody(members, layout, bodyIndent) {
|
|
3179
3196
|
const padding = spaces(bodyIndent);
|
|
3180
|
-
|
|
3197
|
+
switch (layout) {
|
|
3198
|
+
case "indented":
|
|
3199
|
+
return `${padding}${flatUnion(members)}`;
|
|
3200
|
+
case "stacked":
|
|
3201
|
+
return members.map((member) => `${padding}| ${member}`).join("\n");
|
|
3202
|
+
default: {
|
|
3203
|
+
const _exhaustive = layout;
|
|
3204
|
+
return _exhaustive;
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3181
3207
|
}
|
|
3182
3208
|
function flatUnion(members) {
|
|
3183
3209
|
return members.join(" | ");
|
|
@@ -3225,9 +3251,18 @@ function renderArray(entries, position) {
|
|
|
3225
3251
|
return ["[", ...lines, `${spaces(position.indent)}]`].join("\n");
|
|
3226
3252
|
}
|
|
3227
3253
|
function renderEntryLine(entry, indent) {
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3254
|
+
switch (entry.kind) {
|
|
3255
|
+
case "comment":
|
|
3256
|
+
return `${spaces(indent)}// ${entry.text}`;
|
|
3257
|
+
case "source":
|
|
3258
|
+
return `${spaces(indent)}${entry.source},`;
|
|
3259
|
+
case "value":
|
|
3260
|
+
return renderValueLine(entry.value, { indent, prefix: "", suffix: "," });
|
|
3261
|
+
default: {
|
|
3262
|
+
const _exhaustive = entry;
|
|
3263
|
+
return _exhaustive;
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3231
3266
|
}
|
|
3232
3267
|
function renderRecord(record, position) {
|
|
3233
3268
|
const properties = Object.entries(record);
|
|
@@ -3247,11 +3282,27 @@ function propertyPosition(key, indent) {
|
|
|
3247
3282
|
function flatArray(entries) {
|
|
3248
3283
|
const items = [];
|
|
3249
3284
|
for (const entry of entries) {
|
|
3250
|
-
|
|
3251
|
-
|
|
3285
|
+
const item = flatEntry(entry);
|
|
3286
|
+
if (item === void 0) return void 0;
|
|
3287
|
+
items.push(item);
|
|
3252
3288
|
}
|
|
3253
3289
|
return flatList(items);
|
|
3254
3290
|
}
|
|
3291
|
+
function flatEntry(entry) {
|
|
3292
|
+
switch (entry.kind) {
|
|
3293
|
+
// A `//` line cannot fold onto one line.
|
|
3294
|
+
case "comment":
|
|
3295
|
+
return void 0;
|
|
3296
|
+
case "source":
|
|
3297
|
+
return entry.source;
|
|
3298
|
+
case "value":
|
|
3299
|
+
return flatValue(entry.value);
|
|
3300
|
+
default: {
|
|
3301
|
+
const _exhaustive = entry;
|
|
3302
|
+
return _exhaustive;
|
|
3303
|
+
}
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3255
3306
|
function flatValue(value) {
|
|
3256
3307
|
if (Array.isArray(value)) return flatList(value.map(flatValue));
|
|
3257
3308
|
if (isKeyedRecord(value)) return flatRecord(value);
|
|
@@ -3297,12 +3348,16 @@ var GLOBAL_IDENTITY_FIELDS = [
|
|
|
3297
3348
|
...HAND_WRITTEN_FIELDS,
|
|
3298
3349
|
"description"
|
|
3299
3350
|
];
|
|
3300
|
-
var EXTRACTED_FIELDS =
|
|
3351
|
+
var EXTRACTED_FIELDS = [
|
|
3301
3352
|
"skills",
|
|
3302
3353
|
"agents",
|
|
3303
3354
|
"stack",
|
|
3304
3355
|
"selectedDomains"
|
|
3305
|
-
]
|
|
3356
|
+
];
|
|
3357
|
+
var extractedFields = new Set(EXTRACTED_FIELDS);
|
|
3358
|
+
function isExtractedField(key) {
|
|
3359
|
+
return extractedFields.has(key);
|
|
3360
|
+
}
|
|
3306
3361
|
var CANONICAL_FIELD_ORDER = [
|
|
3307
3362
|
"name",
|
|
3308
3363
|
"description",
|
|
@@ -3319,6 +3374,7 @@ var CANONICAL_SKILL_ENTRY_ORDER = [
|
|
|
3319
3374
|
"id",
|
|
3320
3375
|
"scope",
|
|
3321
3376
|
"origin",
|
|
3377
|
+
"displayName",
|
|
3322
3378
|
"excluded"
|
|
3323
3379
|
];
|
|
3324
3380
|
var CANONICAL_AGENT_ENTRY_ORDER = [
|
|
@@ -3503,11 +3559,21 @@ function generateStandaloneConfig(cleaned) {
|
|
|
3503
3559
|
});
|
|
3504
3560
|
}
|
|
3505
3561
|
function standaloneExportField(key, value, emitted) {
|
|
3506
|
-
if (!
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3562
|
+
if (!isExtractedField(key)) return [renderScalarField(key, value)];
|
|
3563
|
+
switch (key) {
|
|
3564
|
+
case "skills":
|
|
3565
|
+
return [` skills${emitted.hasSkills ? "" : ": []"},`];
|
|
3566
|
+
case "agents":
|
|
3567
|
+
return [` agents${emitted.hasAgents ? "" : ": []"},`];
|
|
3568
|
+
case "stack":
|
|
3569
|
+
return emitted.hasStack ? [` stack,`] : [];
|
|
3570
|
+
case "selectedDomains":
|
|
3571
|
+
return [` selectedDomains${emitted.hasSelectedDomains ? "" : ": []"},`];
|
|
3572
|
+
default: {
|
|
3573
|
+
const _exhaustive = key;
|
|
3574
|
+
return _exhaustive;
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3511
3577
|
}
|
|
3512
3578
|
function assembleConfigSource({
|
|
3513
3579
|
imports,
|
|
@@ -3538,7 +3604,7 @@ function buildTypeImports(flags) {
|
|
|
3538
3604
|
].filter((t) => Boolean(t));
|
|
3539
3605
|
}
|
|
3540
3606
|
function isCopiedScalarField(key) {
|
|
3541
|
-
return !
|
|
3607
|
+
return !isExtractedField(key) && key !== "name";
|
|
3542
3608
|
}
|
|
3543
3609
|
function resolveProjectName(cleaned) {
|
|
3544
3610
|
return cleaned.name && cleaned.name !== GLOBAL_CONFIG_NAME ? cleaned.name : DEFAULT_PLUGIN_NAME;
|
|
@@ -4140,7 +4206,8 @@ function toSeedSkillConfig({
|
|
|
4140
4206
|
return {
|
|
4141
4207
|
id,
|
|
4142
4208
|
scope: seedSkill.scope,
|
|
4143
|
-
origin: seedSkill.install === "eject" ? EJECT_SOURCE : sourceForSkill(catalogSkill)
|
|
4209
|
+
origin: seedSkill.install === "eject" ? EJECT_SOURCE : sourceForSkill(catalogSkill),
|
|
4210
|
+
displayName: catalogSkill.displayName
|
|
4144
4211
|
};
|
|
4145
4212
|
}
|
|
4146
4213
|
function sourceForSkill(skill) {
|
|
@@ -4310,12 +4377,12 @@ async function loadStackById(stackId, configDir, source) {
|
|
|
4310
4377
|
);
|
|
4311
4378
|
return null;
|
|
4312
4379
|
}
|
|
4313
|
-
const defaultStack = defaultStacks.find((s) => s.id === stackId)
|
|
4314
|
-
if (defaultStack) {
|
|
4315
|
-
verbose(`Found default stack: ${defaultStack.name} (${stackId})`);
|
|
4316
|
-
} else {
|
|
4380
|
+
const defaultStack = defaultStacks.find((s) => s.id === stackId);
|
|
4381
|
+
if (!defaultStack) {
|
|
4317
4382
|
verbose(`Stack '${stackId}' not found in the default marketplace or the built-ins`);
|
|
4383
|
+
return null;
|
|
4318
4384
|
}
|
|
4385
|
+
verbose(`Found default stack: ${defaultStack.name} (${stackId})`);
|
|
4319
4386
|
return defaultStack;
|
|
4320
4387
|
}
|
|
4321
4388
|
function stackNotOfferedMessage(stackId, source) {
|
|
@@ -4446,10 +4513,8 @@ async function loadProjectConfig(projectDir) {
|
|
|
4446
4513
|
const provider = providerInUse(projectDir);
|
|
4447
4514
|
const projectResult = await loadProjectConfigFromDir(projectDir, provider);
|
|
4448
4515
|
if (projectResult) return projectResult;
|
|
4449
|
-
if (
|
|
4450
|
-
|
|
4451
|
-
}
|
|
4452
|
-
return null;
|
|
4516
|
+
if (isHomeDirectory(projectDir)) return null;
|
|
4517
|
+
return loadProjectConfigFromDir(os5.homedir(), provider);
|
|
4453
4518
|
}
|
|
4454
4519
|
function validateProjectConfig(config) {
|
|
4455
4520
|
const result = projectConfigLoaderSchema.safeParse(config);
|
|
@@ -5236,10 +5301,13 @@ async function loadPluginSkills(pluginDir) {
|
|
|
5236
5301
|
// src/cli/lib/loading/source-fetcher.ts
|
|
5237
5302
|
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
5238
5303
|
import { createHash as createHash2 } from "crypto";
|
|
5239
|
-
import {
|
|
5304
|
+
import { readFileSync } from "fs";
|
|
5305
|
+
import { rename, stat } from "fs/promises";
|
|
5240
5306
|
import { downloadTemplate } from "giget";
|
|
5241
5307
|
import os8 from "os";
|
|
5242
5308
|
import path17 from "path";
|
|
5309
|
+
import { isDeepEqual } from "remeda";
|
|
5310
|
+
import { z as z4 } from "zod";
|
|
5243
5311
|
|
|
5244
5312
|
// src/cli/lib/marketplace-generator.ts
|
|
5245
5313
|
import path16 from "path";
|
|
@@ -5368,17 +5436,43 @@ var MarketplaceUnreachableError = class extends Error {
|
|
|
5368
5436
|
reason;
|
|
5369
5437
|
};
|
|
5370
5438
|
var TarballWithheldError = class extends Error {
|
|
5439
|
+
status;
|
|
5371
5440
|
constructor({ status, statusText }) {
|
|
5372
5441
|
super(`the marketplace answered ${status} ${statusText}`.trimEnd());
|
|
5373
5442
|
this.name = "TarballWithheldError";
|
|
5443
|
+
this.status = status;
|
|
5374
5444
|
}
|
|
5375
5445
|
};
|
|
5376
5446
|
var marketplaceMustAnswer = new AsyncLocalStorage3();
|
|
5377
5447
|
function askingEachMarketplaceItself(body) {
|
|
5378
|
-
|
|
5448
|
+
const differingCopiesReplaced = /* @__PURE__ */ new Set();
|
|
5449
|
+
return marketplaceMustAnswer.run(differingCopiesReplaced, () => body(differingCopiesReplaced));
|
|
5379
5450
|
}
|
|
5380
5451
|
function mustAnswer() {
|
|
5381
|
-
return marketplaceMustAnswer.getStore()
|
|
5452
|
+
return marketplaceMustAnswer.getStore() !== void 0;
|
|
5453
|
+
}
|
|
5454
|
+
var refusalStopsTheLoad = new AsyncLocalStorage3();
|
|
5455
|
+
function stoppingOnARefusal(body) {
|
|
5456
|
+
return refusalStopsTheLoad.run(true, body);
|
|
5457
|
+
}
|
|
5458
|
+
function stopsOnARefusal() {
|
|
5459
|
+
return refusalStopsTheLoad.getStore() !== void 0;
|
|
5460
|
+
}
|
|
5461
|
+
var METHOD_NOT_ALLOWED = 405;
|
|
5462
|
+
function postureOn(status) {
|
|
5463
|
+
if (mustAnswer()) return "stop";
|
|
5464
|
+
if (status === METHOD_NOT_ALLOWED || isServerError(status)) return "keep";
|
|
5465
|
+
if (!isClientError(status)) return void 0;
|
|
5466
|
+
return stopsOnARefusal() ? "stop" : "pass over";
|
|
5467
|
+
}
|
|
5468
|
+
var FIRST_CLIENT_ERROR = 400;
|
|
5469
|
+
var FIRST_SERVER_ERROR = 500;
|
|
5470
|
+
var PAST_THE_SERVER_ERRORS = 600;
|
|
5471
|
+
function isClientError(status) {
|
|
5472
|
+
return status >= FIRST_CLIENT_ERROR && status < FIRST_SERVER_ERROR;
|
|
5473
|
+
}
|
|
5474
|
+
function isServerError(status) {
|
|
5475
|
+
return status >= FIRST_SERVER_ERROR && status < PAST_THE_SERVER_ERRORS;
|
|
5382
5476
|
}
|
|
5383
5477
|
function sanitizeSourceForCache(source) {
|
|
5384
5478
|
const hash = createHash2("sha256").update(source).digest("hex").slice(0, CACHE_HASH_LENGTH);
|
|
@@ -5430,8 +5524,10 @@ function getGigetCacheDir(source) {
|
|
|
5430
5524
|
return void 0;
|
|
5431
5525
|
}
|
|
5432
5526
|
const templateName = uriMatch.groups.repo.replace("/", "-").replace(/[^\da-z-]/gi, "-");
|
|
5433
|
-
|
|
5434
|
-
|
|
5527
|
+
return path17.join(gigetCacheRoot(), providerName, templateName);
|
|
5528
|
+
}
|
|
5529
|
+
function gigetCacheRoot() {
|
|
5530
|
+
return process.env.XDG_CACHE_HOME ? path17.resolve(process.env.XDG_CACHE_HOME, "giget") : path17.resolve(os8.homedir(), ".cache", "giget");
|
|
5435
5531
|
}
|
|
5436
5532
|
async function clearGigetCache(source) {
|
|
5437
5533
|
const gigetDir = getGigetCacheDir(source);
|
|
@@ -5448,7 +5544,7 @@ async function fetchFromRemoteSource(source, subdir) {
|
|
|
5448
5544
|
verbose(`Cache directory: ${cacheDir}`);
|
|
5449
5545
|
if (await directoryExists2(cacheDir)) {
|
|
5450
5546
|
const verdict = await revalidateCachedCopy(cacheDir, source);
|
|
5451
|
-
if (verdict
|
|
5547
|
+
if (keepsTheCopy(verdict)) {
|
|
5452
5548
|
verbose(`Using cached marketplace: ${cacheDir}`);
|
|
5453
5549
|
return {
|
|
5454
5550
|
path: cacheDir,
|
|
@@ -5460,7 +5556,8 @@ async function fetchFromRemoteSource(source, subdir) {
|
|
|
5460
5556
|
announceRefetch(verdict);
|
|
5461
5557
|
if (!mustAnswer()) await discardCachedCopy(cacheDir, source);
|
|
5462
5558
|
}
|
|
5463
|
-
|
|
5559
|
+
const differingCopiesReplaced = marketplaceMustAnswer.getStore();
|
|
5560
|
+
return differingCopiesReplaced ? downloadAnsweredFor(cacheDir, source, fullSource, differingCopiesReplaced) : downloadFreshCopy(cacheDir, source, fullSource);
|
|
5464
5561
|
}
|
|
5465
5562
|
async function discardCachedCopy(cacheDir, source) {
|
|
5466
5563
|
await clearGigetCache(source);
|
|
@@ -5469,14 +5566,15 @@ async function discardCachedCopy(cacheDir, source) {
|
|
|
5469
5566
|
async function downloadFreshCopy(cacheDir, source, fullSource) {
|
|
5470
5567
|
await ensureDir(path17.dirname(cacheDir));
|
|
5471
5568
|
try {
|
|
5472
|
-
const result = await
|
|
5569
|
+
const { result, savedTarball } = await gigetDownload(source, fullSource, {
|
|
5473
5570
|
dir: cacheDir,
|
|
5474
5571
|
force: true,
|
|
5475
5572
|
// Always force when downloading to avoid "already exists" error
|
|
5476
5573
|
offline: false
|
|
5477
5574
|
});
|
|
5478
5575
|
verbose(`Downloaded to: ${result.dir}`);
|
|
5479
|
-
await
|
|
5576
|
+
if (savedTarball) await askBeforeKeepingTheSavedTarball(cacheDir, result, source);
|
|
5577
|
+
await recordFetchedCopy(cacheDir, result, savedTarball);
|
|
5480
5578
|
markCopyCurrentForThisRun(cacheDir);
|
|
5481
5579
|
return {
|
|
5482
5580
|
path: result.dir,
|
|
@@ -5488,19 +5586,50 @@ async function downloadFreshCopy(cacheDir, source, fullSource) {
|
|
|
5488
5586
|
throw createDetailedFetchError(error, source);
|
|
5489
5587
|
}
|
|
5490
5588
|
}
|
|
5589
|
+
async function askBeforeKeepingTheSavedTarball(cacheDir, result, source) {
|
|
5590
|
+
const tar = tarballOf(result);
|
|
5591
|
+
if (tar === void 0) return;
|
|
5592
|
+
const answer = await answerAbout(tar);
|
|
5593
|
+
if (answer === "answered") return;
|
|
5594
|
+
if (answer === "unreachable") {
|
|
5595
|
+
warn(sourceUnreachableUsingCache(source));
|
|
5596
|
+
return;
|
|
5597
|
+
}
|
|
5598
|
+
if (stopsTheLoad(answer)) {
|
|
5599
|
+
await remove(cacheDir);
|
|
5600
|
+
throw answer;
|
|
5601
|
+
}
|
|
5602
|
+
announceTheCopyKept(answer, source);
|
|
5603
|
+
}
|
|
5604
|
+
async function answerAbout(tar) {
|
|
5605
|
+
try {
|
|
5606
|
+
await fetchEtag(tar);
|
|
5607
|
+
return "answered";
|
|
5608
|
+
} catch (error) {
|
|
5609
|
+
if (error instanceof TarballWithheldError) return error;
|
|
5610
|
+
verbose(`Could not ask ${tar} about the tarball giget saved: ${getErrorMessage(error)}`);
|
|
5611
|
+
return "unreachable";
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5491
5614
|
var STAGED_DOWNLOAD_SUFFIX = ".download";
|
|
5492
|
-
|
|
5615
|
+
var ONLY_A_SAVED_COPY_CAME_BACK = "the download failed and only a saved copy came back";
|
|
5616
|
+
var SET_ASIDE_SUFFIX = ".set-aside";
|
|
5617
|
+
async function downloadAnsweredFor(cacheDir, source, fullSource, differingCopiesReplaced) {
|
|
5493
5618
|
const staged = `${cacheDir}${STAGED_DOWNLOAD_SUFFIX}`;
|
|
5619
|
+
const downloadStaged = () => gigetDownload(source, fullSource, {
|
|
5620
|
+
dir: staged,
|
|
5621
|
+
force: true,
|
|
5622
|
+
forceClean: true,
|
|
5623
|
+
offline: false
|
|
5624
|
+
});
|
|
5494
5625
|
await ensureDir(path17.dirname(cacheDir));
|
|
5495
5626
|
try {
|
|
5496
|
-
const result = await
|
|
5497
|
-
dir: staged,
|
|
5498
|
-
force: true,
|
|
5499
|
-
forceClean: true,
|
|
5500
|
-
offline: false
|
|
5501
|
-
});
|
|
5627
|
+
const { result, savedTarball } = await downloadStaged();
|
|
5502
5628
|
const record = await askAfterTheDownload(result, source);
|
|
5629
|
+
if (savedTarball) await downloadPast(savedTarball, record, downloadStaged, source);
|
|
5630
|
+
const differed = await savedCopyDiffers(cacheDir, staged);
|
|
5503
5631
|
await replaceCopy(cacheDir, staged, record);
|
|
5632
|
+
if (differed) differingCopiesReplaced.add(source);
|
|
5504
5633
|
markCopyCurrentForThisRun(cacheDir);
|
|
5505
5634
|
return { path: cacheDir, fromCache: false, unreachable: false, source: fullSource };
|
|
5506
5635
|
} catch (error) {
|
|
@@ -5510,11 +5639,99 @@ async function downloadAnsweredFor(cacheDir, source, fullSource) {
|
|
|
5510
5639
|
await remove(staged);
|
|
5511
5640
|
}
|
|
5512
5641
|
}
|
|
5642
|
+
async function downloadPast(savedTarball, record, download, source) {
|
|
5643
|
+
if (!savedUnder(savedTarball, record)) {
|
|
5644
|
+
throw new MarketplaceUnreachableError(source, ONLY_A_SAVED_COPY_CAME_BACK);
|
|
5645
|
+
}
|
|
5646
|
+
await withTarballSetAside(savedTarball.path, download);
|
|
5647
|
+
}
|
|
5648
|
+
async function withTarballSetAside(tarball, download) {
|
|
5649
|
+
const record = gigetRecordOf(tarball);
|
|
5650
|
+
await rename(record, setAsideOf(record));
|
|
5651
|
+
await rename(tarball, setAsideOf(tarball));
|
|
5652
|
+
try {
|
|
5653
|
+
await download();
|
|
5654
|
+
} catch (error) {
|
|
5655
|
+
await rename(setAsideOf(tarball), tarball);
|
|
5656
|
+
await rename(setAsideOf(record), record);
|
|
5657
|
+
throw error;
|
|
5658
|
+
}
|
|
5659
|
+
await Promise.all([remove(setAsideOf(tarball)), remove(setAsideOf(record))]);
|
|
5660
|
+
}
|
|
5661
|
+
function setAsideOf(file) {
|
|
5662
|
+
return `${file}${SET_ASIDE_SUFFIX}`;
|
|
5663
|
+
}
|
|
5664
|
+
async function savedCopyDiffers(cacheDir, downloaded) {
|
|
5665
|
+
if (!await directoryExists2(cacheDir)) return false;
|
|
5666
|
+
try {
|
|
5667
|
+
return !await holdSameFiles(cacheDir, downloaded);
|
|
5668
|
+
} catch (error) {
|
|
5669
|
+
verbose(`Could not read the saved copy at ${cacheDir}: ${getErrorMessage(error)}`);
|
|
5670
|
+
return true;
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
async function holdSameFiles(left, right) {
|
|
5674
|
+
const [leftFiles, rightFiles] = await Promise.all([everyFileIn(left), everyFileIn(right)]);
|
|
5675
|
+
return isDeepEqual(leftFiles, rightFiles) && leftFiles.every((file) => sameBytesAt(file, left, right));
|
|
5676
|
+
}
|
|
5677
|
+
var EVERY_FILE = "**/*";
|
|
5678
|
+
function everyFileIn(dir) {
|
|
5679
|
+
return glob(EVERY_FILE, dir, { dot: true });
|
|
5680
|
+
}
|
|
5681
|
+
function sameBytesAt(file, left, right) {
|
|
5682
|
+
return readFileSync(path17.join(left, file)).equals(readFileSync(path17.join(right, file)));
|
|
5683
|
+
}
|
|
5513
5684
|
async function replaceCopy(cacheDir, staged, record) {
|
|
5514
5685
|
await remove(cacheDir);
|
|
5515
5686
|
await rename(staged, cacheDir);
|
|
5516
5687
|
await writeFile(fetchRecordPath(cacheDir), JSON.stringify(record));
|
|
5517
5688
|
}
|
|
5689
|
+
var GIGET_TARBALLS = "**/*.tar.gz";
|
|
5690
|
+
var gigetTarballRecordSchema = z4.object({ etag: z4.string().min(1).optional() });
|
|
5691
|
+
async function gigetDownload(source, fullSource, options) {
|
|
5692
|
+
const providerDir = gigetProviderDir(source);
|
|
5693
|
+
const timesBefore = await tarballTimes(providerDir);
|
|
5694
|
+
const result = await downloadTemplate(fullSource, options);
|
|
5695
|
+
const tarball = path17.join(providerDir, gigetTarballOf(result));
|
|
5696
|
+
const writtenByThisDownload = timesBefore.get(tarball) !== await modifiedAt(tarball);
|
|
5697
|
+
if (writtenByThisDownload) return { result };
|
|
5698
|
+
verbose(`giget extracted the tarball it saved earlier, not a download: ${tarball}`);
|
|
5699
|
+
return { result, savedTarball: { path: tarball, etag: await etagSavedWith(tarball) } };
|
|
5700
|
+
}
|
|
5701
|
+
function gigetProviderDir(source) {
|
|
5702
|
+
const provider = SOURCE_PROTO_RE.exec(source)?.[1];
|
|
5703
|
+
if (provider === void 0) throw new Error(`No provider named in '${source}'`);
|
|
5704
|
+
return path17.join(gigetCacheRoot(), provider);
|
|
5705
|
+
}
|
|
5706
|
+
async function tarballTimes(providerDir) {
|
|
5707
|
+
const tarballs = await glob(GIGET_TARBALLS, providerDir);
|
|
5708
|
+
const paths = tarballs.map((tarball) => path17.join(providerDir, tarball));
|
|
5709
|
+
return new Map(await Promise.all(paths.map(async (at) => [at, await modifiedAt(at)])));
|
|
5710
|
+
}
|
|
5711
|
+
async function modifiedAt(file) {
|
|
5712
|
+
return await fileExists(file) ? (await stat(file)).mtimeMs : void 0;
|
|
5713
|
+
}
|
|
5714
|
+
function gigetTarballOf(result) {
|
|
5715
|
+
const name = result.name;
|
|
5716
|
+
const version = result.version;
|
|
5717
|
+
if (typeof name !== "string") throw new Error("the download named no template");
|
|
5718
|
+
const stem = typeof version === "string" && version !== "" ? version : name;
|
|
5719
|
+
return path17.join(name, `${stem}.tar.gz`);
|
|
5720
|
+
}
|
|
5721
|
+
function gigetRecordOf(tarball) {
|
|
5722
|
+
return `${tarball}.json`;
|
|
5723
|
+
}
|
|
5724
|
+
async function etagSavedWith(tarballPath) {
|
|
5725
|
+
const raw = await readFileOptional(gigetRecordOf(tarballPath));
|
|
5726
|
+
const parsed = gigetTarballRecordSchema.safeParse(parseJsonOrUndefined(raw));
|
|
5727
|
+
return parsed.success ? parsed.data.etag : void 0;
|
|
5728
|
+
}
|
|
5729
|
+
function savedUnder(savedTarball, record) {
|
|
5730
|
+
return savedTarball.etag !== void 0 && savedTarball.etag === record.etag;
|
|
5731
|
+
}
|
|
5732
|
+
function keepsTheCopy(verdict) {
|
|
5733
|
+
return verdict === "current" || verdict === "unreachable" || verdict === "refused";
|
|
5734
|
+
}
|
|
5518
5735
|
var REVALIDATION_TIMEOUT_MS = 5e3;
|
|
5519
5736
|
var FETCH_RECORD_SUFFIX = ".etag.json";
|
|
5520
5737
|
var askedThisRun = /* @__PURE__ */ new Map();
|
|
@@ -5546,21 +5763,31 @@ async function classifyCachedCopy(cacheDir, source) {
|
|
|
5546
5763
|
return "current";
|
|
5547
5764
|
}
|
|
5548
5765
|
try {
|
|
5549
|
-
|
|
5550
|
-
if (live !== void 0 && record.etag !== void 0) {
|
|
5551
|
-
return live === record.etag ? "current" : "superseded";
|
|
5552
|
-
}
|
|
5553
|
-
if (mustAnswer()) return "unconfirmed";
|
|
5554
|
-
verbose(`${record.tar} answered without an ETag \u2014 keeping the cached copy`);
|
|
5555
|
-
return "current";
|
|
5766
|
+
return judgeAnswer(record, await fetchEtag(record.tar));
|
|
5556
5767
|
} catch (error) {
|
|
5557
|
-
if (error instanceof TarballWithheldError)
|
|
5768
|
+
if (error instanceof TarballWithheldError) return stopOrKeepTheCopy(error, source);
|
|
5558
5769
|
verbose(`Could not revalidate ${record.tar}: ${getErrorMessage(error)}`);
|
|
5559
5770
|
if (mustAnswer()) throw new MarketplaceUnreachableError(source, getErrorMessage(error));
|
|
5560
5771
|
warn(sourceUnreachableUsingCache(source));
|
|
5561
5772
|
return "unreachable";
|
|
5562
5773
|
}
|
|
5563
5774
|
}
|
|
5775
|
+
function stopOrKeepTheCopy(refusal2, source) {
|
|
5776
|
+
if (stopsTheLoad(refusal2)) throw createDetailedFetchError(refusal2, source);
|
|
5777
|
+
announceTheCopyKept(refusal2, source);
|
|
5778
|
+
return "refused";
|
|
5779
|
+
}
|
|
5780
|
+
function judgeAnswer(record, live) {
|
|
5781
|
+
if (movedOn(record, live)) return "superseded";
|
|
5782
|
+
if (mustAnswer()) return "answered";
|
|
5783
|
+
if (live === void 0) {
|
|
5784
|
+
verbose(`${record.tar} answered without an ETag \u2014 keeping the cached copy`);
|
|
5785
|
+
}
|
|
5786
|
+
return "current";
|
|
5787
|
+
}
|
|
5788
|
+
function movedOn(record, live) {
|
|
5789
|
+
return live !== void 0 && record.etag !== void 0 && live !== record.etag;
|
|
5790
|
+
}
|
|
5564
5791
|
async function fetchEtag(tar) {
|
|
5565
5792
|
const auth = process.env.GIGET_AUTH;
|
|
5566
5793
|
const response = await fetch(tar, {
|
|
@@ -5569,9 +5796,22 @@ async function fetchEtag(tar) {
|
|
|
5569
5796
|
signal: AbortSignal.timeout(REVALIDATION_TIMEOUT_MS)
|
|
5570
5797
|
});
|
|
5571
5798
|
await response.body?.cancel();
|
|
5572
|
-
if (
|
|
5799
|
+
if (withheld(response)) throw new TarballWithheldError(response);
|
|
5573
5800
|
return response.headers.get("etag") ?? void 0;
|
|
5574
5801
|
}
|
|
5802
|
+
function withheld({ ok, status }) {
|
|
5803
|
+
return !ok && postureOn(status) !== void 0;
|
|
5804
|
+
}
|
|
5805
|
+
function stopsTheLoad(refusal2) {
|
|
5806
|
+
return postureOn(refusal2.status) === "stop";
|
|
5807
|
+
}
|
|
5808
|
+
function announceTheCopyKept(refusal2, source) {
|
|
5809
|
+
if (postureOn(refusal2.status) === "keep") {
|
|
5810
|
+
warn(sourceRefusedUsingCache(source, refusal2.status));
|
|
5811
|
+
return;
|
|
5812
|
+
}
|
|
5813
|
+
verbose(`Keeping the saved copy of ${source} over its refusal: ${refusal2.message}`);
|
|
5814
|
+
}
|
|
5575
5815
|
function fetchRecordPath(cacheDir) {
|
|
5576
5816
|
return `${cacheDir}${FETCH_RECORD_SUFFIX}`;
|
|
5577
5817
|
}
|
|
@@ -5585,13 +5825,13 @@ async function readFetchRecord(cacheDir) {
|
|
|
5585
5825
|
}
|
|
5586
5826
|
return parsed.data;
|
|
5587
5827
|
}
|
|
5588
|
-
async function recordFetchedCopy(cacheDir, result) {
|
|
5828
|
+
async function recordFetchedCopy(cacheDir, result, savedTarball) {
|
|
5589
5829
|
const tar = tarballOf(result);
|
|
5590
5830
|
if (tar === void 0) {
|
|
5591
5831
|
verbose("No tarball URL came back from the download \u2014 the copy cannot be revalidated");
|
|
5592
5832
|
return;
|
|
5593
5833
|
}
|
|
5594
|
-
const etag = await etagIfAnswered(tar);
|
|
5834
|
+
const etag = savedTarball ? savedTarball.etag : await etagIfAnswered(tar);
|
|
5595
5835
|
await writeFile(fetchRecordPath(cacheDir), JSON.stringify(fetchRecord(tar, etag)));
|
|
5596
5836
|
}
|
|
5597
5837
|
async function etagIfAnswered(tar) {
|
|
@@ -6140,7 +6380,7 @@ async function installationIfPresent(candidate) {
|
|
|
6140
6380
|
// src/cli/lib/hosts/claude-host.ts
|
|
6141
6381
|
import os12 from "os";
|
|
6142
6382
|
import path21 from "path";
|
|
6143
|
-
import { z as
|
|
6383
|
+
import { z as z6 } from "zod";
|
|
6144
6384
|
|
|
6145
6385
|
// src/cli/utils/exec.ts
|
|
6146
6386
|
import { spawn } from "child_process";
|
|
@@ -6243,24 +6483,24 @@ async function execCommand(command, args, options) {
|
|
|
6243
6483
|
|
|
6244
6484
|
// src/cli/lib/plugins/plugin-settings.ts
|
|
6245
6485
|
import path20 from "path";
|
|
6246
|
-
import { z as
|
|
6247
|
-
var pluginSettingsSchema =
|
|
6486
|
+
import { z as z5 } from "zod";
|
|
6487
|
+
var pluginSettingsSchema = z5.object({
|
|
6248
6488
|
// Absent when no plugin is enabled.
|
|
6249
|
-
enabledPlugins:
|
|
6489
|
+
enabledPlugins: z5.record(z5.string(), z5.unknown()).exactOptional()
|
|
6250
6490
|
}).passthrough();
|
|
6251
6491
|
var installationFields = {
|
|
6252
|
-
installPath:
|
|
6253
|
-
version:
|
|
6254
|
-
installedAt:
|
|
6492
|
+
installPath: z5.string(),
|
|
6493
|
+
version: z5.string(),
|
|
6494
|
+
installedAt: z5.string()
|
|
6255
6495
|
};
|
|
6256
|
-
var pluginInstallationSchema =
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6496
|
+
var pluginInstallationSchema = z5.discriminatedUnion("scope", [
|
|
6497
|
+
z5.object({ scope: z5.literal("project"), projectPath: z5.string(), ...installationFields }),
|
|
6498
|
+
z5.object({ scope: z5.literal("user"), ...installationFields }),
|
|
6499
|
+
z5.object({ scope: z5.literal("local"), ...installationFields })
|
|
6260
6500
|
]);
|
|
6261
|
-
var installedPluginsSchema =
|
|
6262
|
-
version:
|
|
6263
|
-
plugins:
|
|
6501
|
+
var installedPluginsSchema = z5.object({
|
|
6502
|
+
version: z5.number(),
|
|
6503
|
+
plugins: z5.record(z5.string(), z5.array(pluginInstallationSchema))
|
|
6264
6504
|
}).passthrough();
|
|
6265
6505
|
function getInstalledPluginsRegistryPath(pluginsDir2) {
|
|
6266
6506
|
return path20.join(pluginsDir2, INSTALLED_PLUGINS_FILE);
|
|
@@ -6364,12 +6604,12 @@ async function isClaudeCLIAvailable(options) {
|
|
|
6364
6604
|
return false;
|
|
6365
6605
|
}
|
|
6366
6606
|
}
|
|
6367
|
-
var marketplaceInfoListSchema =
|
|
6368
|
-
|
|
6369
|
-
name:
|
|
6370
|
-
source:
|
|
6371
|
-
repo:
|
|
6372
|
-
path:
|
|
6607
|
+
var marketplaceInfoListSchema = z6.array(
|
|
6608
|
+
z6.object({
|
|
6609
|
+
name: z6.string(),
|
|
6610
|
+
source: z6.string(),
|
|
6611
|
+
repo: z6.string().exactOptional(),
|
|
6612
|
+
path: z6.string().exactOptional()
|
|
6373
6613
|
})
|
|
6374
6614
|
);
|
|
6375
6615
|
async function claudePluginMarketplaceList(options) {
|
|
@@ -6480,7 +6720,7 @@ function claudeHost() {
|
|
|
6480
6720
|
// src/cli/lib/hosts/codex-host.ts
|
|
6481
6721
|
import os13 from "os";
|
|
6482
6722
|
import path22 from "path";
|
|
6483
|
-
import { z as
|
|
6723
|
+
import { z as z7 } from "zod";
|
|
6484
6724
|
var CODEX = "codex";
|
|
6485
6725
|
var PLUGIN_CACHE_SUBDIR = "cache";
|
|
6486
6726
|
var STANDING_WARNING = /could not create PATH aliases/;
|
|
@@ -6543,22 +6783,22 @@ async function readJsonFromCodex(schema, args, options, attempt, askedFrom) {
|
|
|
6543
6783
|
}
|
|
6544
6784
|
return validated.data;
|
|
6545
6785
|
}
|
|
6546
|
-
var marketplaceRegistrySchema =
|
|
6547
|
-
marketplaces:
|
|
6548
|
-
|
|
6549
|
-
name:
|
|
6550
|
-
marketplaceSource:
|
|
6786
|
+
var marketplaceRegistrySchema = z7.object({
|
|
6787
|
+
marketplaces: z7.array(
|
|
6788
|
+
z7.object({
|
|
6789
|
+
name: z7.string(),
|
|
6790
|
+
marketplaceSource: z7.object({ sourceType: z7.string(), source: z7.string() })
|
|
6551
6791
|
})
|
|
6552
6792
|
)
|
|
6553
6793
|
});
|
|
6554
|
-
var pluginListingSchema =
|
|
6555
|
-
installed:
|
|
6556
|
-
|
|
6557
|
-
pluginId:
|
|
6558
|
-
name:
|
|
6559
|
-
marketplaceName:
|
|
6560
|
-
version:
|
|
6561
|
-
enabled:
|
|
6794
|
+
var pluginListingSchema = z7.object({
|
|
6795
|
+
installed: z7.array(
|
|
6796
|
+
z7.object({
|
|
6797
|
+
pluginId: z7.string(),
|
|
6798
|
+
name: z7.string(),
|
|
6799
|
+
marketplaceName: z7.string(),
|
|
6800
|
+
version: z7.string(),
|
|
6801
|
+
enabled: z7.boolean()
|
|
6562
6802
|
})
|
|
6563
6803
|
)
|
|
6564
6804
|
});
|
|
@@ -7004,12 +7244,14 @@ async function countDirEntries(dir, pred) {
|
|
|
7004
7244
|
return 0;
|
|
7005
7245
|
}
|
|
7006
7246
|
}
|
|
7007
|
-
function formatInstallationDisplay(info) {
|
|
7247
|
+
function formatInstallationDisplay(info, skillLines = []) {
|
|
7248
|
+
const namedSkillLines = skillLines.map((line2) => `
|
|
7249
|
+
${line2}`).join("");
|
|
7008
7250
|
const agentDirLines = info.agentDirs.map((dir) => `
|
|
7009
7251
|
Agents: ${dir}`).join("");
|
|
7010
7252
|
return `Installation: ${info.name}
|
|
7011
7253
|
Mode: ${INSTALL_MODE_LABELS[info.mode]}
|
|
7012
|
-
Skills: ${info.skillCount}
|
|
7254
|
+
Skills: ${info.skillCount}${namedSkillLines}
|
|
7013
7255
|
Agents: ${info.agentCount}
|
|
7014
7256
|
Config: ${info.configPath}${agentDirLines}`;
|
|
7015
7257
|
}
|
|
@@ -7529,16 +7771,15 @@ Compiled ${plural(results.length, "skill plugin")}:`);
|
|
|
7529
7771
|
|
|
7530
7772
|
// src/cli/lib/skills/local-skill-loader.ts
|
|
7531
7773
|
import path25 from "path";
|
|
7532
|
-
function copiedInSkillsAt(root) {
|
|
7774
|
+
function copiedInSkillsAt(root, provider) {
|
|
7533
7775
|
const scope = isHomeDirectory(root) ? "global" : "project";
|
|
7534
|
-
const provider = providerInUse(root);
|
|
7535
7776
|
return {
|
|
7536
7777
|
dir: skillsDir(provider, scope, root),
|
|
7537
7778
|
pathPrefix: skillsPathPrefix(provider, scope, root)
|
|
7538
7779
|
};
|
|
7539
7780
|
}
|
|
7540
|
-
async function discoverLocalSkills(root) {
|
|
7541
|
-
const { dir: localSkillsPath, pathPrefix } = copiedInSkillsAt(root);
|
|
7781
|
+
async function discoverLocalSkills(root, provider = providerInUse(root)) {
|
|
7782
|
+
const { dir: localSkillsPath, pathPrefix } = copiedInSkillsAt(root, provider);
|
|
7542
7783
|
if (!await directoryExists2(localSkillsPath)) {
|
|
7543
7784
|
verbose(`Local skills directory not found: ${localSkillsPath}`);
|
|
7544
7785
|
return null;
|
|
@@ -7739,9 +7980,10 @@ async function extractSkill(skillsDir2, metadataFile) {
|
|
|
7739
7980
|
const frontmatter = parseFrontmatterOrWarn(skillDir, skillMdPath, await readFile(skillMdPath));
|
|
7740
7981
|
if (!frontmatter) return null;
|
|
7741
7982
|
if (!metadata.displayName) {
|
|
7742
|
-
|
|
7743
|
-
`
|
|
7983
|
+
warn(
|
|
7984
|
+
`Skipping '${metadataFile}': invalid ${STANDARD_FILES.METADATA_YAML} \u2014 missing required field: ${METADATA_KEYS.DISPLAY_NAME}`
|
|
7744
7985
|
);
|
|
7986
|
+
return null;
|
|
7745
7987
|
}
|
|
7746
7988
|
const skillId = frontmatter.name;
|
|
7747
7989
|
const extracted = {
|
|
@@ -9678,7 +9920,7 @@ async function loadCatalogue(options) {
|
|
|
9678
9920
|
...catalogue,
|
|
9679
9921
|
marketplaceSkillIds: new Set(typedKeys(catalogue.matrix.skills))
|
|
9680
9922
|
};
|
|
9681
|
-
result.matrix = await mergeLocalSkills(result.matrix, resolvedProjectDir);
|
|
9923
|
+
result.matrix = await mergeLocalSkills(result.matrix, resolvedProjectDir, provider);
|
|
9682
9924
|
await seatGlobalInstallationSkills(result.matrix, source, purpose);
|
|
9683
9925
|
if (!options.skipExtraSources) {
|
|
9684
9926
|
await loadSkillsFromAllSources(
|
|
@@ -9840,12 +10082,12 @@ function goesOnWithoutManifest(source, purpose) {
|
|
|
9840
10082
|
function configuredLabel(sourceConfig) {
|
|
9841
10083
|
return sourceConfig.marketplace === void 0 ? {} : { marketplace: sourceConfig.marketplace };
|
|
9842
10084
|
}
|
|
9843
|
-
async function mergeLocalSkills(matrix2, projectDir) {
|
|
9844
|
-
const withGlobal = isHomeDirectory(projectDir) ? matrix2 : await mergeDiscoveredLocalSkills(matrix2, os14.homedir(), "global");
|
|
9845
|
-
return mergeDiscoveredLocalSkills(withGlobal, projectDir, "project");
|
|
10085
|
+
async function mergeLocalSkills(matrix2, projectDir, provider) {
|
|
10086
|
+
const withGlobal = isHomeDirectory(projectDir) ? matrix2 : await mergeDiscoveredLocalSkills(matrix2, os14.homedir(), "global", provider);
|
|
10087
|
+
return mergeDiscoveredLocalSkills(withGlobal, projectDir, "project", provider);
|
|
9846
10088
|
}
|
|
9847
|
-
async function mergeDiscoveredLocalSkills(matrix2, dir, label) {
|
|
9848
|
-
const discovered = await discoverLocalSkills(dir);
|
|
10089
|
+
async function mergeDiscoveredLocalSkills(matrix2, dir, label, provider) {
|
|
10090
|
+
const discovered = await discoverLocalSkills(dir, provider);
|
|
9849
10091
|
if (!discovered || discovered.skills.length === 0) return matrix2;
|
|
9850
10092
|
verbose(
|
|
9851
10093
|
`Found ${discovered.skills.length} ${label} local skill(s) in ${discovered.localSkillsPath}`
|
|
@@ -10110,9 +10352,11 @@ export {
|
|
|
10110
10352
|
pluginRefFor,
|
|
10111
10353
|
renderAgent,
|
|
10112
10354
|
renderAgentBody,
|
|
10355
|
+
isHomeDirectory,
|
|
10113
10356
|
sourceRootOf,
|
|
10114
|
-
|
|
10357
|
+
rootsHoldingTheRetiredSourceFolder,
|
|
10115
10358
|
chooseProviderForThisRun,
|
|
10359
|
+
forgetTheProviderChosenForThisRun,
|
|
10116
10360
|
providerInUse,
|
|
10117
10361
|
sourceFolderInUse,
|
|
10118
10362
|
relativeConfigPath,
|
|
@@ -10198,7 +10442,7 @@ export {
|
|
|
10198
10442
|
scopeNoun,
|
|
10199
10443
|
scopeLabel,
|
|
10200
10444
|
layoutIsCurrent,
|
|
10201
|
-
|
|
10445
|
+
retiredSourceFolderIgnored,
|
|
10202
10446
|
GlobalPairWriteViolation,
|
|
10203
10447
|
withGateToken,
|
|
10204
10448
|
assertGateToken,
|
|
@@ -10240,7 +10484,6 @@ export {
|
|
|
10240
10484
|
resolveInstallPaths,
|
|
10241
10485
|
providerToNameAt,
|
|
10242
10486
|
initProviderToNameAt,
|
|
10243
|
-
isHomeDirectory,
|
|
10244
10487
|
SOURCE_ENV_VAR,
|
|
10245
10488
|
readSourceRepoConfig,
|
|
10246
10489
|
loadSourceRepoConfig,
|
|
@@ -10280,6 +10523,7 @@ export {
|
|
|
10280
10523
|
flatUnion,
|
|
10281
10524
|
renderTypeImportLine,
|
|
10282
10525
|
spaces,
|
|
10526
|
+
EXTRACTED_FIELDS,
|
|
10283
10527
|
generateConfigSource,
|
|
10284
10528
|
refuseUnwritableStack,
|
|
10285
10529
|
generateBlankGlobalConfigSource,
|
|
@@ -10352,6 +10596,7 @@ export {
|
|
|
10352
10596
|
getMarketplaceStats,
|
|
10353
10597
|
MarketplaceUnreachableError,
|
|
10354
10598
|
askingEachMarketplaceItself,
|
|
10599
|
+
stoppingOnARefusal,
|
|
10355
10600
|
MarketplaceNameRefusedError,
|
|
10356
10601
|
fetchMarketplace,
|
|
10357
10602
|
isLocalOnlySkill,
|
|
@@ -10375,4 +10620,4 @@ export {
|
|
|
10375
10620
|
executeMigration,
|
|
10376
10621
|
keepsGlobalInstall
|
|
10377
10622
|
};
|
|
10378
|
-
//# sourceMappingURL=chunk-
|
|
10623
|
+
//# sourceMappingURL=chunk-E45IT3HC.js.map
|