@skill-map/cli 0.11.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +325 -118
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.js +1 -1
- package/dist/kernel/index.js.map +1 -1
- package/dist/ui/chunk-6EW3JAB6.js +38 -0
- package/dist/ui/chunk-FWFBO7KA.js +37 -0
- package/dist/ui/chunk-J3FDTSKA.js +1 -0
- package/dist/ui/chunk-MFQFSZZ5.js +54 -0
- package/dist/ui/chunk-N2C45VIA.js +2 -0
- package/dist/ui/chunk-NUUSKOAE.js +971 -0
- package/dist/ui/chunk-Q7L6LLAK.js +1 -0
- package/dist/ui/chunk-RN7YDIJP.js +210 -0
- package/dist/ui/chunk-SKGGJQY3.js +819 -0
- package/dist/ui/chunk-STE4Z72W.js +16 -0
- package/dist/ui/chunk-VYSE3ZFQ.js +2403 -0
- package/dist/ui/chunk-ZTVMUEY2.js +114 -0
- package/dist/ui/favicon.ico +0 -0
- package/dist/ui/index.html +19 -0
- package/dist/ui/main-7S2SK7UD.js +1 -0
- package/dist/ui/media/primeicons-4GST5W3O.woff2 +0 -0
- package/dist/ui/media/primeicons-DHQU4SEP.svg +345 -0
- package/dist/ui/media/primeicons-GEFHGEHP.ttf +0 -0
- package/dist/ui/media/primeicons-P53SE5CV.woff +0 -0
- package/dist/ui/media/primeicons-RSSEDYLY.eot +0 -0
- package/dist/ui/styles-TCK5JUQE.css +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# skill-map
|
|
2
2
|
|
|
3
|
-
Map, inspect, and manage collections of interrelated Markdown files — skills, agents, commands, hooks, and notes that compose AI-agent ecosystems (Claude Code, Codex, Gemini, Copilot,
|
|
3
|
+
Map, inspect, and manage collections of interrelated Markdown files — skills, agents, commands, hooks, and notes that compose AI-agent ecosystems (Claude Code, Codex, Gemini, Copilot, docs sites).
|
|
4
4
|
|
|
5
5
|
**Status**: pre-1.0, active development. Steps 0a–9 are complete (spec, kernel, plugin loader, full CLI surface, plugin author UX). Step 14 (Full Web UI) is in progress with sub-steps 14.1–14.4 closed (Hono BFF + REST + WebSocket broadcaster + reactive UI); 14.5–14.7 (polish + bundle budgets + responsive scope) still pending. The full deterministic scan, check, history, orphans, plugin authoring, and `sm serve` are live; the optional LLM layer (Phase B / `v0.8.0`) lands after Step 14 closes. See [`ROADMAP.md`](../ROADMAP.md) for the canonical completeness marker and full execution plan. Releases follow the standard changeset flow.
|
|
6
6
|
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// cli/entry.ts
|
|
2
|
+
import { existsSync as existsSync19 } from "fs";
|
|
2
3
|
import { Builtins, Cli as Cli2 } from "clipanion";
|
|
3
4
|
|
|
4
5
|
// kernel/adapters/silent-logger.ts
|
|
@@ -28,6 +29,41 @@ function configureLogger(impl) {
|
|
|
28
29
|
active = impl;
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
// kernel/util/tx.ts
|
|
33
|
+
var TOKEN_RE = /\{\{\s*([A-Za-z][A-Za-z0-9_]*)\s*\}\}/g;
|
|
34
|
+
function tx(template, vars = {}) {
|
|
35
|
+
return template.replace(TOKEN_RE, (_match, name) => {
|
|
36
|
+
if (!Object.prototype.hasOwnProperty.call(vars, name)) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`tx: missing variable "${name}" for template "${template.slice(0, 80)}${template.length > 80 ? "\u2026" : ""}"`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const value = vars[name];
|
|
42
|
+
if (value === null || value === void 0) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`tx: variable "${name}" is null/undefined for template "${template.slice(0, 80)}${template.length > 80 ? "\u2026" : ""}"`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return String(value);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// cli/i18n/entry.texts.ts
|
|
52
|
+
var ENTRY_TEXTS = {
|
|
53
|
+
bareNoProject: 'No skill-map project found in {{cwd}}.\nRun "sm init" to bootstrap one, or "sm --help" to see all commands.\n',
|
|
54
|
+
parseErrorHeadline: "sm: {{message}}",
|
|
55
|
+
parseErrorUnknownOption: "unknown option '{{name}}'",
|
|
56
|
+
parseErrorUnknownOptionForVerb: "{{verb}}: unknown option '{{name}}'",
|
|
57
|
+
parseErrorUnknownCommand: "unknown command '{{name}}'",
|
|
58
|
+
parseErrorIncompleteCommand: "incomplete command '{{name}}'",
|
|
59
|
+
parseErrorSubcommandList: "Available subcommands: {{suggestions}}.",
|
|
60
|
+
parseErrorVerbUsage: "{{verb}}: {{message}}",
|
|
61
|
+
parseErrorFlagSuggestion: "Did you mean '{{suggestion}}'?",
|
|
62
|
+
parseErrorVerbSuggestion: "Did you mean {{suggestions}}?",
|
|
63
|
+
parseErrorVerbHelpHint: "Run 'sm help {{verb}}' for usage.",
|
|
64
|
+
parseErrorFooter: "Run 'sm help' to see the full command list."
|
|
65
|
+
};
|
|
66
|
+
|
|
31
67
|
// kernel/ports/logger.ts
|
|
32
68
|
var LOG_LEVELS = [
|
|
33
69
|
"trace",
|
|
@@ -65,25 +101,6 @@ function sanitizeForTerminal(text) {
|
|
|
65
101
|
return text.replace(ANSI_ESCAPE_RE, "").replace(C0_CONTROL_RE, "");
|
|
66
102
|
}
|
|
67
103
|
|
|
68
|
-
// kernel/util/tx.ts
|
|
69
|
-
var TOKEN_RE = /\{\{\s*([A-Za-z][A-Za-z0-9_]*)\s*\}\}/g;
|
|
70
|
-
function tx(template, vars = {}) {
|
|
71
|
-
return template.replace(TOKEN_RE, (_match, name) => {
|
|
72
|
-
if (!Object.prototype.hasOwnProperty.call(vars, name)) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
`tx: missing variable "${name}" for template "${template.slice(0, 80)}${template.length > 80 ? "\u2026" : ""}"`
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
const value = vars[name];
|
|
78
|
-
if (value === null || value === void 0) {
|
|
79
|
-
throw new Error(
|
|
80
|
-
`tx: variable "${name}" is null/undefined for template "${template.slice(0, 80)}${template.length > 80 ? "\u2026" : ""}"`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
return String(value);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
104
|
// cli/i18n/logger.texts.ts
|
|
88
105
|
var LOGGER_TEXTS = {
|
|
89
106
|
invalidLevel: 'invalid log level "{{value}}" (expected one of: {{allowed}})\n'
|
|
@@ -179,6 +196,224 @@ function extractLogLevelFlag(argv) {
|
|
|
179
196
|
}
|
|
180
197
|
var LOGGER_ENV_VAR = ENV_VAR;
|
|
181
198
|
|
|
199
|
+
// cli/util/db-path.ts
|
|
200
|
+
import { existsSync } from "fs";
|
|
201
|
+
import { join, resolve } from "path";
|
|
202
|
+
|
|
203
|
+
// cli/i18n/util.texts.ts
|
|
204
|
+
var UTIL_TEXTS = {
|
|
205
|
+
// db-path.ts
|
|
206
|
+
dbNotFound: "DB not found at {{path}}; run `sm scan` first.\n",
|
|
207
|
+
// elapsed.ts
|
|
208
|
+
doneIn: "done in {{elapsed}}\n",
|
|
209
|
+
// confirm.ts (default-no prompt suffix)
|
|
210
|
+
confirmPromptSuffix: " [y/N] ",
|
|
211
|
+
/**
|
|
212
|
+
* Regex source matching affirmative answers in `confirm()`. Compiled
|
|
213
|
+
* with the `i` flag in the helper. Pre-i18n today the pattern is
|
|
214
|
+
* English-only; when a non-English locale lands the catalog grows
|
|
215
|
+
* alternations (e.g. `^(y(es)?|s(í|i)?)$`).
|
|
216
|
+
*/
|
|
217
|
+
confirmYesPatternSource: "^y(es)?$"
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// cli/util/db-path.ts
|
|
221
|
+
var SKILL_MAP_DIR = ".skill-map";
|
|
222
|
+
var DB_FILENAME = "skill-map.db";
|
|
223
|
+
var JOBS_DIRNAME = "jobs";
|
|
224
|
+
var PLUGINS_DIRNAME = "plugins";
|
|
225
|
+
var SETTINGS_FILENAME = "settings.json";
|
|
226
|
+
var LOCAL_SETTINGS_FILENAME = "settings.local.json";
|
|
227
|
+
var IGNORE_FILENAME = ".skill-mapignore";
|
|
228
|
+
var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
|
|
229
|
+
var GITIGNORE_ENTRIES = [
|
|
230
|
+
`${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME}`,
|
|
231
|
+
`${SKILL_MAP_DIR}/${DB_FILENAME}`
|
|
232
|
+
];
|
|
233
|
+
function resolveDbPath(options) {
|
|
234
|
+
if (options.db) return resolve(options.db);
|
|
235
|
+
if (options.global) return join(options.homedir, DEFAULT_DB_REL);
|
|
236
|
+
return resolve(options.cwd, DEFAULT_DB_REL);
|
|
237
|
+
}
|
|
238
|
+
function defaultProjectDbPath(ctx) {
|
|
239
|
+
return resolve(ctx.cwd, DEFAULT_DB_REL);
|
|
240
|
+
}
|
|
241
|
+
function defaultProjectJobsDir(ctx) {
|
|
242
|
+
return resolve(ctx.cwd, SKILL_MAP_DIR, JOBS_DIRNAME);
|
|
243
|
+
}
|
|
244
|
+
function defaultProjectPluginsDir(ctx) {
|
|
245
|
+
return resolve(ctx.cwd, SKILL_MAP_DIR, PLUGINS_DIRNAME);
|
|
246
|
+
}
|
|
247
|
+
function defaultUserPluginsDir(ctx) {
|
|
248
|
+
return join(ctx.homedir, SKILL_MAP_DIR, PLUGINS_DIRNAME);
|
|
249
|
+
}
|
|
250
|
+
function defaultDbPath(scopeRoot) {
|
|
251
|
+
return join(scopeRoot, SKILL_MAP_DIR, DB_FILENAME);
|
|
252
|
+
}
|
|
253
|
+
function defaultSettingsPath(scopeRoot) {
|
|
254
|
+
return join(scopeRoot, SKILL_MAP_DIR, SETTINGS_FILENAME);
|
|
255
|
+
}
|
|
256
|
+
function defaultLocalSettingsPath(scopeRoot) {
|
|
257
|
+
return join(scopeRoot, SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME);
|
|
258
|
+
}
|
|
259
|
+
function defaultIgnoreFilePath(scopeRoot) {
|
|
260
|
+
return join(scopeRoot, IGNORE_FILENAME);
|
|
261
|
+
}
|
|
262
|
+
function assertDbExists(path, stderr) {
|
|
263
|
+
if (path === ":memory:" || existsSync(path)) return true;
|
|
264
|
+
stderr.write(tx(UTIL_TEXTS.dbNotFound, { path }));
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// cli/util/exit-codes.ts
|
|
269
|
+
var ExitCode = {
|
|
270
|
+
Ok: 0,
|
|
271
|
+
Issues: 1,
|
|
272
|
+
Error: 2,
|
|
273
|
+
Duplicate: 3,
|
|
274
|
+
NonceMismatch: 4,
|
|
275
|
+
NotFound: 5
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// cli/util/parse-error.ts
|
|
279
|
+
function isClipanionParseError(err) {
|
|
280
|
+
if (!err || typeof err !== "object") return false;
|
|
281
|
+
const e = err;
|
|
282
|
+
if (typeof e.name !== "string") return false;
|
|
283
|
+
if (!Array.isArray(e.input)) return false;
|
|
284
|
+
return e.name === "UnknownSyntaxError" || e.name === "AmbiguousSyntaxError";
|
|
285
|
+
}
|
|
286
|
+
function formatParseError(params) {
|
|
287
|
+
const { args: args2, verbPaths, error } = params;
|
|
288
|
+
const firstToken = args2[0] ?? "";
|
|
289
|
+
const offendingFlag = extractOffendingFlag(error.message);
|
|
290
|
+
if (offendingFlag !== null) {
|
|
291
|
+
const verbPrefix2 = matchedVerbPrefix(args2, verbPaths);
|
|
292
|
+
const suggestion2 = suggestFlag(offendingFlag);
|
|
293
|
+
const headline = verbPrefix2 ? tx(ENTRY_TEXTS.parseErrorUnknownOptionForVerb, { verb: verbPrefix2, name: offendingFlag }) : tx(ENTRY_TEXTS.parseErrorUnknownOption, { name: offendingFlag });
|
|
294
|
+
return renderError(headline, suggestion2);
|
|
295
|
+
}
|
|
296
|
+
if (firstToken === "") {
|
|
297
|
+
return renderError(error.message.trim(), null);
|
|
298
|
+
}
|
|
299
|
+
const verbPrefix = matchedVerbPrefix(args2, verbPaths);
|
|
300
|
+
if (verbPrefix) {
|
|
301
|
+
const headline = tx(ENTRY_TEXTS.parseErrorVerbUsage, { verb: verbPrefix, message: error.message.trim() });
|
|
302
|
+
return renderError(headline, tx(ENTRY_TEXTS.parseErrorVerbHelpHint, { verb: verbPrefix }));
|
|
303
|
+
}
|
|
304
|
+
const subcommands = subcommandsUnder(firstToken, verbPaths);
|
|
305
|
+
if (subcommands.length > 0) {
|
|
306
|
+
const headline = tx(ENTRY_TEXTS.parseErrorIncompleteCommand, { name: firstToken });
|
|
307
|
+
const suggestion2 = tx(ENTRY_TEXTS.parseErrorSubcommandList, {
|
|
308
|
+
suggestions: formatSuggestionList(subcommands)
|
|
309
|
+
});
|
|
310
|
+
return renderError(headline, suggestion2);
|
|
311
|
+
}
|
|
312
|
+
const candidates = closestVerbs(firstToken, verbPaths);
|
|
313
|
+
const suggestion = candidates.length > 0 ? tx(ENTRY_TEXTS.parseErrorVerbSuggestion, { suggestions: formatSuggestionList(candidates) }) : null;
|
|
314
|
+
return renderError(tx(ENTRY_TEXTS.parseErrorUnknownCommand, { name: firstToken }), suggestion);
|
|
315
|
+
}
|
|
316
|
+
function subcommandsUnder(namespace, verbPaths) {
|
|
317
|
+
const matches = verbPaths.filter((path) => path.length >= 2 && path[0] === namespace).map((path) => path.join(" ")).sort();
|
|
318
|
+
return matches.slice(0, 3);
|
|
319
|
+
}
|
|
320
|
+
function matchedVerbPrefix(args2, verbPaths) {
|
|
321
|
+
const leading = [];
|
|
322
|
+
for (const tok of args2) {
|
|
323
|
+
if (tok.startsWith("-")) break;
|
|
324
|
+
leading.push(tok);
|
|
325
|
+
}
|
|
326
|
+
if (leading.length === 0) return "";
|
|
327
|
+
let best = [];
|
|
328
|
+
for (const path of verbPaths) {
|
|
329
|
+
if (path.length > leading.length) continue;
|
|
330
|
+
const matches = path.every((tok, i) => leading[i] === tok);
|
|
331
|
+
if (matches && path.length > best.length) best = path;
|
|
332
|
+
}
|
|
333
|
+
return best.join(" ");
|
|
334
|
+
}
|
|
335
|
+
function renderError(headline, suggestion) {
|
|
336
|
+
const lines = [tx(ENTRY_TEXTS.parseErrorHeadline, { message: headline })];
|
|
337
|
+
if (suggestion) lines.push(suggestion);
|
|
338
|
+
lines.push(ENTRY_TEXTS.parseErrorFooter);
|
|
339
|
+
return lines.join("\n") + "\n";
|
|
340
|
+
}
|
|
341
|
+
function extractOffendingFlag(message) {
|
|
342
|
+
const match = /Unsupported option name \("([^"]+)"\)/.exec(message);
|
|
343
|
+
return match ? match[1] : null;
|
|
344
|
+
}
|
|
345
|
+
function suggestFlag(token) {
|
|
346
|
+
if (!token.startsWith("-")) return null;
|
|
347
|
+
if (token.startsWith("--")) return null;
|
|
348
|
+
if (token.length <= 2) return null;
|
|
349
|
+
const longForm = "-" + token;
|
|
350
|
+
return tx(ENTRY_TEXTS.parseErrorFlagSuggestion, { suggestion: longForm });
|
|
351
|
+
}
|
|
352
|
+
function editDistance(a, b, max) {
|
|
353
|
+
if (a === b) return 0;
|
|
354
|
+
if (Math.abs(a.length - b.length) > max) return max + 1;
|
|
355
|
+
const m = a.length;
|
|
356
|
+
const n = b.length;
|
|
357
|
+
if (m === 0) return n;
|
|
358
|
+
if (n === 0) return m;
|
|
359
|
+
let prev = Array.from({ length: n + 1 }, (_, i) => i);
|
|
360
|
+
let curr = new Array(n + 1);
|
|
361
|
+
for (let i = 1; i <= m; i++) {
|
|
362
|
+
const rowMin = fillEditRow({ a, b, i, prev, curr });
|
|
363
|
+
if (rowMin > max) return max + 1;
|
|
364
|
+
[prev, curr] = [curr, prev];
|
|
365
|
+
}
|
|
366
|
+
return prev[n];
|
|
367
|
+
}
|
|
368
|
+
function fillEditRow(args2) {
|
|
369
|
+
const { a, b, i, prev, curr } = args2;
|
|
370
|
+
curr[0] = i;
|
|
371
|
+
let rowMin = curr[0];
|
|
372
|
+
for (let j = 1; j < curr.length; j++) {
|
|
373
|
+
const cost = a.charCodeAt(i - 1) === b.charCodeAt(j - 1) ? 0 : 1;
|
|
374
|
+
const value = Math.min(curr[j - 1] + 1, prev[j] + 1, prev[j - 1] + cost);
|
|
375
|
+
curr[j] = value;
|
|
376
|
+
if (value < rowMin) rowMin = value;
|
|
377
|
+
}
|
|
378
|
+
return rowMin;
|
|
379
|
+
}
|
|
380
|
+
function closestVerbs(typed, verbPaths) {
|
|
381
|
+
const target = typed.toLowerCase();
|
|
382
|
+
const distanceCap = target.length <= 4 ? 2 : 3;
|
|
383
|
+
const ranked = [];
|
|
384
|
+
for (const path of verbPaths) {
|
|
385
|
+
const verb = path.join(" ");
|
|
386
|
+
const head = path[0];
|
|
387
|
+
const distHead = editDistance(target, head.toLowerCase(), distanceCap);
|
|
388
|
+
const distFull = editDistance(target, verb.replace(/\s+/g, "").toLowerCase(), distanceCap);
|
|
389
|
+
const distance = Math.min(distHead, distFull);
|
|
390
|
+
if (distance <= distanceCap) ranked.push({ verb, distance });
|
|
391
|
+
}
|
|
392
|
+
ranked.sort((a, b) => a.distance - b.distance || a.verb.localeCompare(b.verb));
|
|
393
|
+
const seen = /* @__PURE__ */ new Set();
|
|
394
|
+
const out = [];
|
|
395
|
+
for (const { verb } of ranked) {
|
|
396
|
+
const head = verb.split(" ")[0];
|
|
397
|
+
if (seen.has(head)) continue;
|
|
398
|
+
seen.add(head);
|
|
399
|
+
out.push(verb);
|
|
400
|
+
if (out.length === 3) break;
|
|
401
|
+
}
|
|
402
|
+
return out;
|
|
403
|
+
}
|
|
404
|
+
function formatSuggestionList(items) {
|
|
405
|
+
const quoted = items.map((s) => `'${s}'`);
|
|
406
|
+
if (quoted.length <= 1) return quoted[0] ?? "";
|
|
407
|
+
if (quoted.length === 2) return `${quoted[0]} or ${quoted[1]}`;
|
|
408
|
+
return `${quoted.slice(0, -1).join(", ")}, or ${quoted[quoted.length - 1]}`;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// cli/util/runtime-context.ts
|
|
412
|
+
import { homedir } from "os";
|
|
413
|
+
function defaultRuntimeContext() {
|
|
414
|
+
return { cwd: process.cwd(), homedir: homedir() };
|
|
415
|
+
}
|
|
416
|
+
|
|
182
417
|
// cli/commands/check.ts
|
|
183
418
|
import { Command as Command2, Option as Option2 } from "clipanion";
|
|
184
419
|
|
|
@@ -271,91 +506,6 @@ var CHECK_TEXTS = {
|
|
|
271
506
|
probStubAdvisoryAsync: "sm check --include-prob --async: probabilistic Rule dispatch requires the job subsystem (Step 10). Stub: skipped {{count}} probabilistic rule(s) \u2014 {{ruleIds}}. The --async flag is reserved for future encoding (returns job ids without waiting once jobs land); today it is a no-op. Deterministic rules ran as usual.\n"
|
|
272
507
|
};
|
|
273
508
|
|
|
274
|
-
// cli/util/db-path.ts
|
|
275
|
-
import { existsSync } from "fs";
|
|
276
|
-
import { join, resolve } from "path";
|
|
277
|
-
|
|
278
|
-
// cli/i18n/util.texts.ts
|
|
279
|
-
var UTIL_TEXTS = {
|
|
280
|
-
// db-path.ts
|
|
281
|
-
dbNotFound: "DB not found at {{path}}; run `sm scan` first.\n",
|
|
282
|
-
// elapsed.ts
|
|
283
|
-
doneIn: "done in {{elapsed}}\n",
|
|
284
|
-
// confirm.ts (default-no prompt suffix)
|
|
285
|
-
confirmPromptSuffix: " [y/N] ",
|
|
286
|
-
/**
|
|
287
|
-
* Regex source matching affirmative answers in `confirm()`. Compiled
|
|
288
|
-
* with the `i` flag in the helper. Pre-i18n today the pattern is
|
|
289
|
-
* English-only; when a non-English locale lands the catalog grows
|
|
290
|
-
* alternations (e.g. `^(y(es)?|s(í|i)?)$`).
|
|
291
|
-
*/
|
|
292
|
-
confirmYesPatternSource: "^y(es)?$"
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
// cli/util/db-path.ts
|
|
296
|
-
var SKILL_MAP_DIR = ".skill-map";
|
|
297
|
-
var DB_FILENAME = "skill-map.db";
|
|
298
|
-
var JOBS_DIRNAME = "jobs";
|
|
299
|
-
var PLUGINS_DIRNAME = "plugins";
|
|
300
|
-
var SETTINGS_FILENAME = "settings.json";
|
|
301
|
-
var LOCAL_SETTINGS_FILENAME = "settings.local.json";
|
|
302
|
-
var IGNORE_FILENAME = ".skill-mapignore";
|
|
303
|
-
var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
|
|
304
|
-
var GITIGNORE_ENTRIES = [
|
|
305
|
-
`${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME}`,
|
|
306
|
-
`${SKILL_MAP_DIR}/${DB_FILENAME}`
|
|
307
|
-
];
|
|
308
|
-
function resolveDbPath(options) {
|
|
309
|
-
if (options.db) return resolve(options.db);
|
|
310
|
-
if (options.global) return join(options.homedir, DEFAULT_DB_REL);
|
|
311
|
-
return resolve(options.cwd, DEFAULT_DB_REL);
|
|
312
|
-
}
|
|
313
|
-
function defaultProjectDbPath(ctx) {
|
|
314
|
-
return resolve(ctx.cwd, DEFAULT_DB_REL);
|
|
315
|
-
}
|
|
316
|
-
function defaultProjectJobsDir(ctx) {
|
|
317
|
-
return resolve(ctx.cwd, SKILL_MAP_DIR, JOBS_DIRNAME);
|
|
318
|
-
}
|
|
319
|
-
function defaultProjectPluginsDir(ctx) {
|
|
320
|
-
return resolve(ctx.cwd, SKILL_MAP_DIR, PLUGINS_DIRNAME);
|
|
321
|
-
}
|
|
322
|
-
function defaultUserPluginsDir(ctx) {
|
|
323
|
-
return join(ctx.homedir, SKILL_MAP_DIR, PLUGINS_DIRNAME);
|
|
324
|
-
}
|
|
325
|
-
function defaultDbPath(scopeRoot) {
|
|
326
|
-
return join(scopeRoot, SKILL_MAP_DIR, DB_FILENAME);
|
|
327
|
-
}
|
|
328
|
-
function defaultSettingsPath(scopeRoot) {
|
|
329
|
-
return join(scopeRoot, SKILL_MAP_DIR, SETTINGS_FILENAME);
|
|
330
|
-
}
|
|
331
|
-
function defaultLocalSettingsPath(scopeRoot) {
|
|
332
|
-
return join(scopeRoot, SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME);
|
|
333
|
-
}
|
|
334
|
-
function defaultIgnoreFilePath(scopeRoot) {
|
|
335
|
-
return join(scopeRoot, IGNORE_FILENAME);
|
|
336
|
-
}
|
|
337
|
-
function assertDbExists(path, stderr) {
|
|
338
|
-
if (path === ":memory:" || existsSync(path)) return true;
|
|
339
|
-
stderr.write(tx(UTIL_TEXTS.dbNotFound, { path }));
|
|
340
|
-
return false;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// cli/util/runtime-context.ts
|
|
344
|
-
import { homedir } from "os";
|
|
345
|
-
function defaultRuntimeContext() {
|
|
346
|
-
return { cwd: process.cwd(), homedir: homedir() };
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// cli/util/exit-codes.ts
|
|
350
|
-
var ExitCode = {
|
|
351
|
-
Ok: 0,
|
|
352
|
-
Issues: 1,
|
|
353
|
-
Error: 2,
|
|
354
|
-
Duplicate: 3,
|
|
355
|
-
NonceMismatch: 4,
|
|
356
|
-
NotFound: 5
|
|
357
|
-
};
|
|
358
|
-
|
|
359
509
|
// cli/util/plugin-runtime.ts
|
|
360
510
|
import { resolve as resolve8 } from "path";
|
|
361
511
|
|
|
@@ -7028,7 +7178,7 @@ import { Command as Command8, Option as Option8 } from "clipanion";
|
|
|
7028
7178
|
// package.json
|
|
7029
7179
|
var package_default = {
|
|
7030
7180
|
name: "@skill-map/cli",
|
|
7031
|
-
version: "0.
|
|
7181
|
+
version: "0.13.0",
|
|
7032
7182
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
7033
7183
|
license: "MIT",
|
|
7034
7184
|
type: "module",
|
|
@@ -7540,7 +7690,7 @@ function renderCompactOverview(verbs) {
|
|
|
7540
7690
|
return lines.join("\n") + "\n";
|
|
7541
7691
|
}
|
|
7542
7692
|
var RootHelpCommand = class extends Command8 {
|
|
7543
|
-
static paths = [["-h"], ["--help"]
|
|
7693
|
+
static paths = [["-h"], ["--help"]];
|
|
7544
7694
|
async execute() {
|
|
7545
7695
|
const rawDefs = this.cli.definitions();
|
|
7546
7696
|
const verbs = rawDefs.filter((d) => !isBuiltin(d)).map(normalizeDefinition).sort(byPath);
|
|
@@ -12503,7 +12653,7 @@ var PLACEHOLDER_HTML = `<!doctype html>
|
|
|
12503
12653
|
</head>
|
|
12504
12654
|
<body>
|
|
12505
12655
|
<h1>skill-map server is running</h1>
|
|
12506
|
-
<p>The UI bundle was not found.
|
|
12656
|
+
<p>The UI bundle was not found. If you installed <code>@skill-map/cli</code> from npm, this is a packaging bug \u2014 please report it. If you're developing in the monorepo, run <code>npm run build --workspace=ui</code> from the repo root and restart <code>sm serve</code> (or pass <code>--ui-dist <path></code> to point at a custom build).</p>
|
|
12507
12657
|
<p>The REST API is available at <code>/api/health</code>.</p>
|
|
12508
12658
|
</body>
|
|
12509
12659
|
</html>
|
|
@@ -13109,18 +13259,14 @@ function validateWatcherDebounce(value) {
|
|
|
13109
13259
|
// server/paths.ts
|
|
13110
13260
|
import { existsSync as existsSync17, statSync as statSync5 } from "fs";
|
|
13111
13261
|
import { dirname as dirname9, isAbsolute as isAbsolute5, join as join14, resolve as resolve19 } from "path";
|
|
13112
|
-
|
|
13262
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
13263
|
+
var DEFAULT_UI_REL = join14("ui", "dist", "ui", "browser");
|
|
13264
|
+
var PACKAGE_UI_REL = "ui";
|
|
13113
13265
|
var INDEX_HTML2 = "index.html";
|
|
13114
13266
|
function resolveDefaultUiDist(ctx) {
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
if (isUiBundleDir(candidate)) return candidate;
|
|
13119
|
-
const parent = dirname9(current);
|
|
13120
|
-
if (parent === current) return null;
|
|
13121
|
-
current = parent;
|
|
13122
|
-
}
|
|
13123
|
-
return null;
|
|
13267
|
+
const bundled = resolvePackageBundledUi();
|
|
13268
|
+
if (bundled !== null) return bundled;
|
|
13269
|
+
return walkUpForUi(ctx.cwd);
|
|
13124
13270
|
}
|
|
13125
13271
|
function resolveExplicitUiDist(ctx, raw) {
|
|
13126
13272
|
return isAbsolute5(raw) ? raw : resolve19(ctx.cwd, raw);
|
|
@@ -13134,6 +13280,39 @@ function isUiBundleDir(path) {
|
|
|
13134
13280
|
return false;
|
|
13135
13281
|
}
|
|
13136
13282
|
}
|
|
13283
|
+
function resolvePackageBundledUi() {
|
|
13284
|
+
let here;
|
|
13285
|
+
try {
|
|
13286
|
+
here = dirname9(fileURLToPath5(import.meta.url));
|
|
13287
|
+
} catch {
|
|
13288
|
+
return null;
|
|
13289
|
+
}
|
|
13290
|
+
return resolvePackageBundledUiFrom(here);
|
|
13291
|
+
}
|
|
13292
|
+
function resolvePackageBundledUiFrom(here) {
|
|
13293
|
+
let current = here;
|
|
13294
|
+
for (let i = 0; i < 8; i++) {
|
|
13295
|
+
const candidate = join14(current, PACKAGE_UI_REL);
|
|
13296
|
+
if (isUiBundleDir(candidate)) return candidate;
|
|
13297
|
+
const distHere = join14(current, "dist", PACKAGE_UI_REL);
|
|
13298
|
+
if (isUiBundleDir(distHere)) return distHere;
|
|
13299
|
+
const parent = dirname9(current);
|
|
13300
|
+
if (parent === current) return null;
|
|
13301
|
+
current = parent;
|
|
13302
|
+
}
|
|
13303
|
+
return null;
|
|
13304
|
+
}
|
|
13305
|
+
function walkUpForUi(startDir) {
|
|
13306
|
+
let current = resolve19(startDir);
|
|
13307
|
+
for (let i = 0; i < 64; i++) {
|
|
13308
|
+
const candidate = join14(current, DEFAULT_UI_REL);
|
|
13309
|
+
if (isUiBundleDir(candidate)) return candidate;
|
|
13310
|
+
const parent = dirname9(current);
|
|
13311
|
+
if (parent === current) return null;
|
|
13312
|
+
current = parent;
|
|
13313
|
+
}
|
|
13314
|
+
return null;
|
|
13315
|
+
}
|
|
13137
13316
|
|
|
13138
13317
|
// server/index.ts
|
|
13139
13318
|
async function createServer(options, extra = {}) {
|
|
@@ -14064,11 +14243,39 @@ var logLevel = resolveLogLevel({
|
|
|
14064
14243
|
errStream: process.stderr
|
|
14065
14244
|
});
|
|
14066
14245
|
configureLogger(new Logger({ level: logLevel, stream: process.stderr }));
|
|
14067
|
-
var
|
|
14246
|
+
var bareArgs = args.length === 0 ? resolveBareDefault() : null;
|
|
14247
|
+
var routedArgs = routeHelpArgs(bareArgs ?? args, cli);
|
|
14248
|
+
try {
|
|
14249
|
+
cli.process(routedArgs, {
|
|
14250
|
+
stdin: process.stdin,
|
|
14251
|
+
stdout: process.stdout,
|
|
14252
|
+
stderr: process.stderr
|
|
14253
|
+
});
|
|
14254
|
+
} catch (err) {
|
|
14255
|
+
if (isClipanionParseError(err)) {
|
|
14256
|
+
process.stderr.write(
|
|
14257
|
+
formatParseError({
|
|
14258
|
+
args: routedArgs,
|
|
14259
|
+
verbPaths: registeredVerbPaths(cli),
|
|
14260
|
+
error: err
|
|
14261
|
+
})
|
|
14262
|
+
);
|
|
14263
|
+
process.exit(ExitCode.Error);
|
|
14264
|
+
}
|
|
14265
|
+
throw err;
|
|
14266
|
+
}
|
|
14068
14267
|
var exitCode = await cli.run(routedArgs, {
|
|
14069
14268
|
stdin: process.stdin,
|
|
14070
14269
|
stdout: process.stdout,
|
|
14071
14270
|
stderr: process.stderr
|
|
14072
14271
|
});
|
|
14073
14272
|
process.exit(exitCode);
|
|
14273
|
+
function resolveBareDefault() {
|
|
14274
|
+
const ctx = defaultRuntimeContext();
|
|
14275
|
+
if (existsSync19(defaultProjectDbPath(ctx))) {
|
|
14276
|
+
return ["serve"];
|
|
14277
|
+
}
|
|
14278
|
+
process.stderr.write(tx(ENTRY_TEXTS.bareNoProject, { cwd: ctx.cwd }));
|
|
14279
|
+
process.exit(ExitCode.Error);
|
|
14280
|
+
}
|
|
14074
14281
|
//# sourceMappingURL=cli.js.map
|