@skaile/workspaces 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/{asset-feeds-EGSG4FUB.js → asset-feeds-AOZLZMDV.js} +2 -2
  3. package/dist/{asset-feeds-EGSG4FUB.js.map → asset-feeds-AOZLZMDV.js.map} +1 -1
  4. package/dist/asset-manager/index.js +1 -1
  5. package/dist/asset-manager/src/index.d.ts +47 -0
  6. package/dist/asset-manager/src/index.d.ts.map +1 -1
  7. package/dist/{chunk-NHLXS2CH.js → chunk-JUZGLINM.js} +2 -2
  8. package/dist/{chunk-NHLXS2CH.js.map → chunk-JUZGLINM.js.map} +1 -1
  9. package/dist/{chunk-JUZLVRI4.js → chunk-L6BKSTAX.js} +71 -4
  10. package/dist/chunk-L6BKSTAX.js.map +1 -0
  11. package/dist/{chunk-7NQXVBCQ.js → chunk-LHUCCPH4.js} +2 -2
  12. package/dist/{chunk-7NQXVBCQ.js.map → chunk-LHUCCPH4.js.map} +1 -1
  13. package/dist/{chunk-5LHPKVGR.js → chunk-N2KV5RK3.js} +121 -4
  14. package/dist/chunk-N2KV5RK3.js.map +1 -0
  15. package/dist/cli/index.js +841 -553
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/src/commands/asset-cmd.d.ts +1 -1
  18. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  19. package/dist/cli/src/commands/catalog.d.ts +9 -3
  20. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  21. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  22. package/dist/cli/src/commands/skailify-lib.d.ts +108 -0
  23. package/dist/cli/src/commands/skailify-lib.d.ts.map +1 -0
  24. package/dist/core/index.js +1 -1
  25. package/dist/core/src/index.d.ts +1 -1
  26. package/dist/core/src/index.d.ts.map +1 -1
  27. package/dist/factory-assets/connectors/flow/run-flow.js +1 -1
  28. package/dist/factory-assets/skaile.manifest.yaml +3 -0
  29. package/dist/factory-assets/skills/skailify/SKILL.md +84 -0
  30. package/dist/{plugin-store-RBCDBO7K.js → plugin-store-2X2YXJVG.js} +2 -2
  31. package/dist/{plugin-store-RBCDBO7K.js.map → plugin-store-2X2YXJVG.js.map} +1 -1
  32. package/dist/runner/index.js +2 -2
  33. package/dist/runner/src/file-changed-coalescer.d.ts +48 -0
  34. package/dist/runner/src/file-changed-coalescer.d.ts.map +1 -0
  35. package/dist/runner/src/resources.d.ts.map +1 -1
  36. package/dist/sdk/asset-manager.js +1 -1
  37. package/dist/sdk/core.js +1 -1
  38. package/dist/sdk/index.js +2 -2
  39. package/dist/sdk/runner.js +2 -2
  40. package/dist/tui/index.js +2 -2
  41. package/dist/workspace-plugin/index.js +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunk-5LHPKVGR.js.map +0 -1
  44. package/dist/chunk-JUZLVRI4.js.map +0 -1
package/dist/cli/index.js CHANGED
@@ -9,11 +9,11 @@ import '../chunk-5FVJXQDP.js';
9
9
  import '../chunk-JXT46QFC.js';
10
10
  import '../chunk-UKJMQZV6.js';
11
11
  import '../chunk-R7FOF242.js';
12
- import { runFlow, resumeFlow } from '../chunk-7NQXVBCQ.js';
12
+ import { runFlow, resumeFlow } from '../chunk-LHUCCPH4.js';
13
13
  import '../chunk-4R6DROGN.js';
14
14
  import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-GXC3TYMQ.js';
15
- import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-5LHPKVGR.js';
16
- import { buildClaudePluginFiles } from '../chunk-NHLXS2CH.js';
15
+ import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-N2KV5RK3.js';
16
+ import { buildClaudePluginFiles } from '../chunk-JUZGLINM.js';
17
17
  import '../chunk-X5YPJV4N.js';
18
18
  import '../chunk-O7SG5PC2.js';
19
19
  import '../chunk-7QBNJTTQ.js';
@@ -36,15 +36,15 @@ import '../chunk-6E6PKKAD.js';
36
36
  import { loadFlow, loadAllFlows } from '../chunk-X46FY45B.js';
37
37
  import '../chunk-DEYYRFQU.js';
38
38
  import '../chunk-IFGTRL2I.js';
39
- import { AssetManager, NON_DEPLOYABLE_KINDS } from '../chunk-JUZLVRI4.js';
39
+ import { AssetManager, NON_DEPLOYABLE_KINDS, MissingManifestError } from '../chunk-L6BKSTAX.js';
40
40
  import '../chunk-CVWA4RIK.js';
41
41
  import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor } from '../chunk-BLGHFVXE.js';
42
42
  import { assetSearchDirs, detectDomains } from '../chunk-ZAP2BDHG.js';
43
43
  import '../chunk-VPXV2Z5E.js';
44
44
  import { globalCacheRoot, getGlobalCacheDir, resolveAgentDir, findWorkspaceRoot, workspaceConfigFilename, resolveSkWorkspaceConfig } from '../chunk-COSTF7QW.js';
45
- import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest } from '../chunk-DZCK7GRW.js';
45
+ import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, saveSkPublishManifest } from '../chunk-DZCK7GRW.js';
46
46
  import { parseFrontmatter } from '../chunk-6IDBWPK2.js';
47
- import { parseAssetRef, ASSET_KINDS, isValidAssetName, ASSET_NAME_HINT, assetRefToStr } from '../chunk-GEEW6SY2.js';
47
+ import { parseAssetRef, ASSET_KINDS, isValidAssetName, slugifyAssetName, ASSET_NAME_HINT, assetRefToStr } from '../chunk-GEEW6SY2.js';
48
48
  import '../chunk-XGCXFX7X.js';
49
49
  import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
50
50
  import { DRIVER_DEFAULTS } from '../chunk-K5GBV4SA.js';
@@ -55,32 +55,483 @@ import '../chunk-XUXVH3JK.js';
55
55
  import '../chunk-RGPBEGP2.js';
56
56
  import '../chunk-CGYEHQOX.js';
57
57
  import '../chunk-NSBPE2FW.js';
