@shrkcrft/cli 0.1.0-alpha.8 → 0.1.0-alpha.9

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 (74) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/boundaries.command.d.ts.map +1 -1
  3. package/dist/commands/boundaries.command.js +12 -0
  4. package/dist/commands/check.command.d.ts.map +1 -1
  5. package/dist/commands/check.command.js +30 -20
  6. package/dist/commands/command-catalog.d.ts +3 -7
  7. package/dist/commands/command-catalog.d.ts.map +1 -1
  8. package/dist/commands/command-catalog.js +47 -113
  9. package/dist/commands/commands.command.d.ts.map +1 -1
  10. package/dist/commands/commands.command.js +4 -4
  11. package/dist/commands/constructs.command.d.ts.map +1 -1
  12. package/dist/commands/constructs.command.js +22 -5
  13. package/dist/commands/doctor.command.d.ts.map +1 -1
  14. package/dist/commands/doctor.command.js +9 -42
  15. package/dist/commands/export.command.d.ts.map +1 -1
  16. package/dist/commands/export.command.js +3 -76
  17. package/dist/commands/help.command.d.ts +3 -4
  18. package/dist/commands/help.command.d.ts.map +1 -1
  19. package/dist/commands/help.command.js +21 -77
  20. package/dist/commands/helper.command.js +1 -1
  21. package/dist/commands/import.command.d.ts.map +1 -1
  22. package/dist/commands/import.command.js +5 -121
  23. package/dist/commands/init.command.d.ts.map +1 -1
  24. package/dist/commands/init.command.js +16 -184
  25. package/dist/commands/mcp.command.d.ts.map +1 -1
  26. package/dist/commands/mcp.command.js +131 -2
  27. package/dist/commands/onboard.command.d.ts.map +1 -1
  28. package/dist/commands/onboard.command.js +15 -3
  29. package/dist/commands/packs-new.d.ts +1 -1
  30. package/dist/commands/packs-new.d.ts.map +1 -1
  31. package/dist/commands/packs-new.js +36 -5
  32. package/dist/commands/packs.command.d.ts.map +1 -1
  33. package/dist/commands/packs.command.js +17 -3
  34. package/dist/commands/plugin.command.d.ts +11 -0
  35. package/dist/commands/plugin.command.d.ts.map +1 -0
  36. package/dist/commands/plugin.command.js +394 -0
  37. package/dist/commands/profiles.command.js +4 -4
  38. package/dist/commands/release.command.js +13 -13
  39. package/dist/commands/review.command.d.ts.map +1 -1
  40. package/dist/commands/review.command.js +28 -2
  41. package/dist/commands/search.command.js +1 -1
  42. package/dist/commands/task-context.command.js +16 -0
  43. package/dist/export/export-formats.d.ts +1 -1
  44. package/dist/export/export-formats.d.ts.map +1 -1
  45. package/dist/export/export-formats.js +12 -139
  46. package/dist/init/init-templates.d.ts.map +1 -1
  47. package/dist/init/init-templates.js +113 -133
  48. package/dist/main.d.ts +1 -1
  49. package/dist/main.d.ts.map +1 -1
  50. package/dist/main.js +46 -117
  51. package/dist/output/failure-hints.d.ts +9 -1
  52. package/dist/output/failure-hints.d.ts.map +1 -1
  53. package/dist/output/failure-hints.js +8 -2
  54. package/dist/output/watch-loop.d.ts +1 -9
  55. package/dist/output/watch-loop.d.ts.map +1 -1
  56. package/dist/output/watch-loop.js +3 -13
  57. package/dist/schemas/json-schemas.d.ts +36 -36
  58. package/dist/schemas/json-schemas.js +36 -36
  59. package/dist/surface/about.d.ts.map +1 -1
  60. package/dist/surface/about.js +15 -37
  61. package/dist/surface/no-args-landing.d.ts.map +1 -1
  62. package/dist/surface/no-args-landing.js +13 -9
  63. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  64. package/dist/surface/surface-config-writer.js +11 -23
  65. package/package.json +25 -26
  66. package/dist/commands/diff-check.command.d.ts +0 -30
  67. package/dist/commands/diff-check.command.d.ts.map +0 -1
  68. package/dist/commands/diff-check.command.js +0 -210
  69. package/dist/export/claude-commands-export.d.ts +0 -60
  70. package/dist/export/claude-commands-export.d.ts.map +0 -1
  71. package/dist/export/claude-commands-export.js +0 -276
  72. package/dist/init/paths-advisory.d.ts +0 -20
  73. package/dist/init/paths-advisory.d.ts.map +0 -1
  74. package/dist/init/paths-advisory.js +0 -88
