@skaile/workspaces 1.7.0 → 1.8.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 +22 -0
- package/dist/chunk-34U5UC6G.js +284 -0
- package/dist/chunk-34U5UC6G.js.map +1 -0
- package/dist/{chunk-BSXBOKL6.js → chunk-35OWUKOD.js} +2 -2
- package/dist/{chunk-BSXBOKL6.js.map → chunk-35OWUKOD.js.map} +1 -1
- package/dist/{chunk-4OVPB7SI.js → chunk-6K6T2RBP.js} +6 -2
- package/dist/chunk-6K6T2RBP.js.map +1 -0
- package/dist/{chunk-TC3GLA5D.js → chunk-M3Y5KM6F.js} +3 -3
- package/dist/{chunk-TC3GLA5D.js.map → chunk-M3Y5KM6F.js.map} +1 -1
- package/dist/{chunk-SZY7X4M2.js → chunk-S74G7AZL.js} +2 -2
- package/dist/{chunk-SZY7X4M2.js.map → chunk-S74G7AZL.js.map} +1 -1
- package/dist/{chunk-7VGRRH2L.js → chunk-THJZ3JZE.js} +4 -4
- package/dist/{chunk-7VGRRH2L.js.map → chunk-THJZ3JZE.js.map} +1 -1
- package/dist/cli/index.js +178 -355
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/store.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +1 -1
- package/dist/project-4M6QXHCH.js +28 -0
- package/dist/project-4M6QXHCH.js.map +1 -0
- package/dist/run-group-engine/index.d.ts +2 -0
- package/dist/run-group-engine/index.js +68 -0
- package/dist/run-group-engine/index.js.map +1 -0
- package/dist/run-group-engine/src/admit.d.ts +13 -0
- package/dist/run-group-engine/src/admit.d.ts.map +1 -0
- package/dist/run-group-engine/src/derive-instance-status.d.ts +9 -0
- package/dist/run-group-engine/src/derive-instance-status.d.ts.map +1 -0
- package/dist/run-group-engine/src/index.d.ts +5 -0
- package/dist/run-group-engine/src/index.d.ts.map +1 -0
- package/dist/run-group-engine/src/plan-retry.d.ts +11 -0
- package/dist/run-group-engine/src/plan-retry.d.ts.map +1 -0
- package/dist/run-group-engine/src/rollup.d.ts +16 -0
- package/dist/run-group-engine/src/rollup.d.ts.map +1 -0
- package/dist/runner/index.js +2 -2
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/runner.js +2 -2
- package/dist/sdk/store.js +1 -1
- package/dist/{source-R4TWF424.js → source-KUWAEJOO.js} +3 -3
- package/dist/{source-R4TWF424.js.map → source-KUWAEJOO.js.map} +1 -1
- package/dist/{source-manifest-publish-FXDK2BCI.js → source-manifest-publish-FTSKRYPI.js} +3 -3
- package/dist/{source-manifest-publish-FXDK2BCI.js.map → source-manifest-publish-FTSKRYPI.js.map} +1 -1
- package/dist/store/index.js +1 -1
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/tui/index.js +2 -2
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/run-group.d.ts +148 -0
- package/dist/types/src/run-group.d.ts.map +1 -0
- package/dist/workspace-plugin/adapters/mcp.js +1 -1
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +7 -1
- package/dist/chunk-4OVPB7SI.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { AI_RESOURCES, aiResourceRoots } from '../chunk-VK24PIAB.js';
|
|
3
|
+
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportInstalledSoftDeps } from '../chunk-34U5UC6G.js';
|
|
4
|
+
import { makeSourceCommand, syncProjectSources } from '../chunk-THJZ3JZE.js';
|
|
3
5
|
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity } from '../chunk-MB6563TL.js';
|
|
4
|
-
import { makeSourceCommand, syncProjectSources } from '../chunk-7VGRRH2L.js';
|
|
5
6
|
import { openCatalogSource, openLibraryManager, createFullRegistry, openLibrary } from '../chunk-TITPPC54.js';
|
|
6
|
-
import { logErr, S, logOk, logInfo,
|
|
7
|
+
import { logErr, S, logOk, logInfo, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, logWarn, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth } from '../chunk-O3D4KYFG.js';
|
|
7
8
|
import { LocalSecretsProvider } from '../chunk-6BEGKO2Q.js';
|
|
8
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
9
|
+
import { runFlow, resumeFlow } from '../chunk-S74G7AZL.js';
|
|
9
10
|
import '../chunk-4R6DROGN.js';
|
|
10
11
|
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-GXC3TYMQ.js';
|
|
11
|
-
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-
|
|
12
|
-
import { buildClaudePluginFiles } from '../chunk-
|
|
12
|
+
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-M3Y5KM6F.js';
|
|
13
|
+
import { buildClaudePluginFiles } from '../chunk-35OWUKOD.js';
|
|
13
14
|
import '../chunk-X5YPJV4N.js';
|
|
14
15
|
import '../chunk-O7SG5PC2.js';
|
|
15
16
|
import '../chunk-7QBNJTTQ.js';
|
|
@@ -39,7 +40,7 @@ import '../chunk-UKJMQZV6.js';
|
|
|
39
40
|
import '../chunk-R7FOF242.js';
|
|
40
41
|
import '../chunk-STQOPWPS.js';
|
|
41
42
|
import '../chunk-CGYEHQOX.js';
|
|
42
|
-
import {
|
|
43
|
+
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor, checkAgentSkillConformance, readLock } from '../chunk-5NZ56R63.js';
|
|
43
44
|
import { assetSearchDirs, detectDomains } from '../chunk-ZAP2BDHG.js';
|
|
44
45
|
import { factoryAssetRoots } from '../chunk-7J7LQP6T.js';
|
|
45
46
|
import { globalCacheRoot, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, matchPin, coerceVersion, loadSkWorkspaceConfig, resolveSkWorkspaceConfig, storeManifestSlug } from '../chunk-ISA7R7PK.js';
|
|
@@ -62,7 +63,7 @@ import path14__default, { resolve, join } from 'path';
|
|
|
62
63
|
import { fileURLToPath } from 'url';
|
|
63
64
|
import { Help, Command, Option } from 'commander';
|
|
64
65
|
import { rcompare } from 'semver';
|
|
65
|
-
import * as
|
|
66
|
+
import * as p5 from '@clack/prompts';
|
|
66
67
|
import pc5 from 'picocolors';
|
|
67
68
|
import * as os from 'os';
|
|
68
69
|
import { homedir } from 'os';
|
|
@@ -138,7 +139,7 @@ async function searchIndex(query, kind) {
|
|
|
138
139
|
}
|
|
139
140
|
function searchFactory(projectDir, query, kind) {
|
|
140
141
|
const prefixes = factoryAssetRoots().map((r) => r.endsWith(path14__default.sep) ? r : r + path14__default.sep);
|
|
141
|
-
const isFactoryPath = (
|
|
142
|
+
const isFactoryPath = (p7) => prefixes.some((fp) => p7 === fp.slice(0, -1) || p7.startsWith(fp));
|
|
142
143
|
try {
|
|
143
144
|
return new AssetManager({ projectDir }).search(query, kind).filter((e) => isFactoryPath(e.source));
|
|
144
145
|
} catch {
|
|
@@ -157,7 +158,7 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
|
157
158
|
const factory = searchFactory(projectDir, query, kind);
|
|
158
159
|
let entries = unionEntries(await searchIndex(query, kind), factory);
|
|
159
160
|
if (entries.length === 0 && !query && !kind && !airGapped) {
|
|
160
|
-
const { autoSyncForSearch } = await import('../source-
|
|
161
|
+
const { autoSyncForSearch } = await import('../source-KUWAEJOO.js');
|
|
161
162
|
if (await autoSyncForSearch(projectDir)) {
|
|
162
163
|
entries = unionEntries(await searchIndex(query, kind), factory);
|
|
163
164
|
}
|
|
@@ -332,18 +333,18 @@ function makeAddCommand() {
|
|
|
332
333
|
backends,
|
|
333
334
|
driverTarget: opts.target
|
|
334
335
|
});
|
|
335
|
-
const
|
|
336
|
-
|
|
336
|
+
const spinner4 = p5.spinner();
|
|
337
|
+
spinner4.start(`Adding ${ref}`);
|
|
337
338
|
try {
|
|
338
339
|
const added = await am2.add(ref, { link: opts.link });
|
|
339
|
-
|
|
340
|
+
spinner4.stop("Done");
|
|
340
341
|
await promptSoftDepAdds(am2, ref, {
|
|
341
342
|
isTTY: !!process.stdin.isTTY,
|
|
342
343
|
link: opts.link,
|
|
343
344
|
withSoftDeps: opts.withSoftDeps,
|
|
344
345
|
noSoftDeps: opts.softDeps === false,
|
|
345
|
-
confirm: (message) =>
|
|
346
|
-
isCancel:
|
|
346
|
+
confirm: (message) => p5.confirm({ message, initialValue: false }),
|
|
347
|
+
isCancel: p5.isCancel,
|
|
347
348
|
onAdded: logOk,
|
|
348
349
|
onError: logErr,
|
|
349
350
|
onHint: (line) => logInfo(S.dim(line))
|
|
@@ -357,7 +358,7 @@ function makeAddCommand() {
|
|
|
357
358
|
else logInfo("Nothing to deploy (already up to date).");
|
|
358
359
|
} else for (const a of added) logOk(a);
|
|
359
360
|
} catch (err) {
|
|
360
|
-
|
|
361
|
+
spinner4.stop("Failed");
|
|
361
362
|
logErr(String(err));
|
|
362
363
|
process.exit(1);
|
|
363
364
|
}
|
|
@@ -384,8 +385,8 @@ function makeRemoveCommand() {
|
|
|
384
385
|
await promptSoftDepRemovals(am2, ref, {
|
|
385
386
|
isTTY: !!process.stdin.isTTY,
|
|
386
387
|
noSoftDeps: opts.softDeps === false,
|
|
387
|
-
confirm: (message) =>
|
|
388
|
-
isCancel:
|
|
388
|
+
confirm: (message) => p5.confirm({ message, initialValue: false }),
|
|
389
|
+
isCancel: p5.isCancel,
|
|
389
390
|
onRemoved: logOk,
|
|
390
391
|
onHint: (line) => logInfo(S.dim(line))
|
|
391
392
|
});
|
|
@@ -1039,10 +1040,10 @@ function makeCacheCommand() {
|
|
|
1039
1040
|
return;
|
|
1040
1041
|
}
|
|
1041
1042
|
if (!opts.yes) {
|
|
1042
|
-
const ok = await
|
|
1043
|
+
const ok = await p5.confirm({
|
|
1043
1044
|
message: opts.global ? "Clear project AND global cache?" : "Clear project cache?"
|
|
1044
1045
|
});
|
|
1045
|
-
if (
|
|
1046
|
+
if (p5.isCancel(ok) || !ok) {
|
|
1046
1047
|
logInfo("Cancelled.");
|
|
1047
1048
|
return;
|
|
1048
1049
|
}
|
|
@@ -1351,13 +1352,13 @@ function collectWorkspaceDefaults(projectDir) {
|
|
|
1351
1352
|
const wsDefaults = {};
|
|
1352
1353
|
try {
|
|
1353
1354
|
const ws = resolveSkWorkspaceConfig(projectDir);
|
|
1354
|
-
const
|
|
1355
|
-
if (
|
|
1356
|
-
if (
|
|
1357
|
-
if (
|
|
1358
|
-
if (
|
|
1359
|
-
if (
|
|
1360
|
-
if (
|
|
1355
|
+
const p7 = ws.agent_config?.default ?? {};
|
|
1356
|
+
if (p7.driver) wsDefaults.driver = p7.driver;
|
|
1357
|
+
if (p7.provider) wsDefaults.provider = p7.provider;
|
|
1358
|
+
if (p7.model) wsDefaults.model = p7.model;
|
|
1359
|
+
if (p7.skills_dir) wsDefaults.skills_dir = p7.skills_dir;
|
|
1360
|
+
if (p7.agents_dir) wsDefaults.agents_dir = p7.agents_dir;
|
|
1361
|
+
if (p7.prompts_dir) wsDefaults.prompts_dir = p7.prompts_dir;
|
|
1361
1362
|
} catch {
|
|
1362
1363
|
}
|
|
1363
1364
|
return wsDefaults;
|
|
@@ -2299,10 +2300,10 @@ var MCP_SERVER_ENTRY = {
|
|
|
2299
2300
|
function pluginDir(projectDir) {
|
|
2300
2301
|
return path14__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2301
2302
|
}
|
|
2302
|
-
async function readJsonStrict(
|
|
2303
|
+
async function readJsonStrict(p7) {
|
|
2303
2304
|
let raw;
|
|
2304
2305
|
try {
|
|
2305
|
-
raw = await fs6.readFile(
|
|
2306
|
+
raw = await fs6.readFile(p7, "utf-8");
|
|
2306
2307
|
} catch {
|
|
2307
2308
|
return null;
|
|
2308
2309
|
}
|
|
@@ -2310,13 +2311,13 @@ async function readJsonStrict(p8) {
|
|
|
2310
2311
|
return JSON.parse(raw);
|
|
2311
2312
|
} catch (e) {
|
|
2312
2313
|
throw new Error(
|
|
2313
|
-
`cannot parse ${
|
|
2314
|
+
`cannot parse ${p7}: ${e instanceof Error ? e.message : String(e)}; please fix or remove`
|
|
2314
2315
|
);
|
|
2315
2316
|
}
|
|
2316
2317
|
}
|
|
2317
|
-
async function writeJson(
|
|
2318
|
-
await fs6.mkdir(path14__default.dirname(
|
|
2319
|
-
await fs6.writeFile(
|
|
2318
|
+
async function writeJson(p7, value) {
|
|
2319
|
+
await fs6.mkdir(path14__default.dirname(p7), { recursive: true });
|
|
2320
|
+
await fs6.writeFile(p7, `${JSON.stringify(value, null, 2)}
|
|
2320
2321
|
`);
|
|
2321
2322
|
}
|
|
2322
2323
|
async function copyDir(src, dest) {
|
|
@@ -2371,7 +2372,7 @@ async function uninstall(projectDir) {
|
|
|
2371
2372
|
let changed = false;
|
|
2372
2373
|
const settings = await readJsonStrict(settingsPath);
|
|
2373
2374
|
if (settings && Array.isArray(settings.plugins)) {
|
|
2374
|
-
const next = settings.plugins.filter((
|
|
2375
|
+
const next = settings.plugins.filter((p7) => p7 !== dir);
|
|
2375
2376
|
if (next.length !== settings.plugins.length) {
|
|
2376
2377
|
changed = true;
|
|
2377
2378
|
const updated = { ...settings, plugins: next };
|
|
@@ -2418,7 +2419,7 @@ async function enable(projectDir) {
|
|
|
2418
2419
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2419
2420
|
if (detected.method === "plugin") {
|
|
2420
2421
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
2421
|
-
const next2 = disabled2.filter((
|
|
2422
|
+
const next2 = disabled2.filter((p7) => p7 !== detected.pluginPath);
|
|
2422
2423
|
if (next2.length === disabled2.length) return { changed: false };
|
|
2423
2424
|
const updated2 = { ...settings, disabledPlugins: next2 };
|
|
2424
2425
|
if (next2.length === 0) delete updated2.disabledPlugins;
|
|
@@ -2499,10 +2500,10 @@ function buildEntry(projectDir) {
|
|
|
2499
2500
|
env: { SKAILE_PROJECT_DIR: projectDir }
|
|
2500
2501
|
};
|
|
2501
2502
|
}
|
|
2502
|
-
async function readConfig(
|
|
2503
|
+
async function readConfig(p7) {
|
|
2503
2504
|
let raw;
|
|
2504
2505
|
try {
|
|
2505
|
-
raw = await fs6.readFile(
|
|
2506
|
+
raw = await fs6.readFile(p7, "utf-8");
|
|
2506
2507
|
} catch {
|
|
2507
2508
|
return null;
|
|
2508
2509
|
}
|
|
@@ -2510,41 +2511,41 @@ async function readConfig(p8) {
|
|
|
2510
2511
|
return parse$1(raw);
|
|
2511
2512
|
} catch (e) {
|
|
2512
2513
|
throw new Error(
|
|
2513
|
-
`cannot parse ${
|
|
2514
|
+
`cannot parse ${p7}: ${e instanceof Error ? e.message : String(e)}; please fix or remove`
|
|
2514
2515
|
);
|
|
2515
2516
|
}
|
|
2516
2517
|
}
|
|
2517
|
-
async function writeConfig(
|
|
2518
|
-
await fs6.mkdir(path14__default.dirname(
|
|
2518
|
+
async function writeConfig(p7, value) {
|
|
2519
|
+
await fs6.mkdir(path14__default.dirname(p7), { recursive: true });
|
|
2519
2520
|
const cleaned = {};
|
|
2520
2521
|
for (const [k, v] of Object.entries(value)) {
|
|
2521
2522
|
if (v === void 0) continue;
|
|
2522
2523
|
cleaned[k] = v;
|
|
2523
2524
|
}
|
|
2524
|
-
await fs6.writeFile(
|
|
2525
|
+
await fs6.writeFile(p7, stringify$1(cleaned));
|
|
2525
2526
|
}
|
|
2526
2527
|
function configPath(projectDir) {
|
|
2527
2528
|
return path14__default.join(projectDir, ".codex", "config.toml");
|
|
2528
2529
|
}
|
|
2529
2530
|
async function install2(projectDir) {
|
|
2530
|
-
const
|
|
2531
|
-
const cfg = await readConfig(
|
|
2531
|
+
const p7 = configPath(projectDir);
|
|
2532
|
+
const cfg = await readConfig(p7) ?? {};
|
|
2532
2533
|
const next = buildEntry(projectDir);
|
|
2533
2534
|
const servers = { ...cfg.mcp_servers ?? {} };
|
|
2534
2535
|
const previous = servers[SKAILE_MCP_NAME2];
|
|
2535
2536
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
2536
2537
|
let warning;
|
|
2537
2538
|
if (previous && !matches) {
|
|
2538
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path14__default.relative(projectDir,
|
|
2539
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path14__default.relative(projectDir, p7)}`;
|
|
2539
2540
|
}
|
|
2540
2541
|
if (matches) return { changed: false, method: "toml" };
|
|
2541
2542
|
servers[SKAILE_MCP_NAME2] = next;
|
|
2542
|
-
await writeConfig(
|
|
2543
|
+
await writeConfig(p7, { ...cfg, mcp_servers: servers });
|
|
2543
2544
|
return { changed: true, method: "toml", warning };
|
|
2544
2545
|
}
|
|
2545
2546
|
async function uninstall2(projectDir) {
|
|
2546
|
-
const
|
|
2547
|
-
const cfg = await readConfig(
|
|
2547
|
+
const p7 = configPath(projectDir);
|
|
2548
|
+
const cfg = await readConfig(p7);
|
|
2548
2549
|
if (!cfg?.mcp_servers || !(SKAILE_MCP_NAME2 in cfg.mcp_servers)) {
|
|
2549
2550
|
return { changed: false };
|
|
2550
2551
|
}
|
|
@@ -2552,15 +2553,15 @@ async function uninstall2(projectDir) {
|
|
|
2552
2553
|
const updated = { ...cfg, mcp_servers: rest };
|
|
2553
2554
|
if (Object.keys(rest).length === 0) delete updated.mcp_servers;
|
|
2554
2555
|
if (Object.keys(updated).length === 0) {
|
|
2555
|
-
await fs6.unlink(
|
|
2556
|
+
await fs6.unlink(p7);
|
|
2556
2557
|
} else {
|
|
2557
|
-
await writeConfig(
|
|
2558
|
+
await writeConfig(p7, updated);
|
|
2558
2559
|
}
|
|
2559
2560
|
return { changed: true };
|
|
2560
2561
|
}
|
|
2561
2562
|
async function status2(projectDir) {
|
|
2562
|
-
const
|
|
2563
|
-
const cfg = await readConfig(
|
|
2563
|
+
const p7 = configPath(projectDir);
|
|
2564
|
+
const cfg = await readConfig(p7);
|
|
2564
2565
|
const installed = !!(cfg?.mcp_servers && SKAILE_MCP_NAME2 in cfg.mcp_servers);
|
|
2565
2566
|
if (!installed) {
|
|
2566
2567
|
return {
|
|
@@ -2576,7 +2577,7 @@ async function status2(projectDir) {
|
|
|
2576
2577
|
installed: "yes",
|
|
2577
2578
|
enabled: "n/a",
|
|
2578
2579
|
method: "mcp",
|
|
2579
|
-
location: path14__default.relative(projectDir,
|
|
2580
|
+
location: path14__default.relative(projectDir, p7)
|
|
2580
2581
|
};
|
|
2581
2582
|
}
|
|
2582
2583
|
async function install3(projectDir) {
|
|
@@ -2793,7 +2794,7 @@ function printStatusTable(rows) {
|
|
|
2793
2794
|
const widths = cols.map(
|
|
2794
2795
|
(c) => Math.max(c.header.length, ...rows.map((r) => String(r[c.key] ?? "").length))
|
|
2795
2796
|
);
|
|
2796
|
-
const fmtRow = (parts) => parts.map((
|
|
2797
|
+
const fmtRow = (parts) => parts.map((p7, i) => p7.padEnd(widths[i] ?? p7.length)).join(" ");
|
|
2797
2798
|
console.log();
|
|
2798
2799
|
console.log(` ${S.heading(fmtRow(cols.map((c) => c.header)))}`);
|
|
2799
2800
|
for (const r of rows) {
|
|
@@ -3218,11 +3219,11 @@ function makeLibraryCommand() {
|
|
|
3218
3219
|
const { manager, close } = await openLibraryManager();
|
|
3219
3220
|
try {
|
|
3220
3221
|
if (!opts.yes) {
|
|
3221
|
-
const confirmed = await
|
|
3222
|
+
const confirmed = await p5.confirm({
|
|
3222
3223
|
message: `Remove library "${name}"${opts.purge ? " AND delete its directory" : ""}?`,
|
|
3223
3224
|
initialValue: false
|
|
3224
3225
|
});
|
|
3225
|
-
if (!confirmed ||
|
|
3226
|
+
if (!confirmed || p5.isCancel(confirmed)) {
|
|
3226
3227
|
logInfo("Cancelled.");
|
|
3227
3228
|
return;
|
|
3228
3229
|
}
|
|
@@ -5244,18 +5245,18 @@ function makeNpxCommand() {
|
|
|
5244
5245
|
);
|
|
5245
5246
|
process.exit(1);
|
|
5246
5247
|
}
|
|
5247
|
-
const
|
|
5248
|
+
const spinner4 = p5.spinner();
|
|
5248
5249
|
const key = sourceCacheKey(url);
|
|
5249
5250
|
const clonePath = path14__default.join(getGlobalCacheDir(), key);
|
|
5250
|
-
|
|
5251
|
+
spinner4.start(`Cloning ${url}`);
|
|
5251
5252
|
try {
|
|
5252
5253
|
if (!existsSync(clonePath)) {
|
|
5253
5254
|
mkdirSync(path14__default.dirname(clonePath), { recursive: true });
|
|
5254
5255
|
execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
|
|
5255
5256
|
}
|
|
5256
|
-
|
|
5257
|
+
spinner4.stop(`Cloned to ${key}`);
|
|
5257
5258
|
} catch (err) {
|
|
5258
|
-
|
|
5259
|
+
spinner4.stop("Clone failed");
|
|
5259
5260
|
logErr(err instanceof Error ? err.message : String(err));
|
|
5260
5261
|
process.exit(1);
|
|
5261
5262
|
}
|
|
@@ -5275,10 +5276,10 @@ function makeNpxCommand() {
|
|
|
5275
5276
|
}
|
|
5276
5277
|
const skillRef = `skill:@${publisher}/${skillName}`;
|
|
5277
5278
|
const am2 = new AssetManager({ projectDir, global: opts.global, driverTarget: opts.target });
|
|
5278
|
-
|
|
5279
|
+
spinner4.start(`Installing ${skillRef}`);
|
|
5279
5280
|
try {
|
|
5280
5281
|
const added = await am2.add(skillRef);
|
|
5281
|
-
|
|
5282
|
+
spinner4.stop("Done");
|
|
5282
5283
|
if (added.length === 0) {
|
|
5283
5284
|
logInfo(`${opts.skill} already deployed or not found in source.`);
|
|
5284
5285
|
} else {
|
|
@@ -5286,7 +5287,7 @@ function makeNpxCommand() {
|
|
|
5286
5287
|
}
|
|
5287
5288
|
logInfo(`Source registered in skaile.yaml \u2014 manage via ${S.cmd("skaile source")}.`);
|
|
5288
5289
|
} catch (err) {
|
|
5289
|
-
|
|
5290
|
+
spinner4.stop("Failed");
|
|
5290
5291
|
logErr(err.message);
|
|
5291
5292
|
process.exit(1);
|
|
5292
5293
|
}
|
|
@@ -5589,277 +5590,6 @@ function substituteString(value, resolve5, envVarsToSet) {
|
|
|
5589
5590
|
return "envRef" in resolved ? resolved.envRef : resolved.value;
|
|
5590
5591
|
});
|
|
5591
5592
|
}
|
|
5592
|
-
var REF_HINT = "kind:@<publisher>/<name>#<version> (e.g. skill:@skaile/use-exa#1.0.0)";
|
|
5593
|
-
function isValidAssetRef(ref) {
|
|
5594
|
-
try {
|
|
5595
|
-
parseAssetRef(ref);
|
|
5596
|
-
return true;
|
|
5597
|
-
} catch {
|
|
5598
|
-
return false;
|
|
5599
|
-
}
|
|
5600
|
-
}
|
|
5601
|
-
function supportsInstallManifest(source) {
|
|
5602
|
-
return typeof source?.getInstallManifest === "function";
|
|
5603
|
-
}
|
|
5604
|
-
async function runPointerOnlyInstall(ref, deps) {
|
|
5605
|
-
let requested;
|
|
5606
|
-
try {
|
|
5607
|
-
requested = parseAssetRef(ref);
|
|
5608
|
-
} catch (e) {
|
|
5609
|
-
throw new Error(
|
|
5610
|
-
`malformed asset ref '${ref}' \u2014 expected ${REF_HINT}: ${e instanceof Error ? e.message : String(e)}`
|
|
5611
|
-
);
|
|
5612
|
-
}
|
|
5613
|
-
const manifest = await deps.catalog.getInstallManifest(ref);
|
|
5614
|
-
const got = parseAssetRef(manifest.ref);
|
|
5615
|
-
if (got.kind !== requested.kind || got.publisher !== requested.publisher || got.name !== requested.name || got.pin !== requested.pin) {
|
|
5616
|
-
throw new Error(
|
|
5617
|
-
`catalog identity mismatch: requested '${ref}' but the catalog returned a manifest for '${manifest.ref}'`
|
|
5618
|
-
);
|
|
5619
|
-
}
|
|
5620
|
-
const { installPath } = await deps.library.install(manifest);
|
|
5621
|
-
return {
|
|
5622
|
-
installPath,
|
|
5623
|
-
commitSha: manifest.source.commitSha,
|
|
5624
|
-
fileCount: manifest.files.length
|
|
5625
|
-
};
|
|
5626
|
-
}
|
|
5627
|
-
function makeInstallCommand() {
|
|
5628
|
-
return new Command("install").description(`Install dependencies from skaile.yaml, or a single asset by ref (${REF_HINT})`).argument("[ref]", `Asset ref to install from the Catalog (${REF_HINT})`).option("--locked", "Install from lock file (CI mode \u2014 fails on drift)").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").option(
|
|
5629
|
-
"--global",
|
|
5630
|
-
"Install the global SSOT (~/.skaile/skaile.yaml), fanning out to every global backend"
|
|
5631
|
-
).option(
|
|
5632
|
-
"--backend <ids>",
|
|
5633
|
-
"Comma-separated global backends to install into (default: all resolved); implies --global"
|
|
5634
|
-
).option(
|
|
5635
|
-
"--link",
|
|
5636
|
-
"symlink local-path assets instead of copying (dev loop; machine-local, not for committing)"
|
|
5637
|
-
).action(runInstallCommand);
|
|
5638
|
-
}
|
|
5639
|
-
function parseBackendFilter2(raw) {
|
|
5640
|
-
if (!raw) return void 0;
|
|
5641
|
-
const ids = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
5642
|
-
const out = [];
|
|
5643
|
-
for (const id of ids) {
|
|
5644
|
-
if (!SUPPORTED_DRIVER_TARGETS.includes(id)) {
|
|
5645
|
-
logErr(`unknown backend '${id}' \u2014 expected one of: ${SUPPORTED_DRIVER_TARGETS.join(", ")}`);
|
|
5646
|
-
process.exit(1);
|
|
5647
|
-
}
|
|
5648
|
-
out.push(id);
|
|
5649
|
-
}
|
|
5650
|
-
return out.length > 0 ? out : void 0;
|
|
5651
|
-
}
|
|
5652
|
-
async function runInstallCommand(ref, opts) {
|
|
5653
|
-
if (ref !== void 0) {
|
|
5654
|
-
await runRefInstall(ref, opts);
|
|
5655
|
-
return;
|
|
5656
|
-
}
|
|
5657
|
-
await runYamlInstall(opts);
|
|
5658
|
-
}
|
|
5659
|
-
async function runRefInstall(ref, opts) {
|
|
5660
|
-
if (!isValidAssetRef(ref)) {
|
|
5661
|
-
logErr(`malformed asset ref '${ref}' \u2014 expected ${REF_HINT}`);
|
|
5662
|
-
process.exit(1);
|
|
5663
|
-
}
|
|
5664
|
-
const spinner5 = p6.spinner();
|
|
5665
|
-
spinner5.start(`Installing ${ref}`);
|
|
5666
|
-
try {
|
|
5667
|
-
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-ST2VFQTK.js');
|
|
5668
|
-
const catalog = await openCatalogSource2({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5669
|
-
if (!supportsInstallManifest(catalog)) {
|
|
5670
|
-
throw new Error(
|
|
5671
|
-
"pointer-only install (skaile install <ref>) requires a tRPC-framed Catalog. The configured catalog uses REST framing, which does not serve install manifests. Set catalog.url to https://skaile.store, or catalog.framing: trpc, in ~/.skaile/config.yaml."
|
|
5672
|
-
);
|
|
5673
|
-
}
|
|
5674
|
-
const library = await openLibrary2();
|
|
5675
|
-
try {
|
|
5676
|
-
const result = await runPointerOnlyInstall(ref, { catalog, library });
|
|
5677
|
-
spinner5.stop("Done");
|
|
5678
|
-
logOk(`Installed ${colorRef(ref)}`);
|
|
5679
|
-
logInfo(`Path: ${S.dim(result.installPath)}`);
|
|
5680
|
-
logInfo(`Commit: ${S.dim(result.commitSha)}`);
|
|
5681
|
-
logInfo(`Files: ${S.dim(String(result.fileCount))}`);
|
|
5682
|
-
logInfo(
|
|
5683
|
-
S.dim(`Installed globally (see Path above) \u2014 use \`skaile add ${ref}\` to deploy into this project.`)
|
|
5684
|
-
);
|
|
5685
|
-
} finally {
|
|
5686
|
-
library.close();
|
|
5687
|
-
}
|
|
5688
|
-
} catch (err) {
|
|
5689
|
-
spinner5.stop("Failed");
|
|
5690
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
5691
|
-
if (/unreachable/i.test(msg)) {
|
|
5692
|
-
logErr(`asset uninstallable \u2014 source commit no longer available (${msg})`);
|
|
5693
|
-
} else {
|
|
5694
|
-
logErr(msg);
|
|
5695
|
-
}
|
|
5696
|
-
process.exit(1);
|
|
5697
|
-
}
|
|
5698
|
-
}
|
|
5699
|
-
async function runYamlInstall(opts) {
|
|
5700
|
-
const projectDir = path14__default.resolve(opts.projectDir);
|
|
5701
|
-
const backends = parseBackendFilter2(opts.backend);
|
|
5702
|
-
if (opts.global || backends) {
|
|
5703
|
-
await runGlobalInstall(opts, backends);
|
|
5704
|
-
return;
|
|
5705
|
-
}
|
|
5706
|
-
try {
|
|
5707
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-NXBYK5GP.js');
|
|
5708
|
-
const hydrate = ensureSourcesCloned(projectDir, { quiet: true });
|
|
5709
|
-
if (hydrate.cloned.length > 0) {
|
|
5710
|
-
logOk(`Cloned source(s): ${hydrate.cloned.join(", ")}`);
|
|
5711
|
-
}
|
|
5712
|
-
if (hydrate.failed.length > 0) {
|
|
5713
|
-
logErr(`Failed to clone source(s): ${hydrate.failed.join(", ")}`);
|
|
5714
|
-
}
|
|
5715
|
-
} catch (err) {
|
|
5716
|
-
logWarn(`source hydration skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
5717
|
-
}
|
|
5718
|
-
const am2 = new AssetManager({
|
|
5719
|
-
projectDir,
|
|
5720
|
-
driverTarget: opts.target
|
|
5721
|
-
});
|
|
5722
|
-
const spinner5 = p6.spinner();
|
|
5723
|
-
spinner5.start(opts.locked ? "Installing from lock file" : "Installing dependencies");
|
|
5724
|
-
try {
|
|
5725
|
-
const result = await am2.install({ locked: opts.locked, link: opts.link });
|
|
5726
|
-
spinner5.stop("Done");
|
|
5727
|
-
if (result.deployed.length > 0) {
|
|
5728
|
-
for (const d of result.deployed) logOk(d);
|
|
5729
|
-
}
|
|
5730
|
-
if (result.removed.length > 0) {
|
|
5731
|
-
for (const r of result.removed) logWarn(`Removed: ${r}`);
|
|
5732
|
-
}
|
|
5733
|
-
if (result.deployed.length === 0 && result.removed.length === 0) {
|
|
5734
|
-
logInfo("Nothing to install (already up to date).");
|
|
5735
|
-
}
|
|
5736
|
-
if (result.missing.length > 0) {
|
|
5737
|
-
for (const m of result.missing) logErr(`Missing: ${m}`);
|
|
5738
|
-
process.exitCode = 1;
|
|
5739
|
-
}
|
|
5740
|
-
if (result.lockWritten) {
|
|
5741
|
-
logInfo(`Lock file written: ${S.dim("skaile.lock.yaml")}`);
|
|
5742
|
-
}
|
|
5743
|
-
if (!opts.locked) await reportInstalledSoftDeps(am2);
|
|
5744
|
-
} catch (err) {
|
|
5745
|
-
spinner5.stop("Failed");
|
|
5746
|
-
logErr(String(err));
|
|
5747
|
-
process.exit(1);
|
|
5748
|
-
}
|
|
5749
|
-
}
|
|
5750
|
-
async function reportInstalledSoftDeps(am2, onHint = (l) => logInfo(S.dim(l))) {
|
|
5751
|
-
try {
|
|
5752
|
-
const declared = am2.listDeclared().map((d) => d.ref);
|
|
5753
|
-
if (declared.length === 0) return;
|
|
5754
|
-
const edges = await am2.reportSoftDeps(declared);
|
|
5755
|
-
for (const edge of edges) onHint(formatSoftDepHint(edge));
|
|
5756
|
-
} catch {
|
|
5757
|
-
}
|
|
5758
|
-
}
|
|
5759
|
-
async function runGlobalInstall(opts, backends) {
|
|
5760
|
-
const am2 = new AssetManager({
|
|
5761
|
-
projectDir: path14__default.resolve(opts.projectDir),
|
|
5762
|
-
global: true,
|
|
5763
|
-
backends
|
|
5764
|
-
});
|
|
5765
|
-
const spinner5 = p6.spinner();
|
|
5766
|
-
spinner5.start("Installing global dependencies");
|
|
5767
|
-
try {
|
|
5768
|
-
const result = await am2.install({ locked: opts.locked, link: opts.link });
|
|
5769
|
-
spinner5.stop("Done");
|
|
5770
|
-
if (result.deployed.length > 0) for (const d of result.deployed) logOk(d);
|
|
5771
|
-
if (result.removed.length > 0) for (const r of result.removed) logWarn(`Removed: ${r}`);
|
|
5772
|
-
if (result.deployed.length === 0 && result.removed.length === 0)
|
|
5773
|
-
logInfo("Nothing to install (already up to date).");
|
|
5774
|
-
if (result.missing.length > 0) {
|
|
5775
|
-
for (const m of result.missing) logErr(`Missing: ${m}`);
|
|
5776
|
-
process.exitCode = 1;
|
|
5777
|
-
}
|
|
5778
|
-
if (result.lockWritten) logInfo(`Global lock written: ${S.dim("~/.skaile/skaile.lock.yaml")}`);
|
|
5779
|
-
const state2 = am2.globalState({});
|
|
5780
|
-
const byBackend = /* @__PURE__ */ new Map();
|
|
5781
|
-
for (const s of state2)
|
|
5782
|
-
if (s.state === "installed") byBackend.set(s.backend, (byBackend.get(s.backend) ?? 0) + 1);
|
|
5783
|
-
for (const [backend, n] of byBackend) logInfo(`${backend}: ${n} installed`);
|
|
5784
|
-
} catch (err) {
|
|
5785
|
-
spinner5.stop("Failed");
|
|
5786
|
-
logErr(String(err));
|
|
5787
|
-
process.exit(1);
|
|
5788
|
-
}
|
|
5789
|
-
}
|
|
5790
|
-
function makeCheckCommand() {
|
|
5791
|
-
return new Command("check").description("Check for unmet requirements").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
5792
|
-
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5793
|
-
const issues = am2.doctor();
|
|
5794
|
-
if (issues.length === 0) {
|
|
5795
|
-
logOk("All dependencies satisfied.");
|
|
5796
|
-
} else {
|
|
5797
|
-
for (const i of issues) {
|
|
5798
|
-
logErr(
|
|
5799
|
-
`${i.assetKind}:${i.assetName} requires ${i.depKind}:${i.depName} (${i.inRepos ? "fixable" : "not found"})`
|
|
5800
|
-
);
|
|
5801
|
-
}
|
|
5802
|
-
process.exit(1);
|
|
5803
|
-
}
|
|
5804
|
-
});
|
|
5805
|
-
}
|
|
5806
|
-
function makeCleanCommand() {
|
|
5807
|
-
return new Command("clean").description("Remove all skaile-managed assets from the workspace").option("--all", "Full reset: also remove history, patches, repos, and lock file").option("--dry-run", "Show what would be removed without doing it").option("-y, --yes", "Skip confirmation prompt").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").action(async (opts) => {
|
|
5808
|
-
const am2 = new AssetManager({
|
|
5809
|
-
projectDir: path14__default.resolve(opts.projectDir),
|
|
5810
|
-
driverTarget: opts.target
|
|
5811
|
-
});
|
|
5812
|
-
const lock = readLock(path14__default.resolve(opts.projectDir, "skaile.lock.yaml"));
|
|
5813
|
-
if (!lock || Object.keys(lock.assets).length === 0) {
|
|
5814
|
-
logInfo("Nothing to clean (no skaile-managed assets found).");
|
|
5815
|
-
return;
|
|
5816
|
-
}
|
|
5817
|
-
const assetRefs = Object.keys(lock.assets);
|
|
5818
|
-
console.log();
|
|
5819
|
-
console.log(` ${S.heading("Assets to remove:")} ${S.dim(`(${assetRefs.length})`)}`);
|
|
5820
|
-
for (const ref of assetRefs) {
|
|
5821
|
-
console.log(` ${colorRef(ref)}`);
|
|
5822
|
-
}
|
|
5823
|
-
if (opts.all) {
|
|
5824
|
-
console.log();
|
|
5825
|
-
console.log(` ${S.heading("Also removing:")}`);
|
|
5826
|
-
console.log(` ${S.dim(".skaile/history.yaml")}`);
|
|
5827
|
-
console.log(` ${S.dim(".skaile/patches/")}`);
|
|
5828
|
-
console.log(` ${S.dim("skaile.lock.yaml")}`);
|
|
5829
|
-
}
|
|
5830
|
-
if (opts.dryRun) {
|
|
5831
|
-
console.log();
|
|
5832
|
-
logInfo("Dry run \u2014 no changes made.");
|
|
5833
|
-
return;
|
|
5834
|
-
}
|
|
5835
|
-
if (!opts.yes) {
|
|
5836
|
-
const confirm7 = await p6.confirm({ message: "Proceed?" });
|
|
5837
|
-
if (p6.isCancel(confirm7) || !confirm7) {
|
|
5838
|
-
logInfo("Cancelled.");
|
|
5839
|
-
return;
|
|
5840
|
-
}
|
|
5841
|
-
}
|
|
5842
|
-
const result = am2.clean({ all: opts.all });
|
|
5843
|
-
console.log();
|
|
5844
|
-
for (const r of result.removed) {
|
|
5845
|
-
logOk(`Removed ${r}`);
|
|
5846
|
-
}
|
|
5847
|
-
for (const s of result.skipped) {
|
|
5848
|
-
logWarn(`Skipped ${s.ref}: ${s.reason}`);
|
|
5849
|
-
}
|
|
5850
|
-
if (result.unmanaged.length > 0) {
|
|
5851
|
-
console.log();
|
|
5852
|
-
logInfo(`Kept ${result.unmanaged.length} unmanaged asset(s):`);
|
|
5853
|
-
for (const u of result.unmanaged) {
|
|
5854
|
-
console.log(` ${S.dim(u)}`);
|
|
5855
|
-
}
|
|
5856
|
-
}
|
|
5857
|
-
if (opts.all) {
|
|
5858
|
-
console.log();
|
|
5859
|
-
logOk("Full reset complete.");
|
|
5860
|
-
}
|
|
5861
|
-
});
|
|
5862
|
-
}
|
|
5863
5593
|
function buildPresetFromWorkspace(config, name, sources = []) {
|
|
5864
5594
|
const items = [];
|
|
5865
5595
|
for (const ref of config.dependencies ?? []) {
|
|
@@ -6600,7 +6330,7 @@ function makeRunCommand() {
|
|
|
6600
6330
|
logErr("No flows available.");
|
|
6601
6331
|
process.exit(1);
|
|
6602
6332
|
}
|
|
6603
|
-
const selected = await
|
|
6333
|
+
const selected = await p5.select({
|
|
6604
6334
|
message: "Select a flow to run",
|
|
6605
6335
|
options: flows.map((f) => ({
|
|
6606
6336
|
value: f.id,
|
|
@@ -6608,8 +6338,8 @@ function makeRunCommand() {
|
|
|
6608
6338
|
hint: f.description
|
|
6609
6339
|
}))
|
|
6610
6340
|
});
|
|
6611
|
-
if (
|
|
6612
|
-
|
|
6341
|
+
if (p5.isCancel(selected)) {
|
|
6342
|
+
p5.cancel("Cancelled.");
|
|
6613
6343
|
process.exit(0);
|
|
6614
6344
|
}
|
|
6615
6345
|
flowId = selected;
|
|
@@ -6778,11 +6508,11 @@ function makeReplCommand() {
|
|
|
6778
6508
|
console.log();
|
|
6779
6509
|
logWarn(`No skaile.yaml found in ${S.cmd(userCwd)} or any parent directory.`);
|
|
6780
6510
|
console.log();
|
|
6781
|
-
const shouldCreate = await
|
|
6511
|
+
const shouldCreate = await p5.confirm({
|
|
6782
6512
|
message: "Create a temporary workspace? (session state in /tmp/)"
|
|
6783
6513
|
});
|
|
6784
|
-
if (
|
|
6785
|
-
|
|
6514
|
+
if (p5.isCancel(shouldCreate) || !shouldCreate) {
|
|
6515
|
+
p5.cancel("Cancelled.");
|
|
6786
6516
|
process.exit(0);
|
|
6787
6517
|
}
|
|
6788
6518
|
const tmpDir = fs13__default.mkdtempSync(path14__default.join(os2.tmpdir(), "skaile-repl-"));
|
|
@@ -7735,13 +7465,102 @@ function makeStoreCommand() {
|
|
|
7735
7465
|
);
|
|
7736
7466
|
process.exit(2);
|
|
7737
7467
|
});
|
|
7738
|
-
store.command("search <query>").description("Search the
|
|
7739
|
-
|
|
7740
|
-
|
|
7468
|
+
store.command("search <query>").description("Search the AI Asset Store catalog by name, description, or publisher").option("--kind <kind>", "Filter by asset kind (skill, agent, prompt, flow, \u2026)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
|
|
7469
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-ST2VFQTK.js');
|
|
7470
|
+
try {
|
|
7471
|
+
const remote = await openCatalogSource2({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
7472
|
+
const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
|
|
7473
|
+
const results = filterCatalogAssets(assets, query);
|
|
7474
|
+
if (results.length === 0) {
|
|
7475
|
+
logInfo(`No store results for "${query}".`);
|
|
7476
|
+
return;
|
|
7477
|
+
}
|
|
7478
|
+
console.log();
|
|
7479
|
+
for (const a of results) {
|
|
7480
|
+
const ref = catalogAssetRef(a);
|
|
7481
|
+
console.log(
|
|
7482
|
+
` \u2B21 ${kindColorPad(a.kind)} ${colorRef(ref).padEnd(48)} ${S.dim((a.description ?? "").slice(0, 60))}`
|
|
7483
|
+
);
|
|
7484
|
+
}
|
|
7485
|
+
console.log(
|
|
7486
|
+
`
|
|
7487
|
+
${S.dim(`${results.length} result(s) \xB7 \`skaile store show <ref>\` for details`)}
|
|
7488
|
+
`
|
|
7489
|
+
);
|
|
7490
|
+
} catch (e) {
|
|
7491
|
+
if (e instanceof LocalCatalogDisabledError) {
|
|
7492
|
+
logErr(
|
|
7493
|
+
"Remote catalog disabled (catalog.url: local). Set `catalog.url: https://skaile.store` in ~/.skaile/config.yaml."
|
|
7494
|
+
);
|
|
7495
|
+
} else {
|
|
7496
|
+
logErr(`Store search failed: ${e.message}`);
|
|
7497
|
+
}
|
|
7498
|
+
process.exit(1);
|
|
7499
|
+
}
|
|
7741
7500
|
});
|
|
7742
|
-
store.command("show <ref>").description("Show details + provenance
|
|
7743
|
-
|
|
7744
|
-
|
|
7501
|
+
store.command("show <ref>").description("Show a store asset's details + provenance (source, files, integrity)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (ref, opts) => {
|
|
7502
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-ST2VFQTK.js');
|
|
7503
|
+
const { supportsInstallManifest } = await import('../project-4M6QXHCH.js');
|
|
7504
|
+
try {
|
|
7505
|
+
const remote = await openCatalogSource2({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
7506
|
+
const asset = await remote.resolve(ref);
|
|
7507
|
+
if (!asset) {
|
|
7508
|
+
logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
|
|
7509
|
+
process.exit(1);
|
|
7510
|
+
}
|
|
7511
|
+
const canonical = catalogAssetRef(asset);
|
|
7512
|
+
let manifest = null;
|
|
7513
|
+
if (supportsInstallManifest(remote)) {
|
|
7514
|
+
manifest = await remote.getInstallManifest(canonical).catch(() => null);
|
|
7515
|
+
}
|
|
7516
|
+
const field = (label, value) => ` ${S.label(label.padEnd(11))}${value}`;
|
|
7517
|
+
console.log();
|
|
7518
|
+
console.log(
|
|
7519
|
+
` ${kindColorPad(asset.kind)} ${S.heading(`@${asset.publisher}/${asset.name}`)} ${S.dim(`v${asset.version}`)}`
|
|
7520
|
+
);
|
|
7521
|
+
console.log(` ${S.rule(52)}`);
|
|
7522
|
+
if (asset.description) {
|
|
7523
|
+
console.log();
|
|
7524
|
+
console.log(` ${asset.description}`);
|
|
7525
|
+
}
|
|
7526
|
+
console.log();
|
|
7527
|
+
if (manifest) console.log(field("Tier", manifest.tier));
|
|
7528
|
+
if (asset.category) console.log(field("Category", asset.category));
|
|
7529
|
+
if (asset.license) console.log(field("License", asset.license));
|
|
7530
|
+
if (manifest) {
|
|
7531
|
+
console.log();
|
|
7532
|
+
console.log(` ${S.heading("Source")}`);
|
|
7533
|
+
console.log(field("Repo", manifest.source.url));
|
|
7534
|
+
console.log(field("Commit", manifest.source.commitSha));
|
|
7535
|
+
console.log();
|
|
7536
|
+
console.log(` ${S.heading(`Files (${manifest.files.length})`)}`);
|
|
7537
|
+
for (const f of manifest.files) {
|
|
7538
|
+
console.log(` ${S.dim(f.sha256.slice(0, 12))} ${f.path}`);
|
|
7539
|
+
}
|
|
7540
|
+
console.log();
|
|
7541
|
+
console.log(field("Integrity", manifest.sha256));
|
|
7542
|
+
} else if (asset.repo) {
|
|
7543
|
+
console.log(field("Repo", asset.repo));
|
|
7544
|
+
if (asset.sha256) console.log(field("Integrity", asset.sha256));
|
|
7545
|
+
}
|
|
7546
|
+
if (asset.softDeps?.length) {
|
|
7547
|
+
console.log();
|
|
7548
|
+
console.log(` ${S.heading("Soft dependencies")}`);
|
|
7549
|
+
for (const dep of asset.softDeps) console.log(` ${S.dim("\u2192")} ${dep}`);
|
|
7550
|
+
}
|
|
7551
|
+
console.log();
|
|
7552
|
+
console.log(` ${S.dim(`Install: skaile add ${canonical}`)}`);
|
|
7553
|
+
console.log();
|
|
7554
|
+
} catch (e) {
|
|
7555
|
+
if (e instanceof LocalCatalogDisabledError) {
|
|
7556
|
+
logErr(
|
|
7557
|
+
"Remote catalog disabled (catalog.url: local). Set `catalog.url: https://skaile.store` in ~/.skaile/config.yaml."
|
|
7558
|
+
);
|
|
7559
|
+
} else {
|
|
7560
|
+
logErr(`Store show failed: ${e.message}`);
|
|
7561
|
+
}
|
|
7562
|
+
process.exit(1);
|
|
7563
|
+
}
|
|
7745
7564
|
});
|
|
7746
7565
|
store.command("favourite <ref>").description("Pin a ref to your favourites (not yet wired)").action((_ref) => {
|
|
7747
7566
|
logErr("`skaile store favourite` is scaffolded but not yet wired.");
|
|
@@ -7776,9 +7595,13 @@ function makeStoreCommand() {
|
|
|
7776
7595
|
}
|
|
7777
7596
|
try {
|
|
7778
7597
|
const jwt = await getStoreToken();
|
|
7779
|
-
await storeFetch(
|
|
7780
|
-
|
|
7781
|
-
|
|
7598
|
+
await storeFetch(
|
|
7599
|
+
{ ...getStoreConfig(), jwt },
|
|
7600
|
+
`/api/assets/${publisher}/${slug}/${version}/yank`,
|
|
7601
|
+
{
|
|
7602
|
+
method: "PATCH"
|
|
7603
|
+
}
|
|
7604
|
+
);
|
|
7782
7605
|
logOk(`Yanked v${version} of @${publisher}/${slug}`);
|
|
7783
7606
|
} catch (e) {
|
|
7784
7607
|
logErr(e.message);
|
|
@@ -7822,7 +7645,7 @@ function makeUpdateCommand() {
|
|
|
7822
7645
|
async (_name, opts) => {
|
|
7823
7646
|
if (opts.catalog !== false) {
|
|
7824
7647
|
try {
|
|
7825
|
-
const catalogSpinner =
|
|
7648
|
+
const catalogSpinner = p5.spinner();
|
|
7826
7649
|
catalogSpinner.start("Refreshing catalog cache");
|
|
7827
7650
|
const remote = await openCatalogSource({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
7828
7651
|
const result2 = await remote.refresh();
|
|
@@ -7838,7 +7661,7 @@ function makeUpdateCommand() {
|
|
|
7838
7661
|
if (opts.catalogOnly) return;
|
|
7839
7662
|
const projectDir = path14__default.resolve(opts.projectDir);
|
|
7840
7663
|
if (await shouldSyncSources(opts)) {
|
|
7841
|
-
const syncSpinner =
|
|
7664
|
+
const syncSpinner = p5.spinner();
|
|
7842
7665
|
syncSpinner.start("Syncing sources");
|
|
7843
7666
|
const { total, synced, failed } = await syncProjectSources(projectDir);
|
|
7844
7667
|
syncSpinner.stop(
|
|
@@ -7846,10 +7669,10 @@ function makeUpdateCommand() {
|
|
|
7846
7669
|
);
|
|
7847
7670
|
}
|
|
7848
7671
|
const am2 = new AssetManager({ projectDir });
|
|
7849
|
-
const
|
|
7850
|
-
|
|
7672
|
+
const spinner4 = p5.spinner();
|
|
7673
|
+
spinner4.start("Re-deploying assets");
|
|
7851
7674
|
const result = await am2.install();
|
|
7852
|
-
|
|
7675
|
+
spinner4.stop("Done");
|
|
7853
7676
|
if (result.deployed.length > 0) {
|
|
7854
7677
|
for (const d of result.deployed) logOk(`Updated ${d}`);
|
|
7855
7678
|
} else {
|
|
@@ -7861,12 +7684,12 @@ function makeUpdateCommand() {
|
|
|
7861
7684
|
async function shouldSyncSources(opts) {
|
|
7862
7685
|
if (opts.sync === false) return false;
|
|
7863
7686
|
if (opts.yes || !process.stdin.isTTY) return true;
|
|
7864
|
-
const answer = await
|
|
7687
|
+
const answer = await p5.confirm({
|
|
7865
7688
|
message: "Sync sources from upstream before re-deploying?",
|
|
7866
7689
|
initialValue: true
|
|
7867
7690
|
});
|
|
7868
|
-
if (
|
|
7869
|
-
|
|
7691
|
+
if (p5.isCancel(answer)) {
|
|
7692
|
+
p5.cancel("Cancelled.");
|
|
7870
7693
|
process.exit(130);
|
|
7871
7694
|
}
|
|
7872
7695
|
return answer;
|