58
- import * as fs11 from 'fs';
59
- import fs11__default, { readFileSync, existsSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
60
- import * as path13 from 'path';
61
- import path13__default, { resolve, join } from 'path';
58
+ import * as fs12 from 'fs';
59
+ import fs12__default, { readFileSync, existsSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
60
+ import * as path14 from 'path';
61
+ import path14__default, { resolve, join } from 'path';
62
62
  import { fileURLToPath } from 'url';
63
63
  import { Help, Command, Option } from 'commander';
64
- import { homedir } from 'os';
65
64
  import * as p6 from '@clack/prompts';
66
65
  import pc5 from 'picocolors';
66
+ import * as os from 'os';
67
+ import { homedir } from 'os';
68
+ import { parse, stringify } from 'yaml';
67
69
  import * as readline from 'readline';
68
70
  import { createInterface } from 'readline';
69
- import fs5 from 'fs/promises';
70
- import { parse as parse$1, stringify } from 'smol-toml';
71
+ import fs6 from 'fs/promises';
72
+ import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
71
73
  import { execSync, spawnSync } from 'child_process';
72
74
  import { createTRPCUntypedClient, httpLink, httpSubscriptionLink } from '@trpc/client';
73
- import { parse } from 'yaml';
74
75
 
76
+ async function runSearch(kind, query, opts) {
77
+ if (kind?.includes(":")) {
78
+ query = kind;
79
+ kind = void 0;
80
+ }
81
+ const showLocal = !opts.store;
82
+ const showStore = !opts.local;
83
+ if (showLocal) {
84
+ searchLocal(query, kind, opts, showStore);
85
+ }
86
+ if (showStore) {
87
+ await searchStore(query, kind, opts);
88
+ }
89
+ }
90
+ function searchLocal(query, kind, opts, showStore) {
91
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
92
+ const entries = am2.search(query, kind);
93
+ if (entries.length === 0) {
94
+ if (!showStore) {
95
+ logInfo(
96
+ query ? `No entries matching "${query}".` : "No assets found. Run `skaile source sync` first."
97
+ );
98
+ }
99
+ return;
100
+ }
101
+ if (showStore) {
102
+ console.log(`
103
+ ${S.heading("Local:")}`);
104
+ }
105
+ printLocalEntries(entries);
106
+ }
107
+ function printLocalEntries(entries) {
108
+ const byKind = /* @__PURE__ */ new Map();
109
+ for (const e of entries) {
110
+ if (!byKind.has(e.kind)) byKind.set(e.kind, []);
111
+ byKind.get(e.kind).push(e);
112
+ }
113
+ for (const [k, items] of byKind) {
114
+ const nameW = Math.max(4, ...items.map((e) => e.name.length));
115
+ console.log();
116
+ console.log(
117
+ ` ${kindColor(k)} ${S.heading(`${k.toUpperCase()}S`)} ${S.dim(`(${items.length})`)}`
118
+ );
119
+ console.log(` ${S.rule(nameW + 62)}`);
120
+ for (const e of items) {
121
+ const ver = e.version ? S.dim(` v${e.version}`) : "";
122
+ console.log(` ${S.cmd(e.name.padEnd(nameW))} ${e.description.slice(0, 60)}${ver}`);
123
+ }
124
+ }
125
+ console.log(`
126
+ ${S.dim(`${entries.length} total`)}
127
+ `);
128
+ }
129
+ async function searchStore(query, kind, opts) {
130
+ try {
131
+ const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-XFZFKY3W.js');
132
+ const config = getStoreConfig2();
133
+ const params = {};
134
+ if (query) params.q = query;
135
+ if (kind) params.kind = kind;
136
+ const storeRes = await storeFetch2(config, "/api/assets", { params });
137
+ if (storeRes.results.length > 0) {
138
+ console.log(`
139
+ ${S.heading("Store:")}`);
140
+ for (const asset of storeRes.results) {
141
+ const ref = `${asset.kind}:@${asset.publisher}/${asset.slug}`;
142
+ console.log(
143
+ ` \u2B21 ${kindColorPad(asset.kind)} ${colorRef(ref).padEnd(40)} ${S.dim(asset.description?.slice(0, 50) || "")} ${S.dim(`\u2193${asset.downloads}`)}`
144
+ );
145
+ }
146
+ } else if (opts.store) {
147
+ logInfo("No results in store");
148
+ }
149
+ } catch (e) {
150
+ if (opts.store) {
151
+ logErr(`Store search failed: ${e.message}`);
152
+ }
153
+ }
154
+ }
155
+ function makeSearchCommand() {
156
+ return new Command("search").description("Search across all repos").argument("[kind]", "Filter by asset kind").argument("[query]", "Search query").option("--project-dir <path>", "Project directory", process.cwd()).option("--store", "Search only the store").option("--local", "Search only local repos").action(async (kind, query, opts) => {
157
+ await runSearch(kind, query, opts);
158
+ });
159
+ }
160
+ function makeAddCommand() {
161
+ return new Command("add").description("Add to skaile.yaml + deploy").argument("<ref>", "Asset reference (kind:name[@repo])").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Deploy to global dir (~/.claude)").option("--target <agent>", "Driver target", "claude-code").action(async (ref, opts) => {
162
+ const am2 = new AssetManager({
163
+ projectDir: path14__default.resolve(opts.projectDir),
164
+ global: opts.global,
165
+ driverTarget: opts.target
166
+ });
167
+ const spinner5 = p6.spinner();
168
+ spinner5.start(`Adding ${ref}`);
169
+ try {
170
+ const added = await am2.add(ref);
171
+ spinner5.stop("Done");
172
+ if (added.length === 0) {
173
+ const kind = parseAssetRef(ref).kind;
174
+ if (NON_DEPLOYABLE_KINDS.has(kind))
175
+ logInfo(
176
+ `Recorded in skaile.yaml. ${kind} assets are not deployed into the driver target \u2014 they are wired when skaile runs the agent.`
177
+ );
178
+ else logInfo("Nothing to deploy (already up to date).");
179
+ } else for (const a of added) logOk(a);
180
+ } catch (err) {
181
+ spinner5.stop("Failed");
182
+ logErr(String(err));
183
+ process.exit(1);
184
+ }
185
+ });
186
+ }
187
+ function makeRemoveCommand() {
188
+ return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from global dir").option("--target <agent>", "Driver target", "claude-code").action((ref, opts) => {
189
+ const am2 = new AssetManager({
190
+ projectDir: path14__default.resolve(opts.projectDir),
191
+ global: opts.global,
192
+ driverTarget: opts.target
193
+ });
194
+ const ok = am2.remove(ref);
195
+ if (ok) logOk(`Removed ${ref}`);
196
+ else logErr(`Not deployed: ${ref}`);
197
+ });
198
+ }
199
+ function stateLabel(s) {
200
+ if (s === "installed") return S.ok(s);
201
+ if (s === "drift") return S.warn(s);
202
+ if (s === "invalid") return S.err(s);
203
+ return S.dim(s);
204
+ }
205
+ function makeListCommand() {
206
+ return new Command("list").description("List declared dependencies from skaile.yaml with state").argument("[kind]", "Filter by asset kind").option("--project-dir <path>", "Project directory", process.cwd()).option("-g, --global", "Inspect the global deployment dir for state").option("--json", "Output as JSON").addOption(
207
+ new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
208
+ ).action((kind, opts) => {
209
+ const am2 = new AssetManager({
210
+ projectDir: path14__default.resolve(opts.projectDir),
211
+ global: opts.global,
212
+ driverTarget: opts.target
213
+ });
214
+ let declared;
215
+ try {
216
+ declared = am2.listDeclared(kind);
217
+ } catch (err) {
218
+ if (err instanceof MissingManifestError)
219
+ logErr(`No ${S.cmd("skaile.yaml")} found. Run ${S.cmd("skaile init")} to create one.`);
220
+ else logErr(err instanceof Error ? err.message : String(err));
221
+ process.exit(1);
222
+ }
223
+ if (opts.json) {
224
+ console.log(JSON.stringify(declared, null, 2));
225
+ return;
226
+ }
227
+ if (declared.length === 0) {
228
+ logInfo("No dependencies declared in skaile.yaml.");
229
+ return;
230
+ }
231
+ const kindW = Math.max(4, ...declared.map((e) => e.kind.length));
232
+ const nameW = Math.max(4, ...declared.map((e) => e.name.length));
233
+ console.log();
234
+ console.log(
235
+ ` ${S.dim("KIND".padEnd(kindW))} ${S.dim("NAME".padEnd(nameW))} ${S.dim("STATE")}`
236
+ );
237
+ console.log(` ${S.rule(kindW + nameW + 4 + "installed".length)}`);
238
+ for (const e of declared) {
239
+ console.log(
240
+ ` ${kindColorPad(e.kind, kindW)} ${e.name.padEnd(nameW)} ${stateLabel(e.state)}`
241
+ );
242
+ }
243
+ console.log(`
244
+ ${S.dim(`${declared.length} declared`)}`);
245
+ const drift = declared.filter((e) => e.state === "drift").length;
246
+ if (drift > 0)
247
+ logInfo(`${drift} with drift \u2014 run ${S.cmd("skaile install")} to materialize.`);
248
+ const invalid = declared.filter((e) => e.state === "invalid").length;
249
+ if (invalid > 0)
250
+ logInfo(`${invalid} invalid \u2014 fix the ${S.cmd("skaile.yaml")} dependencies entry.`);
251
+ console.log();
252
+ });
253
+ }
254
+ function makeInfoCommand() {
255
+ return new Command("info").description("Show asset metadata, deps, deploy status").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
256
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
257
+ const entry = am2.info(ref);
258
+ if (!entry) {
259
+ logErr(
260
+ `'${ref}' not found. Run ${S.cmd("skaile source sync")} then ${S.cmd("skaile search")}.`
261
+ );
262
+ process.exit(1);
263
+ }
264
+ console.log();
265
+ console.log(` ${S.heading(entry.name)}`);
266
+ console.log(` ${S.rule(40)}`);
267
+ console.log(` kind: ${kindColor(entry.kind)}`);
268
+ if (entry.version) console.log(` version: ${entry.version}`);
269
+ if (entry.description) console.log(` description: ${entry.description}`);
270
+ if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
271
+ console.log(` source: ${S.dim(entry.source)}`);
272
+ if (entry.requires.length) {
273
+ console.log(` requires:`);
274
+ for (const d of entry.requires)
275
+ console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${d.name}`);
276
+ }
277
+ if (entry.dependencies.length) {
278
+ console.log(` dependencies:`);
279
+ for (const s of entry.dependencies) console.log(` ${S.dim("\xB7")} ${colorRef(s)}`);
280
+ }
281
+ console.log();
282
+ });
283
+ }
284
+ function makeCreateCommand() {
285
+ return new Command("create").description("Scaffold a new asset").argument("<name>", "Asset name").addOption(
286
+ new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...ASSET_KINDS])
287
+ ).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
288
+ const am2 = new AssetManager({ projectDir: process.cwd() });
289
+ const destDir = opts.dir ? path14__default.resolve(opts.dir) : process.cwd();
290
+ const result = am2.create(name, opts.kind, destDir);
291
+ if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
292
+ else {
293
+ logErr(result.path);
294
+ process.exit(1);
295
+ }
296
+ });
297
+ }
298
+ function makeDoctorCommand() {
299
+ return new Command("doctor").description("Scan for missing dependency chains").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action((name, opts) => {
300
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
301
+ const issues = am2.doctor();
302
+ if (issues.length === 0) {
303
+ logOk("No missing dependencies.");
304
+ return;
305
+ }
306
+ const assetW = Math.max(5, ...issues.map((i) => `${i.assetKind}:${i.assetName}`.length));
307
+ const depW = Math.max(11, ...issues.map((i) => `${i.depKind}:${i.depName}`.length));
308
+ console.log();
309
+ console.log(
310
+ ` ${S.dim("ASSET".padEnd(assetW))} ${S.dim("MISSING DEP".padEnd(depW))} ${S.dim("IN REPOS")}`
311
+ );
312
+ console.log(` ${S.rule(assetW + depW + 15)}`);
313
+ for (const i of issues) {
314
+ const asset = `${i.assetKind}:${i.assetName}`;
315
+ const dep = `${i.depKind}:${i.depName}`;
316
+ const status4 = i.inRepos ? S.warn("fixable") : S.err("not found");
317
+ console.log(` ${asset.padEnd(assetW)} ${dep.padEnd(depW)} ${status4}`);
318
+ }
319
+ console.log();
320
+ });
321
+ }
322
+ var DEFAULT_IMPORT_VERSION = "0.1.0";
323
+ var DEFAULT_IMPORT_STAGE = "alpha";
324
+ function claudeSkillRoots() {
325
+ const roots = [];
326
+ const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
327
+ if (override) roots.push(override);
328
+ roots.push(path14.join(os.homedir(), ".claude", "skills"));
329
+ return roots;
330
+ }
331
+ function resolveImportSource(nameOrPath) {
332
+ const asPath = path14.resolve(nameOrPath);
333
+ if (fs12.existsSync(asPath)) {
334
+ const dir = fs12.statSync(asPath).isDirectory() ? asPath : path14.dirname(asPath);
335
+ const skillFile = path14.join(dir, "SKILL.md");
336
+ if (fs12.existsSync(skillFile)) return { dir, skillFile, via: "path" };
337
+ }
338
+ if (!nameOrPath.includes(path14.sep) && !nameOrPath.startsWith(".")) {
339
+ for (const root of claudeSkillRoots()) {
340
+ const dir = path14.join(root, nameOrPath);
341
+ const skillFile = path14.join(dir, "SKILL.md");
342
+ if (fs12.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
343
+ }
344
+ }
345
+ return null;
346
+ }
347
+ function normalizeSkillContent(raw, opts = {}) {
348
+ const notes = [];
349
+ const { data, body } = parseFrontmatter(raw);
350
+ const rawName = typeof data.name === "string" && data.name.trim() ? data.name.trim() : void 0;
351
+ const sourceName = rawName ?? opts.fallbackName ?? "";
352
+ let name = sourceName;
353
+ let originalName;
354
+ if (!sourceName) {
355
+ throw new Error("skill has no `name` in frontmatter and no fallback was provided");
356
+ }
357
+ if (!isValidAssetName(sourceName)) {
358
+ name = slugifyAssetName(sourceName);
359
+ originalName = sourceName;
360
+ notes.push(`renamed "${sourceName}" \u2192 "${name}" (canonical kebab-case)`);
361
+ }
362
+ const existingMeta = data.metadata && typeof data.metadata === "object" && !Array.isArray(data.metadata) ? { ...data.metadata } : {};
363
+ if (existingMeta.version == null) {
364
+ existingMeta.version = opts.version ?? DEFAULT_IMPORT_VERSION;
365
+ notes.push(`stamped metadata.version: ${existingMeta.version}`);
366
+ }
367
+ if (existingMeta.stage == null) {
368
+ existingMeta.stage = opts.stage ?? DEFAULT_IMPORT_STAGE;
369
+ notes.push(`stamped metadata.stage: ${existingMeta.stage}`);
370
+ }
371
+ if (existingMeta.tags == null) {
372
+ const keywords = Array.isArray(data.keywords) ? data.keywords : [];
373
+ existingMeta.tags = keywords.filter((k) => typeof k === "string");
374
+ if (existingMeta.tags.length > 0) {
375
+ notes.push("promoted top-level keywords \u2192 metadata.tags");
376
+ }
377
+ }
378
+ const ordered = { name };
379
+ if (data.description != null) ordered.description = data.description;
380
+ ordered.metadata = existingMeta;
381
+ for (const [k, v] of Object.entries(data)) {
382
+ if (k === "name" || k === "description" || k === "metadata" || k === "keywords") continue;
383
+ ordered[k] = v;
384
+ }
385
+ const fm = stringify(ordered).trimEnd();
386
+ const content = `---
387
+ ${fm}
388
+ ---
389
+
390
+ ${body}
391
+ `;
392
+ const changed = notes.length > 0;
393
+ return { content, name, originalName, changed, notes };
394
+ }
395
+ var DOMAIN_TEMPLATE = (name, publisher, description) => {
396
+ const fm = stringify({ name, publisher, description }).trimEnd();
397
+ return `---
398
+ ${fm}
399
+ ---
400
+
401
+ # ${name}
402
+
403
+ ${description}
404
+ `;
405
+ };
406
+ function ensureDomain(libraryPath, domain, opts = {}) {
407
+ const dir = path14.join(libraryPath, domain);
408
+ const domainFile = path14.join(dir, "DOMAIN.md");
409
+ const publisher = opts.publisher ?? slugifyAssetName(domain);
410
+ if (fs12.existsSync(domainFile)) {
411
+ return { dir, publisher, created: false };
412
+ }
413
+ fs12.mkdirSync(dir, { recursive: true });
414
+ const description = opts.description ?? `The ${domain} domain.`;
415
+ fs12.writeFileSync(domainFile, DOMAIN_TEMPLATE(domain, publisher, description), "utf8");
416
+ return { dir, publisher, created: true };
417
+ }
418
+ function listDomains(libraryPath) {
419
+ if (!fs12.existsSync(libraryPath)) return [];
420
+ return fs12.readdirSync(libraryPath, { withFileTypes: true }).filter((e) => e.isDirectory() && fs12.existsSync(path14.join(libraryPath, e.name, "DOMAIN.md"))).map((e) => e.name).sort();
421
+ }
422
+ function upsertManifestAsset(libraryPath, input) {
423
+ const manifest = loadSkPublishManifest(libraryPath) ?? { assets: [] };
424
+ const assets = Array.isArray(manifest.assets) ? [...manifest.assets] : [];
425
+ const entry = { kind: input.kind, name: input.name, root: input.root };
426
+ if (input.version) entry.version = input.version;
427
+ if (input.publisher) entry.publisher = input.publisher;
428
+ if (input.description) entry.description = input.description;
429
+ if (input.keywords && input.keywords.length > 0) entry.keywords = input.keywords;
430
+ const idx = assets.findIndex((a) => a.kind === input.kind && a.name === input.name);
431
+ const added = idx < 0;
432
+ if (added) {
433
+ assets.push(entry);
434
+ } else {
435
+ assets[idx] = { ...assets[idx], ...entry };
436
+ }
437
+ const manifestPath = saveSkPublishManifest(libraryPath, { ...manifest, assets });
438
+ return { manifestPath, added };
439
+ }
440
+
441
+ // cli/src/commands/asset-cmd.ts
75
442
  function makeAssetCommand() {
76
443
  const cmd = new Command("asset").description("Author and install AI assets");
444
+ cmd.command("import <name-or-path>").description("Import + skailify an existing coding-agent skill into a library").option("--to <library>", "Target library (default: auto / personal)").option("--domain <name>", "Place under this domain's skills/ (created if missing)").option("--version <semver>", "Version to stamp when the skill ships none").option("--stage <stage>", "Lifecycle stage to stamp (default: alpha)").option("--no-normalize", "Copy verbatim \u2014 skip frontmatter normalization").option("--commit", "Auto-commit in git-backed libraries", false).action(
445
+ async (nameOrPath, opts) => {
446
+ const src = resolveImportSource(nameOrPath);
447
+ if (!src) {
448
+ logErr(
449
+ `No skill found for "${nameOrPath}". Pass a path to a SKILL.md dir, or a bare name present under ~/.claude/skills/.`
450
+ );
451
+ process.exit(1);
452
+ }
453
+ logInfo(`Source: ${S.dim(src.dir)} (${src.via})`);
454
+ const { manager, close } = await openLibraryManager();
455
+ try {
456
+ let target;
457
+ if (opts.to) {
458
+ target = await manager.requireLibrary(opts.to);
459
+ } else {
460
+ const all = await manager.listLibraries();
461
+ const def = all.find(
462
+ (l) => l.isDefault && (l.ownership === "owner" || l.ownership === "contributor")
463
+ );
464
+ target = def ?? (await manager.ensurePersonalLibrary(resolveLibraryDir())).library;
465
+ }
466
+ if (target.ownership === "reader") {
467
+ logErr(`Library "${target.name}" is read-only (ownership=reader). Choose --to.`);
468
+ process.exit(1);
469
+ }
470
+ const rawSkill = fs12.readFileSync(src.skillFile, "utf8");
471
+ const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
472
+ fallbackName: path14.basename(src.dir),
473
+ version: opts.version,
474
+ stage: opts.stage
475
+ }) : { content: rawSkill, name: path14.basename(src.dir), changed: false, notes: [] };
476
+ if (!opts.normalize && !isValidAssetName(norm.name)) {
477
+ logWarn(
478
+ `Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
479
+ );
480
+ }
481
+ let destParent = target.path;
482
+ let publisher;
483
+ if (opts.domain) {
484
+ const dom = ensureDomain(target.path, opts.domain);
485
+ if (dom.created) logOk(`Scaffolded domain ${S.cmd(opts.domain)} \u2192 ${dom.dir}`);
486
+ destParent = path14.join(dom.dir, "skills");
487
+ publisher = dom.publisher;
488
+ }
489
+ fs12.mkdirSync(destParent, { recursive: true });
490
+ const destDir = path14.join(destParent, norm.name);
491
+ if (fs12.existsSync(destDir)) {
492
+ logErr(`Destination already exists: ${destDir}`);
493
+ process.exit(1);
494
+ }
495
+ fs12.cpSync(src.dir, destDir, { recursive: true });
496
+ fs12.writeFileSync(path14.join(destDir, "SKILL.md"), norm.content, "utf8");
497
+ for (const note of norm.notes) logInfo(` \u2022 ${note}`);
498
+ const descRaw = parseFrontmatter(norm.content).data.description;
499
+ const description = typeof descRaw === "string" ? descRaw.trim() : void 0;
500
+ const root = path14.relative(target.path, destDir);
501
+ const up = upsertManifestAsset(target.path, {
502
+ kind: "skill",
503
+ name: norm.name,
504
+ root,
505
+ version: opts.version,
506
+ publisher,
507
+ description
508
+ });
509
+ logOk(`${up.added ? "Added" : "Updated"} manifest entry skill:${norm.name}`);
510
+ if (target.backend === "git" && opts.commit) {
511
+ const { spawnSync: spawnSync2 } = await import('child_process');
512
+ spawnSync2("git", ["add", "--", destDir], { cwd: target.path, stdio: "inherit" });
513
+ const r = spawnSync2("git", ["commit", "-m", `skaile: import ${norm.name}`], {
514
+ cwd: target.path,
515
+ stdio: "inherit"
516
+ });
517
+ if (r.status !== 0) {
518
+ logWarn("Nothing committed (working tree clean or commit aborted).");
519
+ }
520
+ }
521
+ logOk(`Imported ${S.cmd(norm.name)} \u2192 ${target.name}`);
522
+ logInfo(`Verify: ${S.cmd(`skaile validate ${target.path}`)}`);
523
+ } finally {
524
+ close();
525
+ }
526
+ }
527
+ );
77
528
  cmd.command("migrate <path>").description("Move/copy/link a workspace asset into a library").option("--to <library>", "Target library (default: auto)").option("--domain <name>", "Place inside this domain (domain-structured libs)").option("--mode <mode>", "copy | move | link", "copy").option("--commit", "Auto-commit in git-backed libraries", false).action(
78
529
  async (srcPath, opts) => {
79
530
  if (!["copy", "move", "link"].includes(opts.mode)) {
80
531
  logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
81
532
  process.exit(1);
82
533
  }
83
- if (!fs11.existsSync(srcPath)) {
534
+ if (!fs12.existsSync(srcPath)) {
84
535
  logErr(`Source path does not exist: ${srcPath}`);
85
536
  process.exit(1);
86
537
  }
@@ -107,32 +558,35 @@ function makeAssetCommand() {
107
558
  );
108
559
  process.exit(1);
109
560
  }
110
- const basename2 = path13.basename(srcPath);
111
- const destDir = target.structure === "domain" && opts.domain ? path13.join(target.path, opts.domain) : target.path;
112
- fs11.mkdirSync(destDir, { recursive: true });
113
- const destPath = path13.join(destDir, basename2);
114
- if (fs11.existsSync(destPath)) {
561
+ const basename2 = path14.basename(srcPath);
562
+ const destDir = target.structure === "domain" && opts.domain ? path14.join(target.path, opts.domain) : target.path;
563
+ fs12.mkdirSync(destDir, { recursive: true });
564
+ const destPath = path14.join(destDir, basename2);
565
+ if (fs12.existsSync(destPath)) {
115
566
  logErr(`Destination already exists: ${destPath}`);
116
567
  process.exit(1);
117
568
  }
118
569
  switch (opts.mode) {
119
570
  case "copy":
120
- fs11.cpSync(srcPath, destPath, { recursive: true });
571
+ fs12.cpSync(srcPath, destPath, { recursive: true });
121
572
  break;
122
573
  case "move":
123
- fs11.renameSync(srcPath, destPath);
574
+ fs12.renameSync(srcPath, destPath);
124
575
  break;
125
576
  case "link":
126
- fs11.symlinkSync(path13.resolve(srcPath), destPath);
577
+ fs12.symlinkSync(path14.resolve(srcPath), destPath);
127
578
  break;
128
579
  }
129
580
  if (target.backend === "git" && opts.commit) {
130
581
  const { spawnSync: spawnSync2 } = await import('child_process');
131
- spawnSync2("git", ["add", "-A"], { cwd: target.path, stdio: "ignore" });
132
- spawnSync2("git", ["commit", "-m", `skaile: migrate ${basename2}`], {
582
+ spawnSync2("git", ["add", "--", destPath], { cwd: target.path, stdio: "inherit" });
583
+ const r = spawnSync2("git", ["commit", "-m", `skaile: migrate ${basename2}`], {
133
584
  cwd: target.path,
134
- stdio: "ignore"
585
+ stdio: "inherit"
135
586
  });
587
+ if (r.status !== 0) {
588
+ logWarn("Nothing committed (working tree clean or commit aborted).");
589
+ }
136
590
  }
137
591
  logOk(`Migrated ${basename2} \u2192 ${target.name} (${opts.mode})`);
138
592
  if (opts.mode === "move") {
@@ -157,7 +611,7 @@ function makeAssetCommand() {
157
611
  try {
158
612
  const def = await library.getAssetDef(ref);
159
613
  if (!def) {
160
- logErr(`No asset found for ref "${ref}". Try \`skaile asset list\`.`);
614
+ logErr(`No asset found for ref "${ref}". Try \`skaile search\`.`);
161
615
  process.exit(1);
162
616
  }
163
617
  const target = opts.target ?? process.cwd();
@@ -171,17 +625,17 @@ function makeAssetCommand() {
171
625
  }
172
626
  const manifestPath = def.manifest.path;
173
627
  const candidateSubpath = typeof manifestPath === "string" && manifestPath.length > 0 ? manifestPath : def.name;
174
- const srcPath = path13.join(lib.path, candidateSubpath);
175
- if (!fs11.existsSync(srcPath)) {
628
+ const srcPath = path14.join(lib.path, candidateSubpath);
629
+ if (!fs12.existsSync(srcPath)) {
176
630
  logErr(`Asset path not found: ${srcPath}`);
177
631
  process.exit(1);
178
632
  }
179
- const destPath = path13.join(target, candidateSubpath);
180
- fs11.mkdirSync(path13.dirname(destPath), { recursive: true });
633
+ const destPath = path14.join(target, candidateSubpath);
634
+ fs12.mkdirSync(path14.dirname(destPath), { recursive: true });
181
635
  if (opts.mode === "copy") {
182
- fs11.cpSync(srcPath, destPath, { recursive: true });
636
+ fs12.cpSync(srcPath, destPath, { recursive: true });
183
637
  } else {
184
- fs11.symlinkSync(path13.resolve(srcPath), destPath);
638
+ fs12.symlinkSync(path14.resolve(srcPath), destPath);
185
639
  }
186
640
  logOk(`Installed ${ref} \u2192 ${destPath} (${opts.mode})`);
187
641
  } finally {
@@ -189,29 +643,7 @@ function makeAssetCommand() {
189
643
  }
190
644
  }
191
645
  );
192
- cmd.command("list").description("List asset definitions across libraries").option("--library <name>", "Filter by library").option("--domain <name>", "Filter by domain").option("--kind <kind>", "Filter by kind").option("--json", "Output as JSON").action(async (opts) => {
193
- const { manager, library, close } = await openLibraryManager();
194
- try {
195
- let defs = await library.listAssetDefs(opts.kind ? { kind: opts.kind } : void 0);
196
- if (opts.library) {
197
- const lib = await manager.requireLibrary(opts.library);
198
- defs = defs.filter((d) => d.libraryId === lib.id);
199
- }
200
- if (opts.json) return console.log(JSON.stringify(defs, null, 2));
201
- if (defs.length === 0) {
202
- logInfo("No assets cached. Run `skaile library sync <name>` first.");
203
- return;
204
- }
205
- for (const d of defs) {
206
- console.log(` ${S.cmd(d.id.padEnd(40))} ${d.kind.padEnd(10)} ${d.description ?? ""}`);
207
- }
208
- console.log(`
209
- ${S.dim(`${defs.length} asset(s)`)}
210
- `);
211
- } finally {
212
- close();
213
- }
214
- });
646
+ cmd.addCommand(makeListCommand());
215
647
  cmd.command("show <ref>").description("Show details for an asset by canonical ref").action(async (ref) => {
216
648
  const { library, close } = await openLibraryManager();
217
649
  try {
@@ -268,14 +700,14 @@ function makeAuthCommand() {
268
700
  }
269
701
  function collectCacheTargets(scope) {
270
702
  const out = [];
271
- out.push(path13__default.join(scope.projectDir, ".skaile", "cache"));
272
- out.push(path13__default.join(scope.projectDir, ".skaile", "store-cache"));
273
- out.push(path13__default.join(scope.projectDir, ".skaile", "repos"));
703
+ out.push(path14__default.join(scope.projectDir, ".skaile", "cache"));
704
+ out.push(path14__default.join(scope.projectDir, ".skaile", "store-cache"));
705
+ out.push(path14__default.join(scope.projectDir, ".skaile", "repos"));
274
706
  if (scope.global) {
275
707
  out.push(globalCacheRoot());
276
- const home = process.env.SKAILE_HOME ?? path13__default.join(homedir(), ".skaile");
277
- out.push(path13__default.join(home, "repos"));
278
- out.push(path13__default.join(home, "catalog-cache"));
708
+ const home = process.env.SKAILE_HOME ?? path14__default.join(homedir(), ".skaile");
709
+ out.push(path14__default.join(home, "repos"));
710
+ out.push(path14__default.join(home, "catalog-cache"));
279
711
  }
280
712
  return out;
281
713
  }
@@ -289,7 +721,7 @@ function dirSize(target) {
289
721
  function dirSizeOfDir(dir) {
290
722
  let total = 0;
291
723
  for (const ent of readdirSync(dir, { withFileTypes: true })) {
292
- const child = path13__default.join(dir, ent.name);
724
+ const child = path14__default.join(dir, ent.name);
293
725
  if (ent.isSymbolicLink()) continue;
294
726
  if (ent.isDirectory()) total += dirSizeOfDir(child);
295
727
  else if (ent.isFile()) total += statSync(child).size;
@@ -315,7 +747,7 @@ function makeCacheCommand() {
315
747
  const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
316
748
  cmd.command("clean").description("Remove the project cache (.skaile/cache); --global also clears ~/.skaile/cache").option("--global", "Also clear the global cache (sources + catalog) and legacy dirs").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()).action(async (opts) => {
317
749
  const targets = collectCacheTargets({
318
- projectDir: path13__default.resolve(opts.projectDir),
750
+ projectDir: path14__default.resolve(opts.projectDir),
319
751
  global: opts.global
320
752
  }).filter((t) => existsSync(t));
321
753
  if (targets.length === 0) {
@@ -345,12 +777,12 @@ function makeCacheCommand() {
345
777
  for (const r of removed) logOk(`Removed ${r}`);
346
778
  });
347
779
  cmd.command("dir").description("Print the resolved cache roots").option("--global", "Include the global cache root").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
348
- console.log(path13__default.join(path13__default.resolve(opts.projectDir), ".skaile", "cache"));
780
+ console.log(path14__default.join(path14__default.resolve(opts.projectDir), ".skaile", "cache"));
349
781
  if (opts.global) console.log(globalCacheRoot());
350
782
  });
351
783
  cmd.command("size").description("Show cache disk usage per directory").option("--global", "Include the global cache").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
352
784
  const targets = collectCacheTargets({
353
- projectDir: path13__default.resolve(opts.projectDir),
785
+ projectDir: path14__default.resolve(opts.projectDir),
354
786
  global: opts.global
355
787
  });
356
788
  console.log();
@@ -362,229 +794,11 @@ function makeCacheCommand() {
362
794
  });
363
795
  return cmd;
364
796
  }
365
- async function runSearch(kind, query, opts) {
366
- if (kind?.includes(":")) {
367
- query = kind;
368
- kind = void 0;
369
- }
370
- const showLocal = !opts.store;
371
- const showStore = !opts.local;
372
- if (showLocal) {
373
- searchLocal(query, kind, opts, showStore);
374
- }
375
- if (showStore) {
376
- await searchStore(query, kind, opts);
377
- }
378
- }
379
- function searchLocal(query, kind, opts, showStore) {
380
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
381
- const entries = am2.search(query, kind);
382
- if (entries.length === 0) {
383
- if (!showStore) {
384
- logInfo(
385
- query ? `No entries matching "${query}".` : "No assets found. Run `skaile source sync` first."
386
- );
387
- }
388
- return;
389
- }
390
- if (showStore) {
391
- console.log(`
392
- ${S.heading("Local:")}`);
393
- }
394
- printLocalEntries(entries);
395
- }
396
- function printLocalEntries(entries) {
397
- const byKind = /* @__PURE__ */ new Map();
398
- for (const e of entries) {
399
- if (!byKind.has(e.kind)) byKind.set(e.kind, []);
400
- byKind.get(e.kind).push(e);
401
- }
402
- for (const [k, items] of byKind) {
403
- const nameW = Math.max(4, ...items.map((e) => e.name.length));
404
- console.log();
405
- console.log(
406
- ` ${kindColor(k)} ${S.heading(`${k.toUpperCase()}S`)} ${S.dim(`(${items.length})`)}`
407
- );
408
- console.log(` ${S.rule(nameW + 62)}`);
409
- for (const e of items) {
410
- const ver = e.version ? S.dim(` v${e.version}`) : "";
411
- console.log(` ${S.cmd(e.name.padEnd(nameW))} ${e.description.slice(0, 60)}${ver}`);
412
- }
413
- }
414
- console.log(`
415
- ${S.dim(`${entries.length} total`)}
416
- `);
417
- }
418
- async function searchStore(query, kind, opts) {
419
- try {
420
- const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-XFZFKY3W.js');
421
- const config = getStoreConfig2();
422
- const params = {};
423
- if (query) params.q = query;
424
- if (kind) params.kind = kind;
425
- const storeRes = await storeFetch2(config, "/api/assets", { params });
426
- if (storeRes.results.length > 0) {
427
- console.log(`
428
- ${S.heading("Store:")}`);
429
- for (const asset of storeRes.results) {
430
- const ref = `${asset.kind}:@${asset.publisher}/${asset.slug}`;
431
- console.log(
432
- ` \u2B21 ${kindColorPad(asset.kind)} ${colorRef(ref).padEnd(40)} ${S.dim(asset.description?.slice(0, 50) || "")} ${S.dim(`\u2193${asset.downloads}`)}`
433
- );
434
- }
435
- } else if (opts.store) {
436
- logInfo("No results in store");
437
- }
438
- } catch (e) {
439
- if (opts.store) {
440
- logErr(`Store search failed: ${e.message}`);
441
- }
442
- }
443
- }
444
- function makeSearchCommand() {
445
- return new Command("search").description("Search across all repos").argument("[kind]", "Filter by asset kind").argument("[query]", "Search query").option("--project-dir <path>", "Project directory", process.cwd()).option("--store", "Search only the store").option("--local", "Search only local repos").action(async (kind, query, opts) => {
446
- await runSearch(kind, query, opts);
447
- });
448
- }
449
- function makeAddCommand() {
450
- return new Command("add").description("Add to skaile.yaml + deploy").argument("<ref>", "Asset reference (kind:name[@repo])").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Deploy to global dir (~/.claude)").option("--target <agent>", "Driver target", "claude-code").action(async (ref, opts) => {
451
- const am2 = new AssetManager({
452
- projectDir: path13__default.resolve(opts.projectDir),
453
- global: opts.global,
454
- driverTarget: opts.target
455
- });
456
- const spinner5 = p6.spinner();
457
- spinner5.start(`Adding ${ref}`);
458
- try {
459
- const added = await am2.add(ref);
460
- spinner5.stop("Done");
461
- if (added.length === 0) {
462
- const kind = parseAssetRef(ref).kind;
463
- if (NON_DEPLOYABLE_KINDS.has(kind))
464
- logInfo(
465
- `Recorded in skaile.yaml. ${kind} assets are not deployed into the driver target \u2014 they are wired when skaile runs the agent.`
466
- );
467
- else logInfo("Nothing to deploy (already up to date).");
468
- } else for (const a of added) logOk(a);
469
- } catch (err) {
470
- spinner5.stop("Failed");
471
- logErr(String(err));
472
- process.exit(1);
473
- }
474
- });
475
- }
476
- function makeRemoveCommand() {
477
- return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from global dir").option("--target <agent>", "Driver target", "claude-code").action((ref, opts) => {
478
- const am2 = new AssetManager({
479
- projectDir: path13__default.resolve(opts.projectDir),
480
- global: opts.global,
481
- driverTarget: opts.target
482
- });
483
- const ok = am2.remove(ref);
484
- if (ok) logOk(`Removed ${ref}`);
485
- else logErr(`Not deployed: ${ref}`);
486
- });
487
- }
488
- function makeListCommand() {
489
- return new Command("list").description("List deployed assets").argument("[kind]", "Filter by asset kind").option("--project-dir <path>", "Project directory", process.cwd()).option("-g, --global", "List global deployment").addOption(
490
- new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
491
- ).action((kind, opts) => {
492
- const am2 = new AssetManager({
493
- projectDir: path13__default.resolve(opts.projectDir),
494
- global: opts.global,
495
- driverTarget: opts.target
496
- });
497
- const deployed = am2.listDeployed(kind);
498
- if (deployed.length === 0) {
499
- logInfo("Nothing deployed.");
500
- return;
501
- }
502
- const kindW = Math.max(5, ...deployed.map((e) => e.kind.length));
503
- const nameW = Math.max(4, ...deployed.map((e) => e.name.length));
504
- console.log();
505
- console.log(` ${S.dim("KIND".padEnd(kindW))} ${S.dim("NAME".padEnd(nameW))}`);
506
- console.log(` ${S.rule(kindW + nameW + 4)}`);
507
- for (const e of deployed) {
508
- console.log(` ${kindColorPad(e.kind, kindW)} ${e.name.padEnd(nameW)}`);
509
- }
510
- console.log(`
511
- ${S.dim(`${deployed.length} deployed`)}
512
- `);
513
- });
514
- }
515
- function makeInfoCommand() {
516
- return new Command("info").description("Show asset metadata, deps, deploy status").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
517
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
518
- const entry = am2.info(ref);
519
- if (!entry) {
520
- logErr(
521
- `'${ref}' not found. Run ${S.cmd("skaile source sync")} then ${S.cmd("skaile search")}.`
522
- );
523
- process.exit(1);
524
- }
525
- console.log();
526
- console.log(` ${S.heading(entry.name)}`);
527
- console.log(` ${S.rule(40)}`);
528
- console.log(` kind: ${kindColor(entry.kind)}`);
529
- if (entry.version) console.log(` version: ${entry.version}`);
530
- if (entry.description) console.log(` description: ${entry.description}`);
531
- if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
532
- console.log(` source: ${S.dim(entry.source)}`);
533
- if (entry.requires.length) {
534
- console.log(` requires:`);
535
- for (const d of entry.requires)
536
- console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${d.name}`);
537
- }
538
- if (entry.dependencies.length) {
539
- console.log(` dependencies:`);
540
- for (const s of entry.dependencies) console.log(` ${S.dim("\xB7")} ${colorRef(s)}`);
541
- }
542
- console.log();
543
- });
544
- }
545
- function makeCreateCommand() {
546
- return new Command("create").description("Scaffold a new asset").argument("<name>", "Asset name").addOption(
547
- new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...ASSET_KINDS])
548
- ).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
549
- const am2 = new AssetManager({ projectDir: process.cwd() });
550
- const destDir = opts.dir ? path13__default.resolve(opts.dir) : process.cwd();
551
- const result = am2.create(name, opts.kind, destDir);
552
- if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
553
- else {
554
- logErr(result.path);
555
- process.exit(1);
556
- }
557
- });
558
- }
559
- function makeDoctorCommand() {
560
- return new Command("doctor").description("Scan for missing dependency chains").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action((name, opts) => {
561
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
562
- const issues = am2.doctor();
563
- if (issues.length === 0) {
564
- logOk("No missing dependencies.");
565
- return;
566
- }
567
- const assetW = Math.max(5, ...issues.map((i) => `${i.assetKind}:${i.assetName}`.length));
568
- const depW = Math.max(11, ...issues.map((i) => `${i.depKind}:${i.depName}`.length));
569
- console.log();
570
- console.log(
571
- ` ${S.dim("ASSET".padEnd(assetW))} ${S.dim("MISSING DEP".padEnd(depW))} ${S.dim("IN REPOS")}`
572
- );
573
- console.log(` ${S.rule(assetW + depW + 15)}`);
574
- for (const i of issues) {
575
- const asset = `${i.assetKind}:${i.assetName}`;
576
- const dep = `${i.depKind}:${i.depName}`;
577
- const status4 = i.inRepos ? S.warn("fixable") : S.err("not found");
578
- console.log(` ${asset.padEnd(assetW)} ${dep.padEnd(depW)} ${status4}`);
579
- }
580
- console.log();
581
- });
582
- }
583
797
  function makeCatalogCommand() {
584
798
  const catalog = new Command("catalog").description("Catalog source health and configuration");
585
799
  catalog.command("test").description("Probe the configured catalog source and report status").option("--project-dir <path>", "Project directory (for project-level config overlay)").option("--url <url>", "Override the catalog URL for this probe").option("--force", "Probe the network even in air-gapped mode (cache_ttl: 0)").action(async (opts) => {
586
800
  const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
587
- const projectDir = opts.projectDir ? path13__default.resolve(opts.projectDir) : void 0;
801
+ const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : void 0;
588
802
  const cfg = resolveConfig({ projectDir });
589
803
  const baseUrl = opts.url ?? cfg.catalog.url;
590
804
  if (isLocalCatalogUrl(baseUrl)) {
@@ -602,7 +816,7 @@ function makeCatalogCommand() {
602
816
  });
603
817
  catalog.command("info").description("Print the resolved catalog configuration (url, framing, cacheTtlMs)").option("--project-dir <path>", "Project directory (for project-level config overlay)").action(async (opts) => {
604
818
  const { resolveConfig } = await import('../library/index.js');
605
- const projectDir = opts.projectDir ? path13__default.resolve(opts.projectDir) : void 0;
819
+ const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : void 0;
606
820
  const cfg = resolveConfig({ projectDir });
607
821
  console.log(`url: ${cfg.catalog.url}`);
608
822
  console.log(`framing: ${cfg.catalog.framing}`);
@@ -744,8 +958,8 @@ function findFlowFile(flowId, priorityRoots = []) {
744
958
  for (const root of [...priorityRoots, ...aiResourceRoots()]) {
745
959
  for (const { dir } of assetSearchDirs(root, "flows")) {
746
960
  for (const ext of [".flow.yaml", ".flow.json", ".json"]) {
747
- const candidate = path13__default.join(dir, `${flowId}${ext}`);
748
- if (fs11__default.existsSync(candidate)) return candidate;
961
+ const candidate = path14__default.join(dir, `${flowId}${ext}`);
962
+ if (fs12__default.existsSync(candidate)) return candidate;
749
963
  }
750
964
  }
751
965
  }
@@ -755,7 +969,7 @@ function findSkills(domain) {
755
969
  const found = [];
756
970
  for (const root of aiResourceRoots()) {
757
971
  for (const { dir, domain: dirDomain } of assetSearchDirs(root, "skills")) {
758
- if (fs11__default.existsSync(dir)) walkSkills(dir, dirDomain, found);
972
+ if (fs12__default.existsSync(dir)) walkSkills(dir, dirDomain, found);
759
973
  }
760
974
  }
761
975
  const seen = /* @__PURE__ */ new Set();
@@ -768,11 +982,11 @@ function findSkills(domain) {
768
982
  return deduped;
769
983
  }
770
984
  function walkSkills(dir, domain, out) {
771
- for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
772
- const full = path13__default.join(dir, entry.name);
985
+ for (const entry of fs12__default.readdirSync(dir, { withFileTypes: true })) {
986
+ const full = path14__default.join(dir, entry.name);
773
987
  if (entry.isDirectory()) {
774
- const skillMd = path13__default.join(full, "SKILL.md");
775
- if (fs11__default.existsSync(skillMd)) {
988
+ const skillMd = path14__default.join(full, "SKILL.md");
989
+ if (fs12__default.existsSync(skillMd)) {
776
990
  out.push({ name: entry.name, path: full, skillPath: skillMd, domain });
777
991
  } else {
778
992
  walkSkills(full, domain, out);
@@ -800,10 +1014,10 @@ function resolveFlowIds() {
800
1014
  }
801
1015
  }
802
1016
  function resolveSessionIds(projectDir) {
803
- const sessionsDir = path13__default.join(projectDir, ".skaile", "sessions");
804
- if (!fs11__default.existsSync(sessionsDir)) return [];
1017
+ const sessionsDir = path14__default.join(projectDir, ".skaile", "sessions");
1018
+ if (!fs12__default.existsSync(sessionsDir)) return [];
805
1019
  try {
806
- return fs11__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
1020
+ return fs12__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
807
1021
  } catch {
808
1022
  return [];
809
1023
  }
@@ -919,7 +1133,7 @@ function printResolvedPathsSection(config) {
919
1133
  console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
920
1134
  }
921
1135
  async function showConfig(opts) {
922
- const projectDir = opts.projectDir ? path13__default.resolve(opts.projectDir) : process.cwd();
1136
+ const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
923
1137
  const config = await resolveSettings(projectDir);
924
1138
  const wsDefaults = collectWorkspaceDefaults(projectDir);
925
1139
  printEffectiveSection(config);
@@ -932,13 +1146,13 @@ function makeConfigCommand() {
932
1146
  const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
933
1147
  cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
934
1148
  cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
935
- const projectDir = opts.projectDir ? path13__default.resolve(opts.projectDir) : process.cwd();
1149
+ const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
936
1150
  const config = await resolveSettings(projectDir);
937
1151
  const value = config[key];
938
1152
  console.log(value ?? S.dim("(not set)"));
939
1153
  });
940
1154
  cmd.command("set <key> <value>").description("Set a personal config value (driver, model, provider, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
941
- const projectDir = opts.projectDir ? path13__default.resolve(opts.projectDir) : process.cwd();
1155
+ const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
942
1156
  const isApiKey = key.startsWith(API_KEY_PREFIX);
943
1157
  if (!PERSONAL_KEYS.has(key) && !isApiKey) {
944
1158
  logErr(
@@ -1053,11 +1267,11 @@ function makeConnectCommand() {
1053
1267
  process.exitCode = 1;
1054
1268
  return;
1055
1269
  }
1056
- await new Promise((resolve4) => {
1270
+ await new Promise((resolve5) => {
1057
1271
  client.onMessage((event) => {
1058
1272
  console.log(formatEvent(event));
1059
1273
  if (event.type === "finished" || event.type === "debug_result") {
1060
- resolve4();
1274
+ resolve5();
1061
1275
  }
1062
1276
  });
1063
1277
  client.send(parsed);
@@ -1101,12 +1315,12 @@ function makeConnectCommand() {
1101
1315
  client.send(cmd);
1102
1316
  rl.prompt();
1103
1317
  });
1104
- await new Promise((resolve4) => {
1105
- rl.on("close", resolve4);
1318
+ await new Promise((resolve5) => {
1319
+ rl.on("close", resolve5);
1106
1320
  client.onDisconnect(() => {
1107
1321
  logErr("Server disconnected");
1108
1322
  rl.close();
1109
- resolve4();
1323
+ resolve5();
1110
1324
  });
1111
1325
  });
1112
1326
  await client.disconnect();
@@ -1188,15 +1402,15 @@ function parseOpArgs(args) {
1188
1402
  async function promptText(label, defaultVal) {
1189
1403
  const rl = createInterface({ input: process.stdin, output: process.stdout });
1190
1404
  const hint = defaultVal ? ` [${defaultVal}]` : "";
1191
- return new Promise((resolve4) => {
1405
+ return new Promise((resolve5) => {
1192
1406
  rl.question(` ${label}${hint}: `, (answer) => {
1193
1407
  rl.close();
1194
- resolve4(answer.trim() || defaultVal || "");
1408
+ resolve5(answer.trim() || defaultVal || "");
1195
1409
  });
1196
1410
  });
1197
1411
  }
1198
1412
  async function promptSecret(label) {
1199
- return new Promise((resolve4) => {
1413
+ return new Promise((resolve5) => {
1200
1414
  process.stdout.write(` ${label} (hidden): `);
1201
1415
  const stdin = process.stdin;
1202
1416
  stdin.setRawMode?.(true);
@@ -1209,7 +1423,7 @@ async function promptSecret(label) {
1209
1423
  stdin.pause();
1210
1424
  stdin.removeListener("data", onData);
1211
1425
  process.stdout.write("\n");
1212
- resolve4(value);
1426
+ resolve5(value);
1213
1427
  } else if (char === "") {
1214
1428
  process.exit(1);
1215
1429
  } else if (char === "\x7F") {
@@ -1256,8 +1470,8 @@ function makeConnectorCommand() {
1256
1470
  async (driver, opts) => {
1257
1471
  const { installNpmPackages } = await import('../connectors/index.js');
1258
1472
  const { scanDirectory, factoryAssetRoots, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
1259
- const projectDir = path13__default.resolve(opts.projectDir);
1260
- const yamlPath = path13__default.join(projectDir, "skaile.yaml");
1473
+ const projectDir = path14__default.resolve(opts.projectDir);
1474
+ const yamlPath = path14__default.join(projectDir, "skaile.yaml");
1261
1475
  if (!existsSync(yamlPath)) {
1262
1476
  logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
1263
1477
  process.exit(1);
@@ -1317,8 +1531,8 @@ ${installResult.output}`);
1317
1531
  );
1318
1532
  cmd.command("remove <id>").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Remove a connector from skaile.yaml by its instance ID").action(async (id, opts) => {
1319
1533
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
1320
- const projectDir = path13__default.resolve(opts.projectDir);
1321
- const yamlPath = path13__default.join(projectDir, "skaile.yaml");
1534
+ const projectDir = path14__default.resolve(opts.projectDir);
1535
+ const yamlPath = path14__default.join(projectDir, "skaile.yaml");
1322
1536
  if (!existsSync(yamlPath)) {
1323
1537
  logErr("No skaile.yaml found in current directory.");
1324
1538
  process.exit(1);
@@ -1335,7 +1549,7 @@ ${installResult.output}`);
1335
1549
  cmd.command("status [id]").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Connect and report health status for one or all connectors").action(async (id, opts) => {
1336
1550
  const res = await import('../connectors/index.js');
1337
1551
  res.registerBuiltinConnectors();
1338
- const projectDir = path13__default.resolve(opts.projectDir);
1552
+ const projectDir = path14__default.resolve(opts.projectDir);
1339
1553
  const declarations = res.loadConnectorDeclarations(projectDir);
1340
1554
  if (declarations.length === 0) {
1341
1555
  console.log("No connectors configured in skaile.yaml.");
@@ -1359,7 +1573,7 @@ ${installResult.output}`);
1359
1573
  await manager.disconnectAll();
1360
1574
  });
1361
1575
  cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
1362
- const projectDir = path13__default.resolve(opts.projectDir);
1576
+ const projectDir = path14__default.resolve(opts.projectDir);
1363
1577
  const manager = await connectConnectors(projectDir);
1364
1578
  try {
1365
1579
  console.log(JSON.stringify(manager.listConnectors(), null, 2));
@@ -1368,7 +1582,7 @@ ${installResult.output}`);
1368
1582
  }
1369
1583
  });
1370
1584
  cmd.command("sync [id]").description("Re-sync a filesystem-face connector or all of them (git pull, S3 refresh, etc.)").option("--all", "Sync all connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
1371
- const projectDir = path13__default.resolve(opts.projectDir);
1585
+ const projectDir = path14__default.resolve(opts.projectDir);
1372
1586
  const manager = await connectConnectors(projectDir);
1373
1587
  try {
1374
1588
  if (opts.all) {
@@ -1392,7 +1606,7 @@ ${installResult.output}`);
1392
1606
  }
1393
1607
  });
1394
1608
  cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
1395
- const projectDir = path13__default.resolve(opts.projectDir);
1609
+ const projectDir = path14__default.resolve(opts.projectDir);
1396
1610
  const manager = await connectConnectors(projectDir);
1397
1611
  try {
1398
1612
  if (!manager.has(id)) {
@@ -1407,7 +1621,7 @@ ${installResult.output}`);
1407
1621
  }
1408
1622
  });
1409
1623
  cmd.command("read <id> <resource-path>").description("Read content from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
1410
- const projectDir = path13__default.resolve(opts.projectDir);
1624
+ const projectDir = path14__default.resolve(opts.projectDir);
1411
1625
  const manager = await connectConnectors(projectDir);
1412
1626
  try {
1413
1627
  const content = await manager.read(id, resourcePath);
@@ -1417,7 +1631,7 @@ ${installResult.output}`);
1417
1631
  }
1418
1632
  });
1419
1633
  cmd.command("write <id> <resource-path> <content>").description("Write content to a connector at a path").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, content, opts) => {
1420
- const projectDir = path13__default.resolve(opts.projectDir);
1634
+ const projectDir = path14__default.resolve(opts.projectDir);
1421
1635
  const manager = await connectConnectors(projectDir);
1422
1636
  try {
1423
1637
  await manager.write(id, resourcePath, { data: content });
@@ -1427,7 +1641,7 @@ ${installResult.output}`);
1427
1641
  }
1428
1642
  });
1429
1643
  cmd.command("entries <id> [resource-path]").description("List entries in a connector (files, keys, rows, etc)").option("--project-dir <path>", "Workspace directory", process.cwd()).option("--recursive", "Include nested entries").option("--limit <n>", "Maximum entries to return", parsePositiveIntOption).action(async (id, resourcePath, opts) => {
1430
- const projectDir = path13__default.resolve(opts.projectDir);
1644
+ const projectDir = path14__default.resolve(opts.projectDir);
1431
1645
  const manager = await connectConnectors(projectDir);
1432
1646
  try {
1433
1647
  const entries = await manager.list(id, resourcePath, {
@@ -1440,7 +1654,7 @@ ${installResult.output}`);
1440
1654
  }
1441
1655
  });