package/dist/main.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
2
  import { CommandRegistry, extractGlobalCwd, parseArgs, } from "./command-registry.js";
3
3
  import { initCommand } from "./commands/init.command.js";
4
4
  import { inspectCommand } from "./commands/inspect.command.js";
@@ -20,7 +20,6 @@ import { presetsListCommand, presetsGetCommand, presetsExplainCommand, presetsRe
20
20
  import { taskCommand } from "./commands/task.command.js";
21
21
  import { preflightCommand } from "./commands/preflight.command.js";
22
22
  import { checkCommand } from "./commands/check.command.js";
23
- import { diffCheckCommand } from "./commands/diff-check.command.js";
24
23
  import { driftCommand } from "./commands/drift.command.js";
25
24
  import { graphCommand } from "./commands/graph.command.js";
26
25
  import { coverageCommand } from "./commands/coverage.command.js";
@@ -57,6 +56,7 @@ import { biomeCommand } from "./commands/biome.command.js";
57
56
  import { ideCommand } from "./commands/ide.command.js";
58
57
  import { makeCommandsCommand } from "./commands/commands.command.js";
59
58
  import { safetyCommand } from "./commands/safety.command.js";
59
+ import { pluginCommand } from "./commands/plugin.command.js";
60
60
  import { profilesCommand } from "./commands/profiles.command.js";
61
61
  import { auditProjectCouplingCommand } from "./commands/audit.command.js";
62
62
  import { conventionsCommand } from "./commands/conventions.command.js";
@@ -120,6 +120,33 @@ import { buildSurfaceSummary, findCommandInSummary } from "./surface/surface-sum
120
120
  import { makeSurfaceNotEnabledError, renderSurfaceNotEnabledText, SURFACE_NOT_ENABLED_EXIT_CODE, } from "./surface/not-enabled-error.js";
121
121
  import { extractCommandPath, recordUsage, sanitizeFlagNames, } from "./usage/usage-log.js";
122
122
  import { loadProjectConfig } from '@shrkcrft/config';
123
+ import { initTokenizer } from '@shrkcrft/context';
124
+ import { statSync } from 'node:fs';
125
+ import { resolve as resolvePath } from 'node:path';
126
+ function isUsableDirectory(path) {
127
+ try {
128
+ return statSync(path).isDirectory();
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ let tokenizerInitPromise = null;
135
+ /**
136
+ * Best-effort one-time upgrade from the estimator to gpt-tokenizer.
137
+ *
138
+ * The estimator is always active before this resolves, so commands that
139
+ * race the load still get a budget-safe (if slightly off) count. Subsequent
140
+ * `countTokens` calls get the real BPE count.
141
+ */
142
+ async function ensureTokenizerReady() {
143
+ if (process.env.SHARKCRAFT_NO_REAL_TOKENIZER === '1')
144
+ return;
145
+ if (!tokenizerInitPromise) {
146
+ tokenizerInitPromise = initTokenizer().catch(() => false);
147
+ }
148
+ await tokenizerInitPromise;
149
+ }
123
150
  export function buildRegistry() {
124
151
  const registry = new CommandRegistry();
125
152
  registry.register(initCommand);
@@ -162,7 +189,6 @@ export function buildRegistry() {
162
189
  registry.register(taskCommand);
163
190
  registry.register(explainCommand);
164
191
  registry.register(checkCommand);
165
- registry.register(diffCheckCommand);
166
192
  // changed-only preflight orchestrator.
167
193
  registry.register(preflightCommand);
168
194
  registry.register(driftCommand);
@@ -193,6 +219,7 @@ export function buildRegistry() {
193
219
  registry.register(eslintCommand);
194
220
  registry.register(biomeCommand);
195
221
  registry.register(ideCommand);
222
+ registry.register(pluginCommand);
196
223
  registry.register(profilesCommand);
197
224
  registry.registerSubcommand('audit', auditProjectCouplingCommand);
198
225
  registry.register(conventionsCommand);
@@ -491,9 +518,15 @@ async function isUsageEnabled(cwd) {
491
518
  }
492
519
  }
493
520
  async function runCliInner(argv) {
521
+ await ensureTokenizerReady();
494
522
  const registry = buildRegistry();
495
523
  // Pre-parse the global --cwd so it can appear anywhere (incl. before the command).
496
524
  const { cwd: globalCwd, rest: cleanArgv } = extractGlobalCwd(argv);
525
+ if (globalCwd !== undefined && !isUsableDirectory(globalCwd)) {
526
+ process.stderr.write(`error: --cwd "${globalCwd}" is not an existing directory.\n` +
527
+ `Resolved to: ${resolvePath(globalCwd)}\n`);
528
+ return 2;
529
+ }
497
530
  const [first] = cleanArgv;
498
531
  // bare invocation lands on the curated tiered view.
499
532
  if (!first) {
@@ -506,14 +539,7 @@ async function runCliInner(argv) {
506
539
  return registry.get('help').run(parseArgs([], { globalCwd }));
507
540
  }
508
541
  if (first === '--full-help') {
509
- // Pass through `--all` (catalog dump) and `--verbose` if the user
510
- // included them after `--full-help`.
511
- const extra = [];
512
- if (argv.includes('--all'))
513
- extra.push('--all');
514
- if (argv.includes('--verbose') || argv.includes('-v'))
515
- extra.push('--verbose');
516
- return registry.get('help').run(parseArgs(['--full', ...extra], { globalCwd }));
542
+ return registry.get('help').run(parseArgs(['--full'], { globalCwd }));
517
543
  }
518
544
  if (first === '--version' || first === '-v') {
519
545
  return registry.get('version').run(parseArgs([], { globalCwd }));
@@ -557,7 +583,7 @@ async function runCliInner(argv) {
557
583
  return 2;
558
584
  }
559
585
  const attempted = probe.slice(0, 2).join(' ');
560
- process.stderr.write(`shrk doesn't have a \`${attempted}\` command.\n`);
586
+ process.stderr.write(`Unknown command: ${attempted}\n`);
561
587
  printDidYouMean(attempted);
562
588
  return 2;
563
589
  }
@@ -665,125 +691,28 @@ async function checkSurfaceGate(matchedPath, cwd) {
665
691
  return null;
666
692
  }
667
693
  }
668
- // Score thresholds for did-you-mean output. Picked from observed
669
- // scoring: 1-char-off typos score 8+ on plain commands; 3-4-char-off
670
- // near-misses score ~5; loose / token-overlap matches score 1-3.
671
- // Junk matches (frobnicate → bundle diff) can score 8 too because of
672
- // token overlap, so we sharpen by also requiring the suggestion's
673
- // command name to be reasonably close in length to the attempt.
674
- const SUGGEST_CONFIDENT_SCORE = 7;
675
- const SUGGEST_VISIBLE_SCORE = 3;
676
- function reorderCandidates(attempted, candidates) {
677
- // Stable sort: higher score first, then shorter command (more likely
678
- // canonical), then lexicographic. The base suggester returns ties in
679
- // arbitrary order — this makes the top suggestion more predictable.
680
- const ranked = [...candidates];
681
- ranked.sort((a, b) => {
682
- if (b.score !== a.score)
683
- return b.score - a.score;
684
- if (a.command.length !== b.command.length) {
685
- return a.command.length - b.command.length;
686
- }
687
- return a.command < b.command ? -1 : a.command > b.command ? 1 : 0;
688
- });
689
- return ranked;
690
- }
691
- /** Edit distance (Levenshtein). Used to gate did-you-mean confidence. */
692
- function editDistance(a, b) {
693
- const m = a.length;
694
- const n = b.length;
695
- if (m === 0)
696
- return n;
697
- if (n === 0)
698
- return m;
699
- const dp = new Array(n + 1);
700
- for (let j = 0; j <= n; j += 1)
701
- dp[j] = j;
702
- for (let i = 1; i <= m; i += 1) {
703
- let prev = dp[0];
704
- dp[0] = i;
705
- for (let j = 1; j <= n; j += 1) {
706
- const tmp = dp[j];
707
- const cost = a[i - 1] === b[j - 1] ? 0 : 1;
708
- dp[j] = Math.min(dp[j] + 1, dp[j - 1] + 1, prev + cost);
709
- prev = tmp;
710
- }
711
- }
712
- return dp[n];
713
- }
714
- /**
715
- * Suggestion is "confident" when the candidate's top token is close
716
- * to the attempt in edit-distance terms — `doctorz`→`doctor` (1 edit)
717
- * or `inspct`→`inspect` (1 edit) qualify; `frobnicate`→`bundle` (10
718
- * edits) does not, even when the suggester scores them similarly
719
- * because of incidental token overlap in descriptions.
720
- *
721
- * Threshold: edit distance ≤ max(1, attempt.length / 4) AND raw score
722
- * meets `SUGGEST_VISIBLE_SCORE`. This catches typical fingers-on-keys
723
- * typos while rejecting "you typed something totally different."
724
- */
725
- function isConfidentMatch(attempted, suggestion) {
726
- if (suggestion.score < SUGGEST_VISIBLE_SCORE)
727
- return false;
728
- const lower = attempted.toLowerCase();
729
- const head = (suggestion.command.split(/\s+/)[0] ?? suggestion.command).toLowerCase();
730
- const dist = editDistance(lower, head);
731
- const tolerance = Math.max(1, Math.floor(lower.length / 4));
732
- return dist <= tolerance;
733
- }
734
694
  function printDidYouMean(attempted) {
735
- const rawCandidates = suggestDidYouMean(COMMAND_CATALOG, [attempted], 5);
736
- const reordered = reorderCandidates(attempted, rawCandidates).filter((c) => c.score >= SUGGEST_VISIBLE_SCORE);
737
- if (reordered.length === 0) {
738
- process.stderr.write('Run `shrk help` to see the curated commands, or `shrk --full-help` for the full catalog.\n');
739
- const footer = errorFooterFor('unknown-command', { task: attempted });
740
- if (footer)
741
- process.stderr.write(renderErrorFooter(footer));
742
- return;
743
- }
744
- // Confident single-match path: surface ONE suggestion clearly.
745
- const top = reordered[0];
746
- if (isConfidentMatch(attempted, top)) {
747
- process.stderr.write(`Did you mean \`shrk ${top.command}\`?\n`);
748
- process.stderr.write(` ${top.description}\n`);
749
- // Second-tier suggestions only if they're also strong.
750
- const others = reordered.slice(1, 3).filter((c) => isConfidentMatch(attempted, c));
751
- if (others.length > 0) {
752
- process.stderr.write('Other close matches:\n');
753
- for (const c of others) {
754
- process.stderr.write(` shrk ${c.command} — ${c.description}\n`);
755
- }
756
- }
695
+ const candidates = suggestDidYouMean(COMMAND_CATALOG, [attempted], 3);
696
+ if (candidates.length === 0) {
697
+ process.stderr.write("Tip: run `shrk commands suggest \"<partial>\"` or `shrk help` to discover commands.\n");
757
698
  const footer = errorFooterFor('unknown-command', { task: attempted });
758
699
  if (footer)
759
700
  process.stderr.write(renderErrorFooter(footer));
760
701
  return;
761
702
  }
762
- // Low-confidence: show up to 3 as "closest matches", honest about
763
- // not knowing which is right.
764
- process.stderr.write('Closest matches in the catalog:\n');
765
- for (const c of reordered.slice(0, 3)) {
703
+ process.stderr.write('Did you mean:\n');
704
+ for (const c of candidates) {
766
705
  process.stderr.write(` shrk ${c.command} — ${c.description}\n`);
767
706
  }
768
- process.stderr.write("If none of those look right, run `shrk help` or `shrk \"<task>\"` to route as a free-form task.\n");
707
+ // append the standardised next-command footer so the user
708
+ // always has a deterministic exit route.
769
709
  const footer = errorFooterFor('unknown-command', { task: attempted });
770
710
  if (footer)
771
711
  process.stderr.write(renderErrorFooter(footer));
772
712
  }
773
713
  // Entry point when invoked directly.
774
- //
775
- // Bun exposes `import.meta.main`; Node does not. When Node runs the
776
- // compiled `dist/main.js` directly the path-suffix check (`main.js`)
777
- // catches it. The npm bin shim points at `shrk` so that suffix also
778
- // triggers it. Source dev under Bun still runs via `main.ts`.
779
714
  const isMain = typeof import.meta !== 'undefined' && import.meta.main === true;
780
- const entryPath = process.argv[1] ?? '';
781
- if (isMain ||
782
- entryPath.endsWith('main.ts') ||
783
- entryPath.endsWith('main.js') ||
784
- entryPath.endsWith('shrk') ||
785
- entryPath.endsWith('shrk.js') ||
786
- entryPath.endsWith('shrk.cmd')) {
715
+ if (isMain || process.argv[1]?.endsWith('main.ts') || process.argv[1]?.endsWith('shrk')) {
787
716
  const argv = process.argv.slice(2);
788
717
  runCli(argv).then((code) => process.exit(code), (err) => {
789
718
  process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
@@ -12,7 +12,15 @@ export interface IFailureHint {
12
12
  doc?: string;
13
13
  }
14
14
  export declare function renderFailureHints(hints: readonly IFailureHint[]): string;
15
- export declare function doctorHints(): IFailureHint[];
15
+ export interface IDoctorHintsContext {
16
+ /**
17
+ * True when the workspace has no `sharkcraft/` folder. On a fresh repo
18
+ * the right next step is `shrk init`, not advanced suppressions/watch
19
+ * loops.
20
+ */
21
+ sharkcraftFolderMissing?: boolean;
22
+ }
23
+ export declare function doctorHints(context?: IDoctorHintsContext): IFailureHint[];
16
24
  export declare function staleKnowledgeHints(): IFailureHint[];
17
25
  export declare function templateDriftHints(): IFailureHint[];
18
26
  export declare function fuzzyImpactAmbiguousHints(): IFailureHint[];
@@ -1 +1 @@
1
- {"version":3,"file":"failure-hints.d.ts","sourceRoot":"","sources":["../../src/output/failure-hints.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAUzE;AAID,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAM5C;AAED,wBAAgB,mBAAmB,IAAI,YAAY,EAAE,CAMpD;AAED,wBAAgB,kBAAkB,IAAI,YAAY,EAAE,CAMnD;AAED,wBAAgB,yBAAyB,IAAI,YAAY,EAAE,CAK1D;AAED,wBAAgB,6BAA6B,IAAI,YAAY,EAAE,CAK9D;AAED,wBAAgB,kBAAkB,IAAI,YAAY,EAAE,CAKnD;AAED,wBAAgB,wBAAwB,IAAI,YAAY,EAAE,CAKzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAiB9D;AAED,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,kBAAkB,GAClB,eAAe,GACf,2BAA2B,GAC3B,sBAAsB,GACtB,+BAA+B,GAC/B,wBAAwB,GACxB,8BAA8B,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,GAAG,SAAS,CA4E3G"}
1
+ {"version":3,"file":"failure-hints.d.ts","sourceRoot":"","sources":["../../src/output/failure-hints.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAUzE;AAID,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,EAAE,CAa7E;AAED,wBAAgB,mBAAmB,IAAI,YAAY,EAAE,CAMpD;AAED,wBAAgB,kBAAkB,IAAI,YAAY,EAAE,CAMnD;AAED,wBAAgB,yBAAyB,IAAI,YAAY,EAAE,CAK1D;AAED,wBAAgB,6BAA6B,IAAI,YAAY,EAAE,CAK9D;AAED,wBAAgB,kBAAkB,IAAI,YAAY,EAAE,CAKnD;AAED,wBAAgB,wBAAwB,IAAI,YAAY,EAAE,CAKzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAiB9D;AAED,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,kBAAkB,GAClB,eAAe,GACf,2BAA2B,GAC3B,sBAAsB,GACtB,+BAA+B,GAC/B,wBAAwB,GACxB,8BAA8B,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,GAAG,SAAS,CA4E3G"}
@@ -11,8 +11,14 @@ export function renderFailureHints(hints) {
11
11
  }
12
12
  return lines.join('\n') + '\n';
13
13
  }
14
- // ── Convenience hint builders ──────────────────────────────────────────
15
- export function doctorHints() {
14
+ export function doctorHints(context = {}) {
15
+ if (context.sharkcraftFolderMissing) {
16
+ return [
17
+ { label: 'scaffold sharkcraft/ (auto-pick a preset)', command: 'shrk init --zero-config' },
18
+ { label: 'preview the scaffold first', command: 'shrk init --zero-config --dry-run' },
19
+ { label: 'try the killer demo (no folder required)', command: 'shrk check boundaries --changed-only --since main' },
20
+ ];
21
+ }
16
22
  return [
17
23
  { label: 'preview fix suggestions', command: 'shrk fix preview --action-hints' },
18
24
  { label: 'list suppressions', command: 'shrk doctor suppressions list' },
@@ -27,19 +27,11 @@ export interface IWatchPlan {
27
27
  }
28
28
  export declare function buildWatchPlan(options: IWatchLoopOptions, steps: readonly string[]): IWatchPlan;
29
29
  import type { ParsedArgs } from '../command-registry.js';
30
- export interface IWatchModeOptions {
31
- /**
32
- * Paths to watch when the user does not pass `--paths`. Defaults to
33
- * `['sharkcraft']` if omitted. Use this for commands that scan code
34
- * outside `sharkcraft/` (e.g. `check boundaries` scans the whole repo).
35
- */
36
- defaultPaths?: readonly string[];
37
- }
38
30
  /**
39
31
  * Run a command's `run` function inside a watch loop when --watch is set.
40
32
  *
41
33
  * @returns null if --watch is not set (caller proceeds as before), otherwise
42
34
  * the exit code of the watch loop.
43
35
  */
44
- export declare function maybeRunInWatchMode(args: ParsedArgs, runner: (innerArgs: ParsedArgs) => Promise<number>, options?: IWatchModeOptions): Promise<number | null>;
36
+ export declare function maybeRunInWatchMode(args: ParsedArgs, runner: (innerArgs: ParsedArgs) => Promise<number>): Promise<number | null>;
45
37
  //# sourceMappingURL=watch-loop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch-loop.d.ts","sourceRoot":"","sources":["../../src/output/watch-loop.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACvC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,MAAM,CAAC,CA6DjB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,0BAA0B,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,UAAU,CAYZ;AAED,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,EAClD,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqCxB"}
1
+ {"version":3,"file":"watch-loop.d.ts","sourceRoot":"","sources":["../../src/output/watch-loop.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACvC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,MAAM,CAAC,CA6DjB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,0BAA0B,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,UAAU,CAYZ;AAED,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,GACjD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0BxB"}
@@ -81,41 +81,31 @@ export function buildWatchPlan(options, steps) {
81
81
  steps,
82
82
  };
83
83
  }
84
- import { flagBool, flagNumber, flagString, resolveCwd } from "../command-registry.js";
84
+ import { flagBool, flagNumber, resolveCwd } from "../command-registry.js";
85
85
  /**
86
86
  * Run a command's `run` function inside a watch loop when --watch is set.
87
87
  *
88
88
  * @returns null if --watch is not set (caller proceeds as before), otherwise
89
89
  * the exit code of the watch loop.
90
90
  */
91
- export async function maybeRunInWatchMode(args, runner, options = {}) {
91
+ export async function maybeRunInWatchMode(args, runner) {
92
92
  if (!flagBool(args, 'watch'))
93
93
  return null;
94
94
  const cwd = resolveCwd(args);
95
95
  const debounce = flagNumber(args, 'debounce') ?? 300;
96
96
  const once = flagBool(args, 'once');
97
- const pathsFlag = flagString(args, 'paths');
98
- const userPaths = pathsFlag
99
- ? pathsFlag.split(',').map((s) => s.trim()).filter((s) => s.length > 0)
100
- : [];
101
- const paths = userPaths.length > 0
102
- ? userPaths
103
- : options.defaultPaths && options.defaultPaths.length > 0
104
- ? options.defaultPaths
105
- : ['sharkcraft'];
106
97
  // Strip --watch so the inner snapshot doesn't recurse.
107
98
  const innerFlags = new Map(args.flags);
108
99
  innerFlags.delete('watch');
109
100
  innerFlags.delete('once');
110
101
  innerFlags.delete('debounce');
111
- innerFlags.delete('paths');
112
102
  const innerArgs = {
113
103
  positional: args.positional,
114
104
  flags: innerFlags,
115
105
  multiFlags: args.multiFlags,
116
106
  ...(args.globalCwd ? { globalCwd: args.globalCwd } : {}),
117
107
  };
118
- return runWatchLoop({ cwd, debounce, once, paths }, {
108
+ return runWatchLoop({ cwd, debounce, once }, {
119
109
  snapshot: async () => {
120
110
  const ts = new Date().toLocaleTimeString();
121
111
  process.stdout.write(`\n[watch] ${ts}\n`);