@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 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, Obsidian vaults, docs sites).
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.11.1",
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"], Command8.Default];
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. Run <code>npm run build --workspace=ui</code> from the repo root, or pass <code>--ui-dist &lt;path&gt;</code>, then restart <code>sm serve</code>.</p>
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 &lt;path&gt;</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
- var DEFAULT_UI_REL = join14("ui", "dist", "browser");
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
- let current = resolve19(ctx.cwd);
13116
- for (let i = 0; i < 64; i++) {
13117
- const candidate = join14(current, DEFAULT_UI_REL);
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 routedArgs = routeHelpArgs(args, cli);
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