1442
1656
  cmd.command("search <id> <query>").description("Search within a connector for matching content").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, query, opts) => {
1443
- const projectDir = path13__default.resolve(opts.projectDir);
1657
+ const projectDir = path14__default.resolve(opts.projectDir);
1444
1658
  const manager = await connectConnectors(projectDir);
1445
1659
  try {
1446
1660
  const results = await manager.search(id, query);
@@ -1450,7 +1664,7 @@ ${installResult.output}`);
1450
1664
  }
1451
1665
  });
1452
1666
  cmd.command("delete <id> <resource-path>").description("Delete an entry from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
1453
- const projectDir = path13__default.resolve(opts.projectDir);
1667
+ const projectDir = path14__default.resolve(opts.projectDir);
1454
1668
  const manager = await connectConnectors(projectDir);
1455
1669
  try {
1456
1670
  const ok = await manager.delete(id, resourcePath);
@@ -1460,7 +1674,7 @@ ${installResult.output}`);
1460
1674
  }
1461
1675
  });
1462
1676
  cmd.command("run <id> <op> [args...]").description("Run a custom adapter operation (e.g. git log, sqlite query)").option("--project-dir <path>", "Workspace directory", process.cwd()).allowUnknownOption().action(async (id, op, args, opts) => {
1463
- const projectDir = path13__default.resolve(opts.projectDir);
1677
+ const projectDir = path14__default.resolve(opts.projectDir);
1464
1678
  const manager = await connectConnectors(projectDir);
1465
1679
  try {
1466
1680
  if (!manager.has(id)) {
@@ -1495,17 +1709,17 @@ async function runDebugQuery(query, parentOpts, args) {
1495
1709
  process.exitCode = 1;
1496
1710
  return;
1497
1711
  }
1498
- await new Promise((resolve4) => {
1712
+ await new Promise((resolve5) => {
1499
1713
  const timeout = setTimeout(() => {
1500
1714
  logErr("Timeout: no debug_result received within 5s");
1501
1715
  process.exitCode = 1;
1502
- resolve4();
1716
+ resolve5();
1503
1717
  }, 5e3);
1504
1718
  client.onMessage((event) => {
1505
1719
  if (event.type !== "debug_result") return;
1506
1720
  clearTimeout(timeout);
1507
1721
  printDebugResult(query, event.data);
1508
- resolve4();
1722
+ resolve5();
1509
1723
  });
1510
1724
  client.send({ type: "debug", query, args });
1511
1725
  });
@@ -1569,7 +1783,7 @@ function envRecord() {
1569
1783
  async function buildDeployContext(projectDir) {
1570
1784
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
1571
1785
  const config = resolveSkWorkspaceConfig2(projectDir);
1572
- const workspaceId = config.name ?? path13__default.basename(projectDir);
1786
+ const workspaceId = config.name ?? path14__default.basename(projectDir);
1573
1787
  let log;
1574
1788
  try {
1575
1789
  const { createLogger } = await import('../core/logging.js');
@@ -1601,13 +1815,13 @@ async function ensureTargetsRegistered(projectDir) {
1601
1815
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
1602
1816
  const config = resolveSkWorkspaceConfig2(projectDir);
1603
1817
  if (config.plugins && config.plugins.length > 0) {
1604
- const { ensurePluginsLoaded } = await import('../plugin-store-RBCDBO7K.js');
1818
+ const { ensurePluginsLoaded } = await import('../plugin-store-2X2YXJVG.js');
1605
1819
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
1606
1820
  for (const f of result.failed) logWarn(f.error);
1607
1821
  }
1608
1822
  }
1609
1823
  async function runUp(opts) {
1610
- const projectDir = path13__default.resolve(opts.projectDir);
1824
+ const projectDir = path14__default.resolve(opts.projectDir);
1611
1825
  await ensureTargetsRegistered(projectDir);
1612
1826
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
1613
1827
  const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
@@ -1639,12 +1853,12 @@ async function runUp(opts) {
1639
1853
  await holdUntilSignal(handle, controller);
1640
1854
  }
1641
1855
  function holdUntilSignal(handle, controller) {
1642
- return new Promise((resolve4) => {
1856
+ return new Promise((resolve5) => {
1643
1857
  const onSig = () => {
1644
1858
  process.removeListener("SIGINT", onSig);
1645
1859
  controller.abort();
1646
1860
  logInfo("Stopping\u2026");
1647
- handle.stop().then(() => logOk("Stopped.")).catch((e) => logErr(`stop failed: ${e instanceof Error ? e.message : String(e)}`)).finally(() => resolve4());
1861
+ handle.stop().then(() => logOk("Stopped.")).catch((e) => logErr(`stop failed: ${e instanceof Error ? e.message : String(e)}`)).finally(() => resolve5());
1648
1862
  };
1649
1863
  process.on("SIGINT", onSig);
1650
1864
  });
@@ -1675,7 +1889,7 @@ async function restoreFromHandle(projectDir) {
1675
1889
  return { target, handle, ctx };
1676
1890
  }
1677
1891
  async function runDown(opts) {
1678
- const projectDir = path13__default.resolve(opts.projectDir);
1892
+ const projectDir = path14__default.resolve(opts.projectDir);
1679
1893
  const restored = await restoreFromHandle(projectDir);
1680
1894
  if (!restored) return;
1681
1895
  await restored.handle.stop();
@@ -1684,7 +1898,7 @@ async function runDown(opts) {
1684
1898
  logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
1685
1899
  }
1686
1900
  async function runStatus(opts) {
1687
- const projectDir = path13__default.resolve(opts.projectDir);
1901
+ const projectDir = path14__default.resolve(opts.projectDir);
1688
1902
  const restored = await restoreFromHandle(projectDir);
1689
1903
  if (!restored) return;
1690
1904
  const health = await restored.handle.health();
@@ -1698,7 +1912,7 @@ async function runStatus(opts) {
1698
1912
  console.log();
1699
1913
  }
1700
1914
  async function runLogs(opts) {
1701
- const projectDir = path13__default.resolve(opts.projectDir);
1915
+ const projectDir = path14__default.resolve(opts.projectDir);
1702
1916
  const restored = await restoreFromHandle(projectDir);
1703
1917
  if (!restored) return;
1704
1918
  if (!restored.handle.logs) {
@@ -1722,7 +1936,7 @@ function makeDeployCommand() {
1722
1936
  }
1723
1937
  function makeDiffCommand() {
1724
1938
  return new Command("diff").description("Show changes between deployed and source versions").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
1725
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
1939
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
1726
1940
  const result = am2.diff(ref);
1727
1941
  if (result === null) {
1728
1942
  logInfo("No differences (or asset not found).");
@@ -1775,7 +1989,7 @@ function makeFlowCommand() {
1775
1989
  function makeHistoryCommand() {
1776
1990
  const cmd = new Command("history").description("Show recent add/remove/update actions");
1777
1991
  cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
1778
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
1992
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
1779
1993
  const limit = parseInt(limitStr, 10) || 20;
1780
1994
  const entries = am2.history(limit);
1781
1995
  if (entries.length === 0) {
@@ -1795,7 +2009,7 @@ function makeHistoryCommand() {
1795
2009
  console.log();
1796
2010
  });
1797
2011
  cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
1798
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
2012
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
1799
2013
  am2.clearHistory();
1800
2014
  logOk("History cleared.");
1801
2015
  });
@@ -1808,12 +2022,12 @@ var MCP_SERVER_ENTRY = {
1808
2022
  env: {}
1809
2023
  };
1810
2024
  function pluginDir(projectDir) {
1811
- return path13__default.join(projectDir, ".claude", "plugins", "skaile");
2025
+ return path14__default.join(projectDir, ".claude", "plugins", "skaile");
1812
2026
  }
1813
2027
  async function readJsonStrict(p9) {
1814
2028
  let raw;
1815
2029
  try {
1816
- raw = await fs5.readFile(p9, "utf-8");
2030
+ raw = await fs6.readFile(p9, "utf-8");
1817
2031
  } catch {
1818
2032
  return null;
1819
2033
  }
@@ -1826,32 +2040,32 @@ async function readJsonStrict(p9) {
1826
2040
  }
1827
2041
  }
1828
2042
  async function writeJson(p9, value) {
1829
- await fs5.mkdir(path13__default.dirname(p9), { recursive: true });
1830
- await fs5.writeFile(p9, `${JSON.stringify(value, null, 2)}
2043
+ await fs6.mkdir(path14__default.dirname(p9), { recursive: true });
2044
+ await fs6.writeFile(p9, `${JSON.stringify(value, null, 2)}
1831
2045
  `);
1832
2046
  }
1833
2047
  async function copyDir(src, dest) {
1834
- await fs5.mkdir(dest, { recursive: true });
1835
- const entries = await fs5.readdir(src, { withFileTypes: true });
2048
+ await fs6.mkdir(dest, { recursive: true });
2049
+ const entries = await fs6.readdir(src, { withFileTypes: true });
1836
2050
  for (const entry of entries) {
1837
- const srcPath = path13__default.join(src, entry.name);
1838
- const destPath = path13__default.join(dest, entry.name);
2051
+ const srcPath = path14__default.join(src, entry.name);
2052
+ const destPath = path14__default.join(dest, entry.name);
1839
2053
  if (entry.isDirectory()) await copyDir(srcPath, destPath);
1840
- else await fs5.copyFile(srcPath, destPath);
2054
+ else await fs6.copyFile(srcPath, destPath);
1841
2055
  }
1842
2056
  }
1843
2057
  async function install(projectDir, opts) {
1844
2058
  return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
1845
2059
  }
1846
2060
  async function installMcp(projectDir) {
1847
- const mcpPath = path13__default.join(projectDir, ".claude", "mcp.json");
2061
+ const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
1848
2062
  const existing = await readJsonStrict(mcpPath) ?? {};
1849
2063
  const mcpServers = { ...existing.mcpServers ?? {} };
1850
2064
  const previous = mcpServers[SKAILE_MCP_NAME];
1851
2065
  const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
1852
2066
  let warning;
1853
2067
  if (previous && !matches) {
1854
- warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path13__default.relative(projectDir, mcpPath)}`;
2068
+ warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path14__default.relative(projectDir, mcpPath)}`;
1855
2069
  }
1856
2070
  mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
1857
2071
  await writeJson(mcpPath, { ...existing, mcpServers });
@@ -1860,15 +2074,15 @@ async function installMcp(projectDir) {
1860
2074
  async function installFullPlugin(projectDir) {
1861
2075
  const dir = pluginDir(projectDir);
1862
2076
  for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
1863
- const dest = path13__default.join(dir, rel);
1864
- await fs5.mkdir(path13__default.dirname(dest), { recursive: true });
1865
- await fs5.writeFile(dest, content);
2077
+ const dest = path14__default.join(dir, rel);
2078
+ await fs6.mkdir(path14__default.dirname(dest), { recursive: true });
2079
+ await fs6.writeFile(dest, content);
1866
2080
  }
1867
- const projectSkillsDir = path13__default.join(projectDir, ".skaile", "skills");
2081
+ const projectSkillsDir = path14__default.join(projectDir, ".skaile", "skills");
1868
2082
  if (existsSync(projectSkillsDir)) {
1869
- await copyDir(projectSkillsDir, path13__default.join(dir, "skills"));
2083
+ await copyDir(projectSkillsDir, path14__default.join(dir, "skills"));
1870
2084
  }
1871
- const settingsPath = path13__default.join(projectDir, ".claude", "settings.json");
2085
+ const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
1872
2086
  const settings = await readJsonStrict(settingsPath) ?? {};
1873
2087
  const plugins = settings.plugins ?? [];
1874
2088
  if (!plugins.includes(dir)) plugins.push(dir);
@@ -1876,8 +2090,8 @@ async function installFullPlugin(projectDir) {
1876
2090
  return { changed: true, method: "plugin" };
1877
2091
  }
1878
2092
  async function uninstall(projectDir) {
1879
- const settingsPath = path13__default.join(projectDir, ".claude", "settings.json");
1880
- const mcpPath = path13__default.join(projectDir, ".claude", "mcp.json");
2093
+ const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
2094
+ const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
1881
2095
  const dir = pluginDir(projectDir);
1882
2096
  let changed = false;
1883
2097
  const settings = await readJsonStrict(settingsPath);
@@ -1891,7 +2105,7 @@ async function uninstall(projectDir) {
1891
2105
  }
1892
2106
  }
1893
2107
  if (existsSync(dir)) {
1894
- await fs5.rm(dir, { recursive: true, force: true });
2108
+ await fs6.rm(dir, { recursive: true, force: true });
1895
2109
  changed = true;
1896
2110
  }
1897
2111
  const mcp = await readJsonStrict(mcpPath);
@@ -1901,7 +2115,7 @@ async function uninstall(projectDir) {
1901
2115
  const updated = { ...mcp, mcpServers: rest };
1902
2116
  if (Object.keys(rest).length === 0) delete updated.mcpServers;
1903
2117
  if (Object.keys(updated).length === 0) {
1904
- await fs5.unlink(mcpPath);
2118
+ await fs6.unlink(mcpPath);
1905
2119
  } else {
1906
2120
  await writeJson(mcpPath, updated);
1907
2121
  }
@@ -1911,12 +2125,12 @@ async function uninstall(projectDir) {
1911
2125
  async function detectInstall(projectDir) {
1912
2126
  const dir = pluginDir(projectDir);
1913
2127
  const settings = await readJsonStrict(
1914
- path13__default.join(projectDir, ".claude", "settings.json")
2128
+ path14__default.join(projectDir, ".claude", "settings.json")
1915
2129
  );
1916
- if (existsSync(path13__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
2130
+ if (existsSync(path14__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
1917
2131
  return { method: "plugin", pluginPath: dir };
1918
2132
  }
1919
- const mcp = await readJsonStrict(path13__default.join(projectDir, ".claude", "mcp.json"));
2133
+ const mcp = await readJsonStrict(path14__default.join(projectDir, ".claude", "mcp.json"));
1920
2134
  if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
1921
2135
  return { method: "mcp" };
1922
2136
  }
@@ -1925,7 +2139,7 @@ async function detectInstall(projectDir) {
1925
2139
  async function enable(projectDir) {
1926
2140
  const detected = await detectInstall(projectDir);
1927
2141
  if (!detected) throw new Error("plugin not installed for claude-code");
1928
- const settingsPath = path13__default.join(projectDir, ".claude", "settings.json");
2142
+ const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
1929
2143
  const settings = await readJsonStrict(settingsPath) ?? {};
1930
2144
  if (detected.method === "plugin") {
1931
2145
  const disabled2 = settings.disabledPlugins ?? [];
@@ -1947,7 +2161,7 @@ async function enable(projectDir) {
1947
2161
  async function disable(projectDir) {
1948
2162
  const detected = await detectInstall(projectDir);
1949
2163
  if (!detected) throw new Error("plugin not installed for claude-code");
1950
- const settingsPath = path13__default.join(projectDir, ".claude", "settings.json");
2164
+ const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
1951
2165
  const settings = await readJsonStrict(settingsPath) ?? {};
1952
2166
  if (detected.method === "plugin") {
1953
2167
  const list2 = settings.disabledPlugins ?? [];
@@ -1967,12 +2181,12 @@ async function disable(projectDir) {
1967
2181
  return { changed: true };
1968
2182
  }
1969
2183
  async function status(projectDir) {
1970
- const settingsPath = path13__default.join(projectDir, ".claude", "settings.json");
1971
- const mcpPath = path13__default.join(projectDir, ".claude", "mcp.json");
2184
+ const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
2185
+ const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
1972
2186
  const dir = pluginDir(projectDir);
1973
2187
  const settings = await readJsonStrict(settingsPath);
1974
2188
  const mcp = await readJsonStrict(mcpPath);
1975
- const pluginInstalled = !!(existsSync(path13__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
2189
+ const pluginInstalled = !!(existsSync(path14__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
1976
2190
  const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
1977
2191
  if (!pluginInstalled && !mcpInstalled) {
1978
2192
  return {
@@ -1990,7 +2204,7 @@ async function status(projectDir) {
1990
2204
  installed: "yes",
1991
2205
  enabled: disabled2 ? "no" : "yes",
1992
2206
  method: "plugin",
1993
- location: path13__default.relative(projectDir, dir)
2207
+ location: path14__default.relative(projectDir, dir)
1994
2208
  };
1995
2209
  }
1996
2210
  const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
@@ -1999,7 +2213,7 @@ async function status(projectDir) {
1999
2213
  installed: "yes",
2000
2214
  enabled: disabled ? "no" : "yes",
2001
2215
  method: "mcp",
2002
- location: path13__default.relative(projectDir, mcpPath)
2216
+ location: path14__default.relative(projectDir, mcpPath)
2003
2217
  };
2004
2218
  }
2005
2219
  var SKAILE_MCP_NAME2 = "skaile-workspace";
@@ -2013,7 +2227,7 @@ function buildEntry(projectDir) {
2013
2227
  async function readConfig(p9) {
2014
2228
  let raw;
2015
2229
  try {
2016
- raw = await fs5.readFile(p9, "utf-8");
2230
+ raw = await fs6.readFile(p9, "utf-8");
2017
2231
  } catch {
2018
2232
  return null;
2019
2233
  }
@@ -2026,16 +2240,16 @@ async function readConfig(p9) {
2026
2240
  }
2027
2241
  }
2028
2242
  async function writeConfig(p9, value) {
2029
- await fs5.mkdir(path13__default.dirname(p9), { recursive: true });
2243
+ await fs6.mkdir(path14__default.dirname(p9), { recursive: true });
2030
2244
  const cleaned = {};
2031
2245
  for (const [k, v] of Object.entries(value)) {
2032
2246
  if (v === void 0) continue;
2033
2247
  cleaned[k] = v;
2034
2248
  }
2035
- await fs5.writeFile(p9, stringify(cleaned));
2249
+ await fs6.writeFile(p9, stringify$1(cleaned));
2036
2250
  }
2037
2251
  function configPath(projectDir) {
2038
- return path13__default.join(projectDir, ".codex", "config.toml");
2252
+ return path14__default.join(projectDir, ".codex", "config.toml");
2039
2253
  }
2040
2254
  async function install2(projectDir) {
2041
2255
  const p9 = configPath(projectDir);
@@ -2046,7 +2260,7 @@ async function install2(projectDir) {
2046
2260
  const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
2047
2261
  let warning;
2048
2262
  if (previous && !matches) {
2049
- warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path13__default.relative(projectDir, p9)}`;
2263
+ warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path14__default.relative(projectDir, p9)}`;
2050
2264
  }
2051
2265
  if (matches) return { changed: false, method: "toml" };
2052
2266
  servers[SKAILE_MCP_NAME2] = next;
@@ -2063,7 +2277,7 @@ async function uninstall2(projectDir) {
2063
2277
  const updated = { ...cfg, mcp_servers: rest };
2064
2278
  if (Object.keys(rest).length === 0) delete updated.mcp_servers;
2065
2279
  if (Object.keys(updated).length === 0) {
2066
- await fs5.unlink(p9);
2280
+ await fs6.unlink(p9);
2067
2281
  } else {
2068
2282
  await writeConfig(p9, updated);
2069
2283
  }
@@ -2087,43 +2301,43 @@ async function status2(projectDir) {
2087
2301
  installed: "yes",
2088
2302
  enabled: "n/a",
2089
2303
  method: "mcp",
2090
- location: path13__default.relative(projectDir, p9)
2304
+ location: path14__default.relative(projectDir, p9)
2091
2305
  };
2092
2306
  }
2093
2307
  async function install3(projectDir) {
2094
- const extDir = path13__default.join(projectDir, ".omp", "extensions");
2095
- const extPath = path13__default.join(extDir, "skaile.ts");
2096
- await fs5.mkdir(extDir, { recursive: true });
2308
+ const extDir = path14__default.join(projectDir, ".omp", "extensions");
2309
+ const extPath = path14__default.join(extDir, "skaile.ts");
2310
+ await fs6.mkdir(extDir, { recursive: true });
2097
2311
  const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
2098
2312
  const plugin = new WorkspacePlugin({ projectDir });
2099
2313
  const nextSrc = await plugin.buildOmpExtensionSource();
2100
2314
  let prevSrc = null;
2101
2315
  try {
2102
- prevSrc = await fs5.readFile(extPath, "utf-8");
2316
+ prevSrc = await fs6.readFile(extPath, "utf-8");
2103
2317
  } catch {
2104
2318
  }
2105
2319
  if (prevSrc === nextSrc) return { changed: false, method: "generated" };
2106
- await fs5.writeFile(extPath, nextSrc);
2320
+ await fs6.writeFile(extPath, nextSrc);
2107
2321
  return { changed: true, method: "generated" };
2108
2322
  }
2109
2323
  async function uninstall3(projectDir) {
2110
- const extPath = path13__default.join(projectDir, ".omp", "extensions", "skaile.ts");
2324
+ const extPath = path14__default.join(projectDir, ".omp", "extensions", "skaile.ts");
2111
2325
  try {
2112
- await fs5.unlink(extPath);
2326
+ await fs6.unlink(extPath);
2113
2327
  return { changed: true };
2114
2328
  } catch {
2115
2329
  return { changed: false };
2116
2330
  }
2117
2331
  }
2118
2332
  async function status3(projectDir) {
2119
- const extPath = path13__default.join(projectDir, ".omp", "extensions", "skaile.ts");
2333
+ const extPath = path14__default.join(projectDir, ".omp", "extensions", "skaile.ts");
2120
2334
  if (existsSync(extPath)) {
2121
2335
  return {
2122
2336
  backend: "omp",
2123
2337
  installed: "yes",
2124
2338
  enabled: "n/a",
2125
2339
  method: "extension",
2126
- location: path13__default.relative(projectDir, extPath)
2340
+ location: path14__default.relative(projectDir, extPath)
2127
2341
  };
2128
2342
  }
2129
2343
  return {
@@ -2186,7 +2400,7 @@ async function installCodex(projectDir) {
2186
2400
  console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
2187
2401
  }
2188
2402
  async function runInstall(opts) {
2189
- const projectDir = path13__default.resolve(opts.projectDir);
2403
+ const projectDir = path14__default.resolve(opts.projectDir);
2190
2404
  const targets = resolveDriver(opts.driver);
2191
2405
  let exitCode = 0;
2192
2406
  if (targets.includes("claude-code")) {
@@ -2220,7 +2434,7 @@ async function uninstallCodex(projectDir) {
2220
2434
  else logInfo(`codex: not installed`);
2221
2435
  }
2222
2436
  async function runUninstall(opts) {
2223
- const projectDir = path13__default.resolve(opts.projectDir);
2437
+ const projectDir = path14__default.resolve(opts.projectDir);
2224
2438
  const targets = resolveDriver(opts.driver);
2225
2439
  let exitCode = 0;
2226
2440
  if (targets.includes("claude-code")) {
@@ -2263,7 +2477,7 @@ async function toggleTarget(t, projectDir, action3) {
2263
2477
  });
2264
2478
  }
2265
2479
  async function runToggle(opts, action3) {
2266
- const projectDir = path13__default.resolve(opts.projectDir);
2480
+ const projectDir = path14__default.resolve(opts.projectDir);
2267
2481
  const requestedAll = opts.driver === "all";
2268
2482
  const targets = resolveDriver(opts.driver);
2269
2483
  const usageError = checkToggleSupported(targets, requestedAll, action3);
@@ -2275,7 +2489,7 @@ async function runToggle(opts, action3) {
2275
2489
  return exitCode;
2276
2490
  }
2277
2491
  async function runStatus2(opts) {
2278
- const projectDir = path13__default.resolve(opts.projectDir);
2492
+ const projectDir = path14__default.resolve(opts.projectDir);
2279
2493
  const targets = resolveDriver(opts.driver);
2280
2494
  const rows = [];
2281
2495
  let exitCode = 0;
@@ -2346,7 +2560,7 @@ async function runHook(event) {
2346
2560
  await plugin.shutdown();
2347
2561
  return;
2348
2562
  }
2349
- const store = new PluginStore(path13__default.join(projectDir, ".skaile", "plugin-state.json"));
2563
+ const store = new PluginStore(path14__default.join(projectDir, ".skaile", "plugin-state.json"));
2350
2564
  await store.load();
2351
2565
  const status4 = store.get("connector:status");
2352
2566
  if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
@@ -2468,12 +2682,12 @@ function makeLibraryCommand() {
2468
2682
  cmd.command("init <name>").description("Create a new local library at ~/.skaile/libraries/<name>").option("--git <url>", "Initialize as a git library tracking <url>").option("--owner", "Mark as owner (default for local)").option("--contributor", "Mark as contributor").option("--reader", "Mark as reader").action(
2469
2683
  async (name, opts) => {
2470
2684
  const libDir = resolveLibraryDir();
2471
- const libPath = path13.join(libDir, name);
2685
+ const libPath = path14.join(libDir, name);
2472
2686
  const ownership = opts.contributor ? "contributor" : opts.reader ? "reader" : "owner";
2473
2687
  const { manager, close } = await openLibraryManager();
2474
2688
  try {
2475
2689
  if (opts.git) {
2476
- fs11.mkdirSync(libPath, { recursive: true });
2690
+ fs12.mkdirSync(libPath, { recursive: true });
2477
2691
  await manager.addLibrary({
2478
2692
  name,
2479
2693
  path: libPath,
@@ -2482,7 +2696,7 @@ function makeLibraryCommand() {
2482
2696
  ownership
2483
2697
  });
2484
2698
  } else {
2485
- fs11.mkdirSync(libPath, { recursive: true });
2699
+ fs12.mkdirSync(libPath, { recursive: true });
2486
2700
  await manager.addLibrary({
2487
2701
  name,
2488
2702
  path: libPath,
@@ -2539,7 +2753,7 @@ function makeLibraryCommand() {
2539
2753
  target = def;
2540
2754
  }
2541
2755
  const am2 = new AssetManager({ projectDir: process.cwd() });
2542
- const destDir = opts.dir ? path13.join(target.path, opts.dir) : target.path;
2756
+ const destDir = opts.dir ? path14.join(target.path, opts.dir) : target.path;
2543
2757
  const res = am2.create(name, opts.kind ?? kind, destDir);
2544
2758
  if (res.ok) {
2545
2759
  logOk(`Created ${opts.kind ?? kind}: ${pc5.dim(res.path)}`);
@@ -2552,6 +2766,80 @@ function makeLibraryCommand() {
2552
2766
  }
2553
2767
  }
2554
2768
  );
2769
+ const domain = cmd.command("domain").description("Manage domains (publisher namespaces) inside a library");
2770
+ async function resolveTargetLibrary(manager, libraryName) {
2771
+ if (libraryName) return manager.requireLibrary(libraryName);
2772
+ const all = await manager.listLibraries();
2773
+ const def = all.find((l) => l.isDefault);
2774
+ if (def) return def;
2775
+ if (all.length === 1) return all[0];
2776
+ if (all.length === 0) {
2777
+ logErr("No libraries registered. Run `skaile library init <name>` first.");
2778
+ process.exit(1);
2779
+ }
2780
+ logErr("No default library set. Run `skaile library default <name>` or pass --library.");
2781
+ process.exit(1);
2782
+ }
2783
+ domain.command("create <name>").description("Scaffold a domain dir + DOMAIN.md inside a library").option("--library <name>", "Target library (default: the default-marked one)").option("--publisher <p>", "Publisher slug (default: the domain name kebab-cased)").option("--description <text>", "Domain description for DOMAIN.md").action(
2784
+ async (name, opts) => {
2785
+ const { manager, close } = await openLibraryManager();
2786
+ try {
2787
+ const target = await resolveTargetLibrary(manager, opts.library);
2788
+ if (target.ownership === "reader") {
2789
+ logErr(`Library "${target.name}" is read-only (ownership=reader).`);
2790
+ process.exit(1);
2791
+ }
2792
+ const res = ensureDomain(target.path, name, {
2793
+ publisher: opts.publisher,
2794
+ description: opts.description
2795
+ });
2796
+ if (target.structure !== "domain") {
2797
+ await manager.updateLibrary(target.id, { structure: "domain" });
2798
+ }
2799
+ if (res.created) {
2800
+ logOk(`Created domain ${S.cmd(name)} (publisher @${res.publisher}) \u2192 ${res.dir}`);
2801
+ } else {
2802
+ logInfo(`Domain ${S.cmd(name)} already exists at ${res.dir}`);
2803
+ }
2804
+ } finally {
2805
+ close();
2806
+ }
2807
+ }
2808
+ );
2809
+ domain.command("list").description("List domains in a library").option("--library <name>", "Target library (default: the default-marked one)").option("--json", "Output as JSON").action(async (opts) => {
2810
+ const { manager, close } = await openLibraryManager();
2811
+ try {
2812
+ const target = await resolveTargetLibrary(manager, opts.library);
2813
+ const domains = listDomains(target.path);
2814
+ if (opts.json) return console.log(JSON.stringify(domains, null, 2));
2815
+ if (domains.length === 0) {
2816
+ logInfo(
2817
+ `No domains in "${target.name}". Create one: \`skaile library domain create <name>\`.`
2818
+ );
2819
+ return;
2820
+ }
2821
+ for (const d of domains) console.log(` ${S.cmd(d)}`);
2822
+ console.log(`
2823
+ ${S.dim(`${domains.length} domain(s) in ${target.name}`)}
2824
+ `);
2825
+ } finally {
2826
+ close();
2827
+ }
2828
+ });
2829
+ domain.command("show <name>").description("Print a domain's DOMAIN.md").option("--library <name>", "Target library (default: the default-marked one)").action(async (name, opts) => {
2830
+ const { manager, close } = await openLibraryManager();
2831
+ try {
2832
+ const target = await resolveTargetLibrary(manager, opts.library);
2833
+ const domainFile = path14.join(target.path, name, "DOMAIN.md");
2834
+ if (!existsSync(domainFile)) {
2835
+ logErr(`Domain "${name}" not found in "${target.name}" (no ${domainFile}).`);
2836
+ process.exit(1);
2837
+ }
2838
+ console.log(fs12.readFileSync(domainFile, "utf8"));
2839
+ } finally {
2840
+ close();
2841
+ }
2842
+ });
2555
2843
  cmd.command("default <name>").description("Set <name> as the default library").action(async (name) => {
2556
2844
  const { manager, close } = await openLibraryManager();
2557
2845
  try {
@@ -2565,13 +2853,13 @@ function makeLibraryCommand() {
2565
2853
  const { manager, close } = await openLibraryManager();
2566
2854
  try {
2567
2855
  const lib = await manager.requireLibrary(oldName);
2568
- const parent = path13.dirname(lib.path);
2569
- const newPath = path13.join(parent, newName);
2570
- if (fs11.existsSync(newPath)) {
2856
+ const parent = path14.dirname(lib.path);
2857
+ const newPath = path14.join(parent, newName);
2858
+ if (fs12.existsSync(newPath)) {
2571
2859
  logErr(`Target directory already exists: ${newPath}`);
2572
2860
  process.exit(1);
2573
2861
  }
2574
- fs11.renameSync(lib.path, newPath);
2862
+ fs12.renameSync(lib.path, newPath);
2575
2863
  await manager.updateLibrary(lib.id, { name: newName, path: newPath });
2576
2864
  logOk(`Renamed ${oldName} \u2192 ${newName}`);
2577
2865
  } finally {
@@ -2755,9 +3043,9 @@ async function printOverallStatus(projectDir, asJson) {
2755
3043
  } catch {
2756
3044
  secretsStrategy = "unavailable";
2757
3045
  }
2758
- const resolvedProjectDir = path13.resolve(projectDir);
2759
- const hasWorkspaceConfig = existsSync(path13.join(resolvedProjectDir, "skaile.yaml"));
2760
- const hasLockFile = existsSync(path13.join(resolvedProjectDir, "skaile.lock.yaml"));
3046
+ const resolvedProjectDir = path14.resolve(projectDir);
3047
+ const hasWorkspaceConfig = existsSync(path14.join(resolvedProjectDir, "skaile.yaml"));
3048
+ const hasLockFile = existsSync(path14.join(resolvedProjectDir, "skaile.lock.yaml"));
2761
3049
  let assignments = [];
2762
3050
  if (hasWorkspaceConfig) {
2763
3051
  try {
@@ -3113,7 +3401,7 @@ function actOnHeader(row, action3) {
3113
3401
  return row.type === "domain-header" || row.type === "domain-info";
3114
3402
  }
3115
3403
  async function loadAssets() {
3116
- const { gatherAssetFeeds } = await import('../asset-feeds-EGSG4FUB.js');
3404
+ const { gatherAssetFeeds } = await import('../asset-feeds-AOZLZMDV.js');
3117
3405
  const { entries, domains, notes } = await gatherAssetFeeds(am, am.projectDir);
3118
3406
  if (notes.length > 0) {
3119
3407
  state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
@@ -3218,7 +3506,7 @@ async function loadSourcesAndLibraries() {
3218
3506
  const { manager, library, close } = await openLibraryManager2();
3219
3507
  try {
3220
3508
  const newRoot = getGlobalCacheDir2();
3221
- const legacyRoot = path13__default.join(skaileHomeDir(), "sources");
3509
+ const legacyRoot = path14__default.join(skaileHomeDir(), "sources");
3222
3510
  const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
3223
3511
  const libs = await manager.listLibraries();
3224
3512
  const defs = await library.listAssetDefs();
@@ -3598,10 +3886,10 @@ async function showInfo() {
3598
3886
  }
3599
3887
  console.log();
3600
3888
  console.log(pc5.dim(" Press any key to return..."));
3601
- await new Promise((resolve4) => {
3889
+ await new Promise((resolve5) => {
3602
3890
  const onData = () => {
3603
3891
  process.stdin.removeListener("data", onData);
3604
- resolve4();
3892
+ resolve5();
3605
3893
  };
3606
3894
  process.stdin.once("data", onData);
3607
3895
  });
@@ -3854,13 +4142,13 @@ async function run(projectDir) {
3854
4142
  }
3855
4143
  function makeManageCommand() {
3856
4144
  return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
3857
- await run(path13__default.resolve(opts.projectDir));
4145
+ await run(path14__default.resolve(opts.projectDir));
3858
4146
  });
3859
4147
  }
3860
4148
  function makeMcpServerCommand() {
3861
4149
  return new Command("mcp-server").description("Start skaile workspace MCP server (stdio transport)").option("--project-dir <path>", "Project directory (default: cwd)", process.cwd()).action(async (opts) => {
3862
- const path36 = await import('path');
3863
- const projectDir = path36.default.resolve(opts.projectDir);
4150
+ const path37 = await import('path');
4151
+ const projectDir = path37.default.resolve(opts.projectDir);
3864
4152
  const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
3865
4153
  registerLogStore(
3866
4154
  new LogStore({
@@ -3897,8 +4185,8 @@ function makeNpxCommand() {
3897
4185
  skills.command("add <url>").description(
3898
4186
  "Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
3899
4187
  ).requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").option("--global", "Deploy globally").action(async (url, opts) => {
3900
- const projectDir = path13__default.resolve(opts.projectDir);
3901
- const projYaml = path13__default.join(projectDir, "skaile.yaml");
4188
+ const projectDir = path14__default.resolve(opts.projectDir);
4189
+ const projYaml = path14__default.join(projectDir, "skaile.yaml");
3902
4190
  if (!existsSync(projYaml)) {
3903
4191
  logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
3904
4192
  process.exit(1);
@@ -3911,7 +4199,7 @@ function makeNpxCommand() {
3911
4199
  }
3912
4200
  const spinner5 = p6.spinner();
3913
4201
  const slug = sourceSlug(url);
3914
- const clonePath = path13__default.join(getGlobalCacheDir(), slug);
4202
+ const clonePath = path14__default.join(getGlobalCacheDir(), slug);
3915
4203
  spinner5.start(`Cloning ${url}`);
3916
4204
  try {
3917
4205
  if (!existsSync(clonePath)) {
@@ -3960,7 +4248,7 @@ function makeNpxCommand() {
3960
4248
  return npx;
3961
4249
  }
3962
4250
  function resolvePublisher(clonePath, url) {
3963
- const manifestPath = path13__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
4251
+ const manifestPath = path14__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
3964
4252
  if (existsSync(manifestPath)) {
3965
4253
  try {
3966
4254
  const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
@@ -3973,12 +4261,12 @@ function resolvePublisher(clonePath, url) {
3973
4261
  return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
3974
4262
  }
3975
4263
  function resolveSkillName(clonePath, requested) {
3976
- const skillsDir = path13__default.join(clonePath, "skills");
3977
- if (existsSync(path13__default.join(skillsDir, requested, "SKILL.md"))) return requested;
4264
+ const skillsDir = path14__default.join(clonePath, "skills");
4265
+ if (existsSync(path14__default.join(skillsDir, requested, "SKILL.md"))) return requested;
3978
4266
  if (!existsSync(skillsDir)) return requested;
3979
4267
  for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
3980
4268
  if (!entry.isDirectory()) continue;
3981
- const md = path13__default.join(skillsDir, entry.name, "SKILL.md");
4269
+ const md = path14__default.join(skillsDir, entry.name, "SKILL.md");
3982
4270
  if (!existsSync(md)) continue;
3983
4271
  try {
3984
4272
  const { data } = parseFrontmatter(readFileSync(md, "utf8"));
@@ -3996,7 +4284,7 @@ function makeOutdatedCommand() {
3996
4284
  new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
3997
4285
  ).action((name, opts) => {
3998
4286
  const am2 = new AssetManager({
3999
- projectDir: path13__default.resolve(opts.projectDir),
4287
+ projectDir: path14__default.resolve(opts.projectDir),
4000
4288
  driverTarget: opts.target
4001
4289
  });
4002
4290
  const entries = am2.outdated();
@@ -4025,7 +4313,7 @@ function makeOutdatedCommand() {
4025
4313
  function makePatchCommand() {
4026
4314
  const cmd = new Command("patch").description("Patch workflow for skill improvement");
4027
4315
  cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
4028
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
4316
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
4029
4317
  try {
4030
4318
  const dest = am2.patch(ref);
4031
4319
  logOk(`Extracted to ${S.dim(dest)}`);
@@ -4036,7 +4324,7 @@ function makePatchCommand() {
4036
4324
  }
4037
4325
  });
4038
4326
  cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
4039
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
4327
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
4040
4328
  try {
4041
4329
  const patchFile = am2.patchCommit(ref);
4042
4330
  logOk(`Patch saved to ${S.dim(patchFile)}`);
@@ -4047,7 +4335,7 @@ function makePatchCommand() {
4047
4335
  }
4048
4336
  });
4049
4337
  cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
4050
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
4338
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
4051
4339
  try {
4052
4340
  am2.patchSubmit(ref);
4053
4341
  logOk("Patch applied to repo clone and committed.");
@@ -4060,7 +4348,7 @@ function makePatchCommand() {
4060
4348
  }
4061
4349
  });
4062
4350
  cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
4063
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
4351
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
4064
4352
  am2.patchRemove(ref);
4065
4353
  logOk(`Patch removed for ${ref}`);
4066
4354
  });
@@ -4078,7 +4366,7 @@ function action2(fn) {
4078
4366
  };
4079
4367
  }
4080
4368
  async function reconcileAndReport(projectDir, plugins) {
4081
- const { reconcilePlugins } = await import('../plugin-store-RBCDBO7K.js');
4369
+ const { reconcilePlugins } = await import('../plugin-store-2X2YXJVG.js');
4082
4370
  if (plugins.length === 0) {
4083
4371
  logInfo("No plugins declared \u2014 nothing to reconcile.");
4084
4372
  return;
@@ -4092,10 +4380,10 @@ async function reconcileAndReport(projectDir, plugins) {
4092
4380
  }
4093
4381
  }
4094
4382
  async function runInstall2(spec, opts) {
4095
- const projectDir = path13__default.resolve(opts.projectDir);
4383
+ const projectDir = path14__default.resolve(opts.projectDir);
4096
4384
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
4097
- const { specName } = await import('../plugin-store-RBCDBO7K.js');
4098
- const yamlPath = path13__default.join(projectDir, "skaile.yaml");
4385
+ const { specName } = await import('../plugin-store-2X2YXJVG.js');
4386
+ const yamlPath = path14__default.join(projectDir, "skaile.yaml");
4099
4387
  const editor = WorkspaceYamlEditor2.load(yamlPath);
4100
4388
  const replaced = editor.addPlugin(spec, specName);
4101
4389
  editor.save();
@@ -4104,10 +4392,10 @@ async function runInstall2(spec, opts) {
4104
4392
  await reconcileAndReport(projectDir, editor.getPlugins());
4105
4393
  }
4106
4394
  async function runRemove(name, opts) {
4107
- const projectDir = path13__default.resolve(opts.projectDir);
4395
+ const projectDir = path14__default.resolve(opts.projectDir);
4108
4396
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
4109
- const { specName } = await import('../plugin-store-RBCDBO7K.js');
4110
- const yamlPath = path13__default.join(projectDir, "skaile.yaml");
4397
+ const { specName } = await import('../plugin-store-2X2YXJVG.js');
4398
+ const yamlPath = path14__default.join(projectDir, "skaile.yaml");
4111
4399
  const editor = WorkspaceYamlEditor2.load(yamlPath);
4112
4400
  const removed = editor.removePlugin(name, specName);
4113
4401
  if (!removed) {
@@ -4119,7 +4407,7 @@ async function runRemove(name, opts) {
4119
4407
  await reconcileAndReport(projectDir, editor.getPlugins());
4120
4408
  }
4121
4409
  async function runList(opts) {
4122
- const projectDir = path13__default.resolve(opts.projectDir);
4410
+ const projectDir = path14__default.resolve(opts.projectDir);
4123
4411
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
4124
4412
  const config = resolveSkWorkspaceConfig2(projectDir);
4125
4413
  const declared = config.plugins ?? [];
@@ -4134,7 +4422,7 @@ async function runList(opts) {
4134
4422
  const registry = createPluginRegistry();
4135
4423
  if (declared.length > 0) {
4136
4424
  try {
4137
- const { loadPlugins } = await import('../plugin-store-RBCDBO7K.js');
4425
+ const { loadPlugins } = await import('../plugin-store-2X2YXJVG.js');
4138
4426
  const result = await loadPlugins(projectDir, declared, registry);
4139
4427
  for (const f of result.failed) logWarn(f.error);
4140
4428
  } catch (err) {
@@ -4173,7 +4461,7 @@ function makePresetCommand() {
4173
4461
  cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
4174
4462
  const presetName = name ?? "my-preset";
4175
4463
  const filename = `${presetName}.preset.yaml`;
4176
- const outPath = path13__default.join(path13__default.resolve(opts.dir), filename);
4464
+ const outPath = path14__default.join(path14__default.resolve(opts.dir), filename);
4177
4465
  if (existsSync(outPath)) {
4178
4466
  logErr(`File already exists: ${outPath}`);
4179
4467
  logInfo("Choose a different name or remove the existing file.");
@@ -4221,7 +4509,7 @@ async function reportNestedPresetRefs(preset) {
4221
4509
  }
4222
4510
  async function checkPresetCycles(preset, resolved) {
4223
4511
  const { detectCycles } = await import('../discovery/index.js');
4224
- const presetRef = path13__default.basename(resolved, ".preset.yaml");
4512
+ const presetRef = path14__default.basename(resolved, ".preset.yaml");
4225
4513
  const edges = [];
4226
4514
  for (const item of preset.items) {
4227
4515
  if (item.ref) {
@@ -4272,7 +4560,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
4272
4560
  }
4273
4561
  }
4274
4562
  async function runPresetValidate(filePath) {
4275
- const resolved = path13__default.resolve(filePath);
4563
+ const resolved = path14__default.resolve(filePath);
4276
4564
  const preset = await loadPresetForValidation(resolved);
4277
4565
  await reportNestedPresetRefs(preset);
4278
4566
  await checkPresetCycles(preset, resolved);
@@ -4367,7 +4655,7 @@ async function runRefInstall(ref, opts) {
4367
4655
  spinner5.start(`Installing ${ref}`);
4368
4656
  try {
4369
4657
  const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-362BZ6OW.js');
4370
- const catalog = await openCatalogSource2({ projectDir: path13__default.resolve(opts.projectDir) });
4658
+ const catalog = await openCatalogSource2({ projectDir: path14__default.resolve(opts.projectDir) });
4371
4659
  if (!supportsInstallManifest(catalog)) {
4372
4660
  throw new Error(
4373
4661
  "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."
@@ -4396,7 +4684,7 @@ async function runRefInstall(ref, opts) {
4396
4684
  }
4397
4685
  }
4398
4686
  async function runYamlInstall(opts) {
4399
- const projectDir = path13__default.resolve(opts.projectDir);
4687
+ const projectDir = path14__default.resolve(opts.projectDir);
4400
4688
  try {
4401
4689
  const { ensureSourcesCloned } = await import('../ensure-sources-NSDMTAWN.js');
4402
4690
  const hydrate = ensureSourcesCloned(projectDir, { quiet: true });
@@ -4441,7 +4729,7 @@ async function runYamlInstall(opts) {
4441
4729
  }
4442
4730
  function makeCheckCommand() {
4443
4731
  return new Command("check").description("Check for unmet requirements").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
4444
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
4732
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
4445
4733
  const issues = am2.doctor();
4446
4734
  if (issues.length === 0) {
4447
4735
  logOk("All dependencies satisfied.");
@@ -4458,10 +4746,10 @@ function makeCheckCommand() {
4458
4746
  function makeCleanCommand() {
4459
4747
  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) => {
4460
4748
  const am2 = new AssetManager({
4461
- projectDir: path13__default.resolve(opts.projectDir),
4749
+ projectDir: path14__default.resolve(opts.projectDir),
4462
4750
  driverTarget: opts.target
4463
4751
  });
4464
- const lock = readLock(path13__default.resolve(opts.projectDir, "skaile.lock.yaml"));
4752
+ const lock = readLock(path14__default.resolve(opts.projectDir, "skaile.lock.yaml"));
4465
4753
  if (!lock || Object.keys(lock.assets).length === 0) {
4466
4754
  logInfo("Nothing to clean (no skaile-managed assets found).");
4467
4755
  return;
@@ -4514,14 +4802,14 @@ function makeCleanCommand() {
4514
4802
  }
4515
4803
  function makeRebuildCommand() {
4516
4804
  return new Command("rebuild").description("Re-snapshot inline-snapshot composition items and bump prompt version").argument("[agent]", "Agent name or path (defaults to current project agent)").option("--project-dir <dir>", "Project directory", process.cwd()).action(async (agentArg, opts) => {
4517
- const projectDir = path13__default.resolve(opts.projectDir);
4805
+ const projectDir = path14__default.resolve(opts.projectDir);
4518
4806
  let agentDir;
4519
4807
  if (agentArg) {
4520
4808
  if (agentArg.includes("/") || agentArg.includes("\\")) {
4521
- agentDir = path13__default.resolve(projectDir, agentArg);
4809
+ agentDir = path14__default.resolve(projectDir, agentArg);
4522
4810
  } else {
4523
4811
  const resolved = resolveAgentDir(projectDir);
4524
- agentDir = resolved ?? path13__default.resolve(projectDir, agentArg);
4812
+ agentDir = resolved ?? path14__default.resolve(projectDir, agentArg);
4525
4813
  }
4526
4814
  } else {
4527
4815
  const resolved = resolveAgentDir(projectDir);
@@ -4599,7 +4887,7 @@ function makeFlowEventHandler() {
4599
4887
  }
4600
4888
  function makeRunCommand() {
4601
4889
  const cmd = new Command("run").description("Start a flow or run a single-shot text prompt").argument("[flow-id-or-text...]", "Flow ID or text prompt").option("--project-dir <path>", "Project directory", process.cwd()).option("--driver <name>", "Driver backend (claude-sdk, codex, omp)").option("--provider <name>", "LLM provider").option("--model <name>", "Model override").option("--label <label>", "Human-readable session label").option("--dry-run", "Print plan without executing").option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
4602
- const projectDir = path13__default.resolve(opts.projectDir);
4890
+ const projectDir = path14__default.resolve(opts.projectDir);
4603
4891
  const cliDriver = opts.driver;
4604
4892
  const dryRun = opts.dryRun ?? false;
4605
4893
  let flowId = positional[0];
@@ -4634,12 +4922,12 @@ function makeRunCommand() {
4634
4922
  const priorityRoots = [];
4635
4923
  let dir = projectDir;
4636
4924
  for (let i = 0; i < 6; i++) {
4637
- const candidate = path13__default.join(dir, "ai-assets");
4638
- if (fs11__default.existsSync(candidate)) {
4925
+ const candidate = path14__default.join(dir, "ai-assets");
4926
+ if (fs12__default.existsSync(candidate)) {
4639
4927
  priorityRoots.push(candidate);
4640
4928
  break;
4641
4929
  }
4642
- dir = path13__default.dirname(dir);
4930
+ dir = path14__default.dirname(dir);
4643
4931
  }
4644
4932
  const flowPath = findFlowFile(flowId, priorityRoots);
4645
4933
  if (!flowPath) {
@@ -4694,7 +4982,7 @@ function makeRunCommand() {
4694
4982
  }
4695
4983
  function makeResumeCommand() {
4696
4984
  const cmd = new Command("resume").description("Resume current session").option("--project-dir <path>", "Project directory", process.cwd()).option("--session <run-id>", "Target session by runId").option("--dry-run", "Print plan without executing").action(async (opts) => {
4697
- const projectDir = path13__default.resolve(opts.projectDir);
4985
+ const projectDir = path14__default.resolve(opts.projectDir);
4698
4986
  const sessionId = opts.session;
4699
4987
  const dryRun = opts.dryRun ?? false;
4700
4988
  const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
@@ -4721,7 +5009,7 @@ function makeResumeCommand() {
4721
5009
  }
4722
5010
  function makeStatusCommand() {
4723
5011
  return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
4724
- const projectDir = path13__default.resolve(opts.projectDir);
5012
+ const projectDir = path14__default.resolve(opts.projectDir);
4725
5013
  const session = await loadSession(projectDir);
4726
5014
  if (!session) {
4727
5015
  logInfo("No active session.");
@@ -4746,7 +5034,7 @@ function makeStatusCommand() {
4746
5034
  }
4747
5035
  function makeClearCommand() {
4748
5036
  return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
4749
- const projectDir = path13__default.resolve(opts.projectDir);
5037
+ const projectDir = path14__default.resolve(opts.projectDir);
4750
5038
  await clearSession(projectDir);
4751
5039
  logOk("Session cleared.");
4752
5040
  });
@@ -4755,8 +5043,8 @@ function makeReplCommand() {
4755
5043
  return new Command("repl").description("Start an interactive agent session").option("--project-dir <path>", "Project directory").option("--driver <name>", "Driver backend (claude-sdk, omp)").option("--provider <name>", "LLM provider").option("--model <name>", "Model override").option("--resume", "Resume last session").option("--resume-session <id>", "Resume specific session").action(async (opts) => {
4756
5044
  const { findWorkspaceRoot: findWorkspaceRoot2 } = await import('../core/index.js');
4757
5045
  const { startRepl } = await import('../tui/index.js');
4758
- const os = await import('os');
4759
- const userCwd = path13__default.resolve(opts.projectDir ?? process.cwd());
5046
+ const os2 = await import('os');
5047
+ const userCwd = path14__default.resolve(opts.projectDir ?? process.cwd());
4760
5048
  const workspaceRoot = findWorkspaceRoot2(userCwd);
4761
5049
  let projectDir;
4762
5050
  let agentCwd;
@@ -4778,13 +5066,13 @@ function makeReplCommand() {
4778
5066
  p6.cancel("Cancelled.");
4779
5067
  process.exit(0);
4780
5068
  }
4781
- const tmpDir = fs11__default.mkdtempSync(path13__default.join(os.tmpdir(), "skaile-repl-"));
5069
+ const tmpDir = fs12__default.mkdtempSync(path14__default.join(os2.tmpdir(), "skaile-repl-"));
4782
5070
  projectDir = tmpDir;
4783
5071
  agentCwd = userCwd;
4784
5072
  logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
4785
5073
  if (!driverOverride) {
4786
- const claudeDir = path13__default.join(os.homedir(), ".claude");
4787
- if (fs11__default.existsSync(claudeDir)) {
5074
+ const claudeDir = path14__default.join(os2.homedir(), ".claude");
5075
+ if (fs12__default.existsSync(claudeDir)) {
4788
5076
  driverOverride = "claude-sdk";
4789
5077
  logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} backend`);
4790
5078
  } else {
@@ -4835,7 +5123,7 @@ async function ensurePluginsLoadedForServe(projectDir) {
4835
5123
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
4836
5124
  const config = resolveSkWorkspaceConfig2(projectDir);
4837
5125
  if (!config.plugins || config.plugins.length === 0) return;
4838
- const { ensurePluginsLoaded } = await import('../plugin-store-RBCDBO7K.js');
5126
+ const { ensurePluginsLoaded } = await import('../plugin-store-2X2YXJVG.js');
4839
5127
  const { pluginRegistry } = await import('../plugin-registry/index.js');
4840
5128
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
4841
5129
  if (result.loaded.length > 0) {
@@ -4851,9 +5139,9 @@ async function ensurePluginsLoadedForServe(projectDir) {
4851
5139
  async function runCompileTest(opts) {
4852
5140
  const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-F4NZ66VD.js');
4853
5141
  const { tmpdir } = await import('os');
4854
- const { dirname: dirname3, join: join5, resolve: resolve4 } = await import('path');
5142
+ const { dirname: dirname4, join: join6, resolve: resolve5 } = await import('path');
4855
5143
  const { fileURLToPath: fileURLToPath2 } = await import('url');
4856
- const { unlinkSync, existsSync: existsSync13 } = await import('fs');
5144
+ const { unlinkSync, existsSync: existsSync14 } = await import('fs');
4857
5145
  const { spawn } = await import('child_process');
4858
5146
  const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
4859
5147
  const { MONOREPO_ROOT } = await import('../paths-4SSFMX5Z.js');
@@ -4863,9 +5151,9 @@ async function runCompileTest(opts) {
4863
5151
  process.exitCode = 2;
4864
5152
  return;
4865
5153
  }
4866
- const outfile = join5(tmpdir(), `skaile-compile-test-${Date.now()}`);
5154
+ const outfile = join6(tmpdir(), `skaile-compile-test-${Date.now()}`);
4867
5155
  const __thisFile = fileURLToPath2(import.meta.url);
4868
- const entryPoint = resolve4(dirname3(__thisFile), "..", "index.ts");
5156
+ const entryPoint = resolve5(dirname4(__thisFile), "..", "index.ts");
4869
5157
  logInfo2(`Building compiled binary...`);
4870
5158
  logInfo2(`Entry: ${S2.dim(entryPoint)}`);
4871
5159
  logInfo2(`Output: ${S2.dim(outfile)}`);
@@ -4915,7 +5203,7 @@ async function runCompileTest(opts) {
4915
5203
  } catch {
4916
5204
  }
4917
5205
  try {
4918
- if (existsSync13(outfile)) unlinkSync(outfile);
5206
+ if (existsSync14(outfile)) unlinkSync(outfile);
4919
5207
  } catch {
4920
5208
  }
4921
5209
  }
@@ -5168,19 +5456,19 @@ function buildTailSelect(q) {
5168
5456
  return { sql, params };
5169
5457
  }
5170
5458
  function sleepUnlessAborted(ms, signal) {
5171
- return new Promise((resolve4) => {
5459
+ return new Promise((resolve5) => {
5172
5460
  if (signal?.aborted) {
5173
- resolve4();
5461
+ resolve5();
5174
5462
  return;
5175
5463
  }
5176
5464
  const timer = setTimeout(() => {
5177
5465
  signal?.removeEventListener("abort", onAbort);
5178
- resolve4();
5466
+ resolve5();
5179
5467
  }, ms);
5180
5468
  const onAbort = () => {
5181
5469
  clearTimeout(timer);
5182
5470
  signal?.removeEventListener("abort", onAbort);
5183
- resolve4();
5471
+ resolve5();
5184
5472
  };
5185
5473
  signal?.addEventListener("abort", onAbort, { once: true });
5186
5474
  });
@@ -5257,7 +5545,7 @@ async function remoteTail(opts) {
5257
5545
  ]
5258
5546
  });
5259
5547
  const filter = makeFilter(opts.query);
5260
- return new Promise((resolve4, reject) => {
5548
+ return new Promise((resolve5, reject) => {
5261
5549
  let settled = false;
5262
5550
  const finish = (err) => {
5263
5551
  if (settled) return;
@@ -5268,11 +5556,11 @@ async function remoteTail(opts) {
5268
5556
  }
5269
5557
  opts.signal?.removeEventListener("abort", onAbort);
5270
5558
  if (err) reject(err);
5271
- else resolve4();
5559
+ else resolve5();
5272
5560
  };
5273
5561
  const onAbort = () => finish();
5274
5562
  if (opts.signal?.aborted) {
5275
- resolve4();
5563
+ resolve5();
5276
5564
  return;
5277
5565
  }
5278
5566
  opts.signal?.addEventListener("abort", onAbort, { once: true });
@@ -5326,7 +5614,7 @@ function resolveMode(opts) {
5326
5614
  if (opts.forceLocal && opts.forceRemote) {
5327
5615
  throw new Error("Cannot use both --local and --remote");
5328
5616
  }
5329
- const startDir = path13__default.resolve(opts.projectDir ?? process.cwd());
5617
+ const startDir = path14__default.resolve(opts.projectDir ?? process.cwd());
5330
5618
  const localDb = findLogsDb(startDir);
5331
5619
  if (opts.forceLocal) {
5332
5620
  if (!localDb) {
@@ -5359,14 +5647,14 @@ function resolveMode(opts) {
5359
5647
  function findLogsDb(startDir) {
5360
5648
  let dir = startDir;
5361
5649
  for (let i = 0; i < MAX_WALK_LEVELS; i++) {
5362
- const candidate = path13__default.join(dir, ".skaile", "logs.db");
5650
+ const candidate = path14__default.join(dir, ".skaile", "logs.db");
5363
5651
  if (existsSync(candidate)) {
5364
5652
  try {
5365
5653
  if (statSync(candidate).isFile()) return candidate;
5366
5654
  } catch {
5367
5655
  }
5368
5656
  }
5369
- const parent = path13__default.dirname(dir);
5657
+ const parent = path14__default.dirname(dir);
5370
5658
  if (parent === dir) return void 0;
5371
5659
  dir = parent;
5372
5660
  }
@@ -5392,7 +5680,7 @@ function readApiToken() {
5392
5680
  }
5393
5681
  function readGlobalSettings() {
5394
5682
  try {
5395
- const settingsPath = path13__default.join(homedir(), ".skaile", "settings.json");
5683
+ const settingsPath = path14__default.join(homedir(), ".skaile", "settings.json");
5396
5684
  if (!existsSync(settingsPath)) return {};
5397
5685
  return JSON.parse(readFileSync(settingsPath, "utf8"));
5398
5686
  } catch {
@@ -5541,7 +5829,7 @@ function parsePositiveInt(value, flag) {
5541
5829
  function makeSessionCommand() {
5542
5830
  const cmd = new Command("session").description("Manage sessions");
5543
5831
  cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
5544
- const projectDir = path13__default.resolve(opts.projectDir);
5832
+ const projectDir = path14__default.resolve(opts.projectDir);
5545
5833
  const sessions = await listSessions(projectDir);
5546
5834
  const current = await loadSession(projectDir);
5547
5835
  if (sessions.length === 0) {
@@ -5569,7 +5857,7 @@ function makeSessionCommand() {
5569
5857
  console.log();
5570
5858
  });
5571
5859
  cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
5572
- const projectDir = path13__default.resolve(opts.projectDir);
5860
+ const projectDir = path14__default.resolve(opts.projectDir);
5573
5861
  const session = await loadSessionById(projectDir, runId);
5574
5862
  if (!session) {
5575
5863
  logErr(`Session not found: ${runId}`);
@@ -5578,12 +5866,12 @@ function makeSessionCommand() {
5578
5866
  console.log(JSON.stringify(session, null, 2));
5579
5867
  });
5580
5868
  cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
5581
- const projectDir = path13__default.resolve(opts.projectDir);
5869
+ const projectDir = path14__default.resolve(opts.projectDir);
5582
5870
  await setCurrentSession(projectDir, runId);
5583
5871
  logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
5584
5872
  });
5585
5873
  cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
5586
- const projectDir = path13__default.resolve(opts.projectDir);
5874
+ const projectDir = path14__default.resolve(opts.projectDir);
5587
5875
  await deleteSession(projectDir, runId);
5588
5876
  logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
5589
5877
  });
@@ -5637,12 +5925,12 @@ function showOverview(am2) {
5637
5925
  }
5638
5926
  function showAsset(am2, kind, name) {
5639
5927
  const entry = am2.info(`${kind}:${name}`);
5640
- if (entry?.source && fs11__default.existsSync(entry.source)) {
5928
+ if (entry?.source && fs12__default.existsSync(entry.source)) {
5641
5929
  console.log();
5642
5930
  console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
5643
5931
  console.log(` ${S.rule(40)}`);
5644
5932
  console.log();
5645
- console.log(fs11__default.readFileSync(entry.source, "utf-8"));
5933
+ console.log(fs12__default.readFileSync(entry.source, "utf-8"));
5646
5934
  return;
5647
5935
  }
5648
5936
  logErr(`Asset not found: ${kind}:${name}`);
@@ -5651,7 +5939,7 @@ function showAsset(am2, kind, name) {
5651
5939
  function makeShowCommand() {
5652
5940
  return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, bundle, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").action((kind, name, opts) => {
5653
5941
  const am2 = new AssetManager({
5654
- projectDir: path13__default.resolve(opts.projectDir),
5942
+ projectDir: path14__default.resolve(opts.projectDir),
5655
5943
  driverTarget: opts.target
5656
5944
  });
5657
5945
  if (!kind) {
@@ -5689,7 +5977,7 @@ function addSourceManifestCommands(src) {
5689
5977
 
5690
5978
  // cli/src/commands/source.ts
5691
5979
  function sourceClonePath(name) {
5692
- return path13.join(getGlobalCacheDir(), name);
5980
+ return path14.join(getGlobalCacheDir(), name);
5693
5981
  }
5694
5982
  function deriveSlug(url) {
5695
5983
  return url.replace(/\.git$/, "").split(/[/:]/).pop() ?? "source";
@@ -5714,7 +6002,7 @@ function requireProjectYamlPath() {
5714
6002
  );
5715
6003
  process.exit(1);
5716
6004
  }
5717
- return path13.join(root, workspaceConfigFilename());
6005
+ return path14.join(root, workspaceConfigFilename());
5718
6006
  }
5719
6007
  function readProjectSources(yamlPath) {
5720
6008
  if (!existsSync(yamlPath)) return [];
@@ -5812,7 +6100,7 @@ function makeSourceCommand() {
5812
6100
  const result = await refreshManifestCache(entry, opts.dev);
5813
6101
  logOk(`Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from "${slug}".`);
5814
6102
  for (const err of result.errors) logWarn(err);
5815
- logOk(`Source "${slug}" registered in ${path13.relative(process.cwd(), yamlPath)}.`);
6103
+ logOk(`Source "${slug}" registered in ${path14.relative(process.cwd(), yamlPath)}.`);
5816
6104
  }
5817
6105
  );
5818
6106
  cmd.command("list").description("List sources registered in this project's skaile.yaml").option("--json", "Output as JSON").action(async (opts) => {
@@ -5940,10 +6228,10 @@ function makeStoreCommand() {
5940
6228
  if (opts.email) {
5941
6229
  const readline2 = await import('readline');
5942
6230
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
5943
- const password = await new Promise((resolve4) => {
6231
+ const password = await new Promise((resolve5) => {
5944
6232
  rl.question("Password: ", (answer) => {
5945
6233
  rl.close();
5946
- resolve4(answer);
6234
+ resolve5(answer);
5947
6235
  });
5948
6236
  });
5949
6237
  try {
@@ -6098,7 +6386,7 @@ function printTree(node, prefix = "", isLast = true) {
6098
6386
  }
6099
6387
  function makeTreeCommand() {
6100
6388
  return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
6101
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
6389
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
6102
6390
  const root = am2.tree();
6103
6391
  if (root.children.length === 0) {
6104
6392
  logInfo("No dependencies in lock file. Run `skaile install` first.");
@@ -6116,7 +6404,7 @@ function makeUpdateCommand() {
6116
6404
  try {
6117
6405
  const catalogSpinner = p6.spinner();
6118
6406
  catalogSpinner.start("Refreshing catalog cache");
6119
- const remote = await openCatalogSource({ projectDir: path13__default.resolve(opts.projectDir) });
6407
+ const remote = await openCatalogSource({ projectDir: path14__default.resolve(opts.projectDir) });
6120
6408
  const result2 = await remote.refresh();
6121
6409
  catalogSpinner.stop(
6122
6410
  `Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
@@ -6128,7 +6416,7 @@ function makeUpdateCommand() {
6128
6416
  }
6129
6417
  }
6130
6418
  if (opts.catalogOnly) return;
6131
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
6419
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
6132
6420
  const spinner5 = p6.spinner();
6133
6421
  spinner5.start("Re-deploying assets");
6134
6422
  const result = await am2.install();
@@ -6162,12 +6450,12 @@ function findManifestCandidates(rootPath) {
6162
6450
  function walk(dir) {
6163
6451
  let entries;
6164
6452
  try {
6165
- entries = fs11__default.readdirSync(dir, { withFileTypes: true });
6453
+ entries = fs12__default.readdirSync(dir, { withFileTypes: true });
6166
6454
  } catch {
6167
6455
  return;
6168
6456
  }
6169
6457
  for (const entry of entries) {
6170
- const fullPath = path13__default.join(dir, entry.name);
6458
+ const fullPath = path14__default.join(dir, entry.name);
6171
6459
  if (entry.isDirectory()) {
6172
6460
  if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
6173
6461
  } else if (entry.isFile()) {
@@ -6208,7 +6496,7 @@ function checkManifestIdentity(kind, parsed) {
6208
6496
  return null;
6209
6497
  }
6210
6498
  function parseManifestCandidate(c, absRoot) {
6211
- const content = fs11__default.readFileSync(c.filePath, "utf-8");
6499
+ const content = fs12__default.readFileSync(c.filePath, "utf-8");
6212
6500
  if (c.filePath.endsWith(".md")) {
6213
6501
  const parsed = parseMdFrontmatter(content);
6214
6502
  if (parsed === null) {
@@ -6220,13 +6508,13 @@ function parseManifestCandidate(c, absRoot) {
6220
6508
  const parsed = c.filePath.endsWith(".json") ? JSON.parse(content) : parse(content);
6221
6509
  return { kind: "value", parsed };
6222
6510
  } catch (e) {
6223
- const relPath = path13__default.relative(absRoot, c.filePath);
6511
+ const relPath = path14__default.relative(absRoot, c.filePath);
6224
6512
  logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
6225
6513
  return { kind: "error" };
6226
6514
  }
6227
6515
  }
6228
6516
  function validateManifestCandidate(c, parsed, absRoot, registry) {
6229
- const relPath = path13__default.relative(absRoot, c.filePath);
6517
+ const relPath = path14__default.relative(absRoot, c.filePath);
6230
6518
  let errors = 0;
6231
6519
  const identityError = checkManifestIdentity(c.kind, parsed);
6232
6520
  if (identityError) {
@@ -6248,8 +6536,8 @@ function validateManifestCandidate(c, parsed, absRoot, registry) {
6248
6536
  return { errors, warnings: 0 };
6249
6537
  }
6250
6538
  function validateManifests(rootPath) {
6251
- const absRoot = path13__default.resolve(rootPath);
6252
- if (!fs11__default.existsSync(absRoot)) {
6539
+ const absRoot = path14__default.resolve(rootPath);
6540
+ if (!fs12__default.existsSync(absRoot)) {
6253
6541
  logErr(`Path does not exist: ${absRoot}`);
6254
6542
  return { total: 0, errors: 1, warnings: 0 };
6255
6543
  }
@@ -6275,12 +6563,12 @@ function findWorkspaceManifests(rootPath) {
6275
6563
  function walk(dir) {
6276
6564
  let entries;
6277
6565
  try {
6278
- entries = fs11__default.readdirSync(dir, { withFileTypes: true });
6566
+ entries = fs12__default.readdirSync(dir, { withFileTypes: true });
6279
6567
  } catch {
6280
6568
  return;
6281
6569
  }
6282
6570
  for (const entry of entries) {
6283
- const full = path13__default.join(dir, entry.name);
6571
+ const full = path14__default.join(dir, entry.name);
6284
6572
  if (entry.isDirectory()) {
6285
6573
  if (!SKIP_DIRS.has(entry.name)) walk(full);
6286
6574
  } else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
@@ -6343,14 +6631,14 @@ function validateWorkspaceAssets(parsed, relPath) {
6343
6631
  return errors;
6344
6632
  }
6345
6633
  function validateWorkspaceManifests(rootPath) {
6346
- const absRoot = path13__default.resolve(rootPath);
6634
+ const absRoot = path14__default.resolve(rootPath);
6347
6635
  const files = findWorkspaceManifests(absRoot);
6348
6636
  let errors = 0;
6349
6637
  for (const file of files) {
6350
- const relPath = path13__default.relative(absRoot, file);
6638
+ const relPath = path14__default.relative(absRoot, file);
6351
6639
  let parsed;
6352
6640
  try {
6353
- parsed = parse(fs11__default.readFileSync(file, "utf-8")) ?? {};
6641
+ parsed = parse(fs12__default.readFileSync(file, "utf-8")) ?? {};
6354
6642
  } catch (e) {
6355
6643
  logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
6356
6644
  errors++;
@@ -6364,34 +6652,34 @@ function validateWorkspaceManifests(rootPath) {
6364
6652
  var EXCLUDED_DOMAINS = /* @__PURE__ */ new Set(["skaileup-shared", "external", "docs"]);
6365
6653
  function collectAssetVersions() {
6366
6654
  const assets = [];
6367
- if (!fs11__default.existsSync(AI_RESOURCES)) return assets;
6368
- const domains = fs11__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory() && !EXCLUDED_DOMAINS.has(d.name));
6655
+ if (!fs12__default.existsSync(AI_RESOURCES)) return assets;
6656
+ const domains = fs12__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory() && !EXCLUDED_DOMAINS.has(d.name));
6369
6657
  for (const d of domains) {
6370
- const domainDir = path13__default.join(AI_RESOURCES, d.name);
6371
- const skillsDir = path13__default.join(domainDir, "skills");
6372
- if (fs11__default.existsSync(skillsDir)) {
6658
+ const domainDir = path14__default.join(AI_RESOURCES, d.name);
6659
+ const skillsDir = path14__default.join(domainDir, "skills");
6660
+ if (fs12__default.existsSync(skillsDir)) {
6373
6661
  collectSkillVersions(skillsDir, d.name, assets);
6374
6662
  }
6375
- const agentsDir = path13__default.join(domainDir, "agents");
6376
- if (fs11__default.existsSync(agentsDir)) {
6663
+ const agentsDir = path14__default.join(domainDir, "agents");
6664
+ if (fs12__default.existsSync(agentsDir)) {
6377
6665
  collectAgentVersions(agentsDir, d.name, assets);
6378
6666
  }
6379
- const flowsDir = path13__default.join(domainDir, "flows");
6380
- if (fs11__default.existsSync(flowsDir)) {
6667
+ const flowsDir = path14__default.join(domainDir, "flows");
6668
+ if (fs12__default.existsSync(flowsDir)) {
6381
6669
  collectFlowVersions(flowsDir, d.name, assets);
6382
6670
  }
6383
- const promptsDir = path13__default.join(domainDir, "prompts");
6384
- if (fs11__default.existsSync(promptsDir)) {
6671
+ const promptsDir = path14__default.join(domainDir, "prompts");
6672
+ if (fs12__default.existsSync(promptsDir)) {
6385
6673
  collectPromptVersions(promptsDir, d.name, assets);
6386
6674
  }
6387
6675
  }
6388
6676
  return assets;
6389
6677
  }
6390
6678
  function collectFlowVersions(dir, domain, out) {
6391
- for (const f of fs11__default.readdirSync(dir)) {
6679
+ for (const f of fs12__default.readdirSync(dir)) {
6392
6680
  if (!f.endsWith(".flow.yaml")) continue;
6393
- const fp = path13__default.join(dir, f);
6394
- const content = fs11__default.readFileSync(fp, "utf-8");
6681
+ const fp = path14__default.join(dir, f);
6682
+ const content = fs12__default.readFileSync(fp, "utf-8");
6395
6683
  const parsed = parse(content);
6396
6684
  out.push({
6397
6685
  kind: "flow",
@@ -6403,10 +6691,10 @@ function collectFlowVersions(dir, domain, out) {
6403
6691
  }
6404
6692
  }
6405
6693
  function collectPromptVersions(dir, domain, out) {
6406
- for (const f of fs11__default.readdirSync(dir)) {
6694
+ for (const f of fs12__default.readdirSync(dir)) {
6407
6695
  if (!f.endsWith(".prompt.md")) continue;
6408
- const fp = path13__default.join(dir, f);
6409
- const content = fs11__default.readFileSync(fp, "utf-8");
6696
+ const fp = path14__default.join(dir, f);
6697
+ const content = fs12__default.readFileSync(fp, "utf-8");
6410
6698
  const fm = parseSkillFrontmatter(content);
6411
6699
  out.push({
6412
6700
  kind: "prompt",
@@ -6418,12 +6706,12 @@ function collectPromptVersions(dir, domain, out) {
6418
6706
  }
6419
6707
  }
6420
6708
  function collectSkillVersions(dir, domain, out) {
6421
- for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
6709
+ for (const entry of fs12__default.readdirSync(dir, { withFileTypes: true })) {
6422
6710
  if (!entry.isDirectory()) continue;
6423
- const full = path13__default.join(dir, entry.name);
6424
- const skillMd = path13__default.join(full, "SKILL.md");
6425
- if (fs11__default.existsSync(skillMd)) {
6426
- const content = fs11__default.readFileSync(skillMd, "utf-8");
6711
+ const full = path14__default.join(dir, entry.name);
6712
+ const skillMd = path14__default.join(full, "SKILL.md");
6713
+ if (fs12__default.existsSync(skillMd)) {
6714
+ const content = fs12__default.readFileSync(skillMd, "utf-8");
6427
6715
  const fm = parseSkillFrontmatter(content);
6428
6716
  out.push({
6429
6717
  kind: "skill",
@@ -6438,11 +6726,11 @@ function collectSkillVersions(dir, domain, out) {
6438
6726
  }
6439
6727
  }
6440
6728
  function collectAgentVersions(dir, domain, out) {
6441
- for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
6729
+ for (const entry of fs12__default.readdirSync(dir, { withFileTypes: true })) {
6442
6730
  if (!entry.isDirectory()) continue;
6443
- const agentYaml = path13__default.join(dir, entry.name, "agent.yaml");
6444
- if (!fs11__default.existsSync(agentYaml)) continue;
6445
- const content = fs11__default.readFileSync(agentYaml, "utf-8");
6731
+ const agentYaml = path14__default.join(dir, entry.name, "agent.yaml");
6732
+ if (!fs12__default.existsSync(agentYaml)) continue;
6733
+ const content = fs12__default.readFileSync(agentYaml, "utf-8");
6446
6734
  const parsed = parse(content);
6447
6735
  out.push({
6448
6736
  kind: "agent",
@@ -6473,7 +6761,7 @@ function filterToChangedAssets(assets) {
6473
6761
  encoding: "utf-8"
6474
6762
  });
6475
6763
  const changedFiles = new Set(
6476
- diffOutput.trim().split("\n").filter(Boolean).map((f) => path13__default.resolve(AI_RESOURCES, f))
6764
+ diffOutput.trim().split("\n").filter(Boolean).map((f) => path14__default.resolve(AI_RESOURCES, f))
6477
6765
  );
6478
6766
  return assets.filter((a) => changedFiles.has(a.filePath));
6479
6767
  } catch {
@@ -6499,7 +6787,7 @@ function checkVersionBumps(assets) {
6499
6787
  let warnings = 0;
6500
6788
  for (const a of assets) {
6501
6789
  if (!a.version) continue;
6502
- const relPath = path13__default.relative(AI_RESOURCES, a.filePath);
6790
+ const relPath = path14__default.relative(AI_RESOURCES, a.filePath);
6503
6791
  try {
6504
6792
  const headContent = execSync(`git show HEAD:${relPath}`, {
6505
6793
  cwd: AI_RESOURCES,
@@ -6525,7 +6813,7 @@ function checkFlowVersionPins(assets) {
6525
6813
  }
6526
6814
  let errors = 0;
6527
6815
  for (const f of flows) {
6528
- const content = fs11__default.readFileSync(f.filePath, "utf-8");
6816
+ const content = fs12__default.readFileSync(f.filePath, "utf-8");
6529
6817
  const parsed = parse(content);
6530
6818
  const nodes = (parsed?.nodes ?? []).filter((n) => n.type === "skill" && n.data?.version).map((n) => ({
6531
6819
  nodeId: n.id,
@@ -6572,7 +6860,7 @@ function makeValidateCommand() {
6572
6860
  "Validate asset manifests, versions, and changelogs"
6573
6861
  );
6574
6862
  cmd.argument("[path]", "Path to asset repo or directory to validate", ".").action((targetPath) => {
6575
- const absPath = path13__default.resolve(targetPath);
6863
+ const absPath = path14__default.resolve(targetPath);
6576
6864
  logInfo(`Validating manifests in ${absPath}`);
6577
6865
  const { total, errors } = validateManifests(absPath);
6578
6866
  const ws = validateWorkspaceManifests(absPath);
@@ -6618,7 +6906,7 @@ function makeValidateCommand() {
6618
6906
  let errors = 0;
6619
6907
  for (const domain of modifiedDomains) {
6620
6908
  const changelogModified = modifiedFiles.some(
6621
- (f) => f === `${domain}/CHANGELOG.md` || f === path13__default.join(domain, "CHANGELOG.md")
6909
+ (f) => f === `${domain}/CHANGELOG.md` || f === path14__default.join(domain, "CHANGELOG.md")
6622
6910
  );
6623
6911
  if (changelogModified) {
6624
6912
  logOk(`${domain}/CHANGELOG.md updated`);
@@ -6700,7 +6988,7 @@ function makeVerifyCommand() {
6700
6988
  }
6701
6989
  function makeWhyCommand() {
6702
6990
  return new Command("why").description("Show why an asset is installed (dependency chain)").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
6703
- const am2 = new AssetManager({ projectDir: path13__default.resolve(opts.projectDir) });
6991
+ const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
6704
6992
  const chain = am2.why(ref);
6705
6993
  if (chain.length === 0) {
6706
6994
  logErr(`${ref} not found in lock file. Run \`skaile install\` first.`);
@@ -6721,7 +7009,7 @@ function makeWhyCommand() {
6721
7009
  var _defaultFormatHelp = Help.prototype.formatHelp;
6722
7010
  var pkg = JSON.parse(
6723
7011
  readFileSync(
6724
- path13__default.resolve(path13__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
7012
+ path14__default.resolve(path14__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
6725
7013
  "utf-8"
6726
7014
  )
6727
7015
  );
@@ -6842,7 +7130,7 @@ program.command("init [project-dir]").description("Initialize a project director
6842
7130
  (projectDir, opts) => runInit(projectDir, opts)
6843
7131
  );
6844
7132
  async function runInit(projectDir, opts) {
6845
- const { mkdirSync: mkdirSync3, writeFileSync: writeFileSync2 } = await import('fs');
7133
+ const { mkdirSync: mkdirSync4, writeFileSync: writeFileSync4 } = await import('fs');
6846
7134
  const { stringify } = await import('yaml');
6847
7135
  const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
6848
7136
  const backend = opts.backend;
@@ -6851,33 +7139,33 @@ async function runInit(projectDir, opts) {
6851
7139
  process.exitCode = 1;
6852
7140
  return;
6853
7141
  }
6854
- const resolved = path13__default.resolve(projectDir ?? ".");
6855
- const projectName = path13__default.basename(resolved);
7142
+ const resolved = path14__default.resolve(projectDir ?? ".");
7143
+ const projectName = path14__default.basename(resolved);
6856
7144
  const created = [];
6857
- const { existsSync: existsSync13 } = await import('fs');
6858
- if (!existsSync13(resolved)) {
6859
- mkdirSync3(resolved, { recursive: true });
7145
+ const { existsSync: existsSync14 } = await import('fs');
7146
+ if (!existsSync14(resolved)) {
7147
+ mkdirSync4(resolved, { recursive: true });
6860
7148
  created.push(".");
6861
7149
  }
6862
- const skaileDir = path13__default.join(resolved, ".skaile");
6863
- if (!existsSync13(skaileDir)) {
6864
- mkdirSync3(path13__default.join(skaileDir, "sessions"), { recursive: true });
7150
+ const skaileDir = path14__default.join(resolved, ".skaile");
7151
+ if (!existsSync14(skaileDir)) {
7152
+ mkdirSync4(path14__default.join(skaileDir, "sessions"), { recursive: true });
6865
7153
  created.push(".skaile/");
6866
7154
  }
6867
- const settingsPath = path13__default.join(skaileDir, "settings.json");
6868
- if (!existsSync13(settingsPath)) {
6869
- writeFileSync2(settingsPath, "{}\n");
7155
+ const settingsPath = path14__default.join(skaileDir, "settings.json");
7156
+ if (!existsSync14(settingsPath)) {
7157
+ writeFileSync4(settingsPath, "{}\n");
6870
7158
  created.push(".skaile/settings.json");
6871
7159
  }
6872
- const wsConfigPath = path13__default.join(resolved, "skaile.yaml");
6873
- if (!existsSync13(wsConfigPath)) {
6874
- writeFileSync2(wsConfigPath, stringify(buildInitWorkspaceConfig(projectName, backend)));
7160
+ const wsConfigPath = path14__default.join(resolved, "skaile.yaml");
7161
+ if (!existsSync14(wsConfigPath)) {
7162
+ writeFileSync4(wsConfigPath, stringify(buildInitWorkspaceConfig(projectName, backend)));
6875
7163
  created.push("skaile.yaml");
6876
7164
  }
6877
7165
  for (const dir of new Set(Object.values(DRIVER_TARGETS[backend].local))) {
6878
- const full = path13__default.join(resolved, dir);
6879
- if (!existsSync13(full)) {
6880
- mkdirSync3(full, { recursive: true });
7166
+ const full = path14__default.join(resolved, dir);
7167
+ if (!existsSync14(full)) {
7168
+ mkdirSync4(full, { recursive: true });
6881
7169
  created.push(`${dir}/`);
6882
7170
  }
6883
7171
  }
@@ -6907,8 +7195,8 @@ function buildInitWorkspaceConfig(projectName, backend) {
6907
7195
  }
6908
7196
  async function initGitScaffold(resolved, created) {
6909
7197
  const { execSync: execSync3 } = await import('child_process');
6910
- const { existsSync: existsSync13, readFileSync: readFileSync6, writeFileSync: writeFileSync2 } = await import('fs');
6911
- const gitignorePath = path13__default.join(resolved, ".gitignore");
7198
+ const { existsSync: existsSync14, readFileSync: readFileSync8, writeFileSync: writeFileSync4 } = await import('fs');
7199
+ const gitignorePath = path14__default.join(resolved, ".gitignore");
6912
7200
  const entries = [
6913
7201
  "node_modules/",
6914
7202
  ".skaile/sessions/",
@@ -6917,16 +7205,16 @@ async function initGitScaffold(resolved, created) {
6917
7205
  ".env",
6918
7206
  ".env.local"
6919
7207
  ];
6920
- const existing = existsSync13(gitignorePath) ? readFileSync6(gitignorePath, "utf-8") : "";
7208
+ const existing = existsSync14(gitignorePath) ? readFileSync8(gitignorePath, "utf-8") : "";
6921
7209
  const have = new Set(existing.split("\n").map((l) => l.trim()));
6922
7210
  const append = entries.filter((e) => !have.has(e));
6923
7211
  if (append.length > 0) {
6924
7212
  const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
6925
- writeFileSync2(gitignorePath, `${existing + prefix}${append.join("\n")}
7213
+ writeFileSync4(gitignorePath, `${existing + prefix}${append.join("\n")}
6926
7214
  `);
6927
7215
  if (!existing) created.push(".gitignore");
6928
7216
  }
6929
- if (!existsSync13(path13__default.join(resolved, ".git"))) {
7217
+ if (!existsSync14(path14__default.join(resolved, ".git"))) {
6930
7218
  try {
6931
7219
  execSync3("git init", { cwd: resolved, stdio: "pipe" });
6932
7220
  created.push(".git/");
@@ -6938,10 +7226,10 @@ async function initGitScaffold(resolved, created) {
6938
7226
  }
6939
7227
  async function bootstrapUserConfig() {
6940
7228
  try {
6941
- const fs12 = await import('fs');
7229
+ const fs13 = await import('fs');
6942
7230
  const { userConfigPath, saveConfig, getConfigDefaults } = await import('../library/index.js');
6943
7231
  const userCfgPath = userConfigPath();
6944
- if (!fs12.existsSync(userCfgPath)) {
7232
+ if (!fs13.existsSync(userCfgPath)) {
6945
7233
  const defaults = getConfigDefaults();
6946
7234
  saveConfig(userCfgPath, {
6947
7235
  catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
@@ -6972,7 +7260,7 @@ function printInitSummary(resolved, projectDir, created) {
6972
7260
  logOk(`Initialized project at ${S.heading(resolved)}`);
6973
7261
  console.log();
6974
7262
  console.log(S.heading(" Next steps:"));
6975
- const isCurrentDir = resolved === path13__default.resolve(".");
7263
+ const isCurrentDir = resolved === path14__default.resolve(".");
6976
7264
  let step = 1;
6977
7265
  if (!isCurrentDir) {
6978
7266
  console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);