@shrkcrft/cli 0.1.0-alpha.1 → 0.1.0-alpha.10

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 (120) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/api-diff.command.d.ts +11 -0
  3. package/dist/commands/api-diff.command.d.ts.map +1 -0
  4. package/dist/commands/api-diff.command.js +116 -0
  5. package/dist/commands/arch.command.d.ts +9 -0
  6. package/dist/commands/arch.command.d.ts.map +1 -0
  7. package/dist/commands/arch.command.js +186 -0
  8. package/dist/commands/boundaries.command.d.ts.map +1 -1
  9. package/dist/commands/boundaries.command.js +0 -12
  10. package/dist/commands/check.command.d.ts.map +1 -1
  11. package/dist/commands/check.command.js +20 -30
  12. package/dist/commands/code-intel.command.d.ts +18 -0
  13. package/dist/commands/code-intel.command.d.ts.map +1 -0
  14. package/dist/commands/code-intel.command.js +146 -0
  15. package/dist/commands/command-catalog.d.ts +7 -3
  16. package/dist/commands/command-catalog.d.ts.map +1 -1
  17. package/dist/commands/command-catalog.js +201 -47
  18. package/dist/commands/commands.command.d.ts.map +1 -1
  19. package/dist/commands/commands.command.js +4 -4
  20. package/dist/commands/completion.command.d.ts +10 -0
  21. package/dist/commands/completion.command.d.ts.map +1 -0
  22. package/dist/commands/completion.command.js +121 -0
  23. package/dist/commands/constructs.command.d.ts.map +1 -1
  24. package/dist/commands/constructs.command.js +5 -22
  25. package/dist/commands/context.command.d.ts.map +1 -1
  26. package/dist/commands/context.command.js +89 -0
  27. package/dist/commands/diff-check.command.d.ts +30 -0
  28. package/dist/commands/diff-check.command.d.ts.map +1 -0
  29. package/dist/commands/diff-check.command.js +210 -0
  30. package/dist/commands/doctor.command.d.ts.map +1 -1
  31. package/dist/commands/doctor.command.js +42 -9
  32. package/dist/commands/export.command.d.ts.map +1 -1
  33. package/dist/commands/export.command.js +76 -3
  34. package/dist/commands/framework.command.d.ts +12 -0
  35. package/dist/commands/framework.command.d.ts.map +1 -0
  36. package/dist/commands/framework.command.js +180 -0
  37. package/dist/commands/gate.command.d.ts +15 -0
  38. package/dist/commands/gate.command.d.ts.map +1 -0
  39. package/dist/commands/gate.command.js +296 -0
  40. package/dist/commands/graph-code-subverbs.d.ts +11 -0
  41. package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
  42. package/dist/commands/graph-code-subverbs.js +818 -0
  43. package/dist/commands/graph.command.d.ts.map +1 -1
  44. package/dist/commands/graph.command.js +22 -0
  45. package/dist/commands/help.command.d.ts +4 -3
  46. package/dist/commands/help.command.d.ts.map +1 -1
  47. package/dist/commands/help.command.js +77 -21
  48. package/dist/commands/helper.command.js +1 -1
  49. package/dist/commands/impact.command.d.ts.map +1 -1
  50. package/dist/commands/impact.command.js +170 -1
  51. package/dist/commands/import.command.d.ts.map +1 -1
  52. package/dist/commands/import.command.js +121 -5
  53. package/dist/commands/init.command.d.ts.map +1 -1
  54. package/dist/commands/init.command.js +184 -16
  55. package/dist/commands/mcp.command.d.ts.map +1 -1
  56. package/dist/commands/mcp.command.js +2 -131
  57. package/dist/commands/migrate.command.d.ts +13 -0
  58. package/dist/commands/migrate.command.d.ts.map +1 -0
  59. package/dist/commands/migrate.command.js +152 -0
  60. package/dist/commands/onboard.command.d.ts.map +1 -1
  61. package/dist/commands/onboard.command.js +3 -15
  62. package/dist/commands/packs-new.d.ts +1 -1
  63. package/dist/commands/packs-new.d.ts.map +1 -1
  64. package/dist/commands/packs-new.js +5 -36
  65. package/dist/commands/packs.command.d.ts.map +1 -1
  66. package/dist/commands/packs.command.js +3 -17
  67. package/dist/commands/plan-context.command.d.ts +11 -0
  68. package/dist/commands/plan-context.command.d.ts.map +1 -0
  69. package/dist/commands/plan-context.command.js +77 -0
  70. package/dist/commands/profiles.command.js +4 -4
  71. package/dist/commands/release.command.js +13 -13
  72. package/dist/commands/review.command.d.ts.map +1 -1
  73. package/dist/commands/review.command.js +2 -28
  74. package/dist/commands/rule-graph-subverbs.d.ts +3 -0
  75. package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
  76. package/dist/commands/rule-graph-subverbs.js +132 -0
  77. package/dist/commands/search-structural.command.d.ts +18 -0
  78. package/dist/commands/search-structural.command.d.ts.map +1 -0
  79. package/dist/commands/search-structural.command.js +376 -0
  80. package/dist/commands/search.command.js +1 -1
  81. package/dist/commands/task-context.command.js +0 -16
  82. package/dist/commands/task.command.d.ts.map +1 -1
  83. package/dist/commands/task.command.js +8 -2
  84. package/dist/dashboard/code-intelligence-data.d.ts +33 -0
  85. package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
  86. package/dist/dashboard/code-intelligence-data.js +307 -0
  87. package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
  88. package/dist/dashboard/dashboard-api-server.js +137 -1
  89. package/dist/export/claude-commands-export.d.ts +60 -0
  90. package/dist/export/claude-commands-export.d.ts.map +1 -0
  91. package/dist/export/claude-commands-export.js +276 -0
  92. package/dist/export/export-formats.d.ts +1 -1
  93. package/dist/export/export-formats.d.ts.map +1 -1
  94. package/dist/export/export-formats.js +139 -12
  95. package/dist/init/init-templates.d.ts.map +1 -1
  96. package/dist/init/init-templates.js +133 -113
  97. package/dist/init/paths-advisory.d.ts +20 -0
  98. package/dist/init/paths-advisory.d.ts.map +1 -0
  99. package/dist/init/paths-advisory.js +88 -0
  100. package/dist/main.d.ts +1 -1
  101. package/dist/main.d.ts.map +1 -1
  102. package/dist/main.js +137 -46
  103. package/dist/output/failure-hints.d.ts +1 -9
  104. package/dist/output/failure-hints.d.ts.map +1 -1
  105. package/dist/output/failure-hints.js +2 -8
  106. package/dist/output/watch-loop.d.ts +9 -1
  107. package/dist/output/watch-loop.d.ts.map +1 -1
  108. package/dist/output/watch-loop.js +13 -3
  109. package/dist/schemas/json-schemas.d.ts +36 -36
  110. package/dist/schemas/json-schemas.js +36 -36
  111. package/dist/surface/about.d.ts.map +1 -1
  112. package/dist/surface/about.js +37 -15
  113. package/dist/surface/no-args-landing.d.ts.map +1 -1
  114. package/dist/surface/no-args-landing.js +9 -13
  115. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  116. package/dist/surface/surface-config-writer.js +23 -11
  117. package/package.json +36 -25
  118. package/dist/commands/plugin.command.d.ts +0 -11
  119. package/dist/commands/plugin.command.d.ts.map +0 -1
  120. package/dist/commands/plugin.command.js +0 -394
package/dist/main.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env bun
1
+ #!/usr/bin/env node
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,8 +20,17 @@ 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";
23
24
  import { driftCommand } from "./commands/drift.command.js";
24
25
  import { graphCommand } from "./commands/graph.command.js";
26
+ import { ruleGraphCommand } from "./commands/rule-graph-subverbs.js";
27
+ import { searchStructuralCommand } from "./commands/search-structural.command.js";
28
+ import { planContextCommand } from "./commands/plan-context.command.js";
29
+ import { archCommand } from "./commands/arch.command.js";
30
+ import { frameworkCommand } from "./commands/framework.command.js";
31
+ import { apiDiffCommand } from "./commands/api-diff.command.js";
32
+ import { gateCommand } from "./commands/gate.command.js";
33
+ import { migrateCommand } from "./commands/migrate.command.js";
25
34
  import { coverageCommand } from "./commands/coverage.command.js";
26
35
  import { statsCommand } from "./commands/stats.command.js";
27
36
  import { reviewCommand } from "./commands/review.command.js";
@@ -56,7 +65,6 @@ import { biomeCommand } from "./commands/biome.command.js";
56
65
  import { ideCommand } from "./commands/ide.command.js";
57
66
  import { makeCommandsCommand } from "./commands/commands.command.js";
58
67
  import { safetyCommand } from "./commands/safety.command.js";
59
- import { pluginCommand } from "./commands/plugin.command.js";
60
68
  import { profilesCommand } from "./commands/profiles.command.js";
61
69
  import { auditProjectCouplingCommand } from "./commands/audit.command.js";
62
70
  import { conventionsCommand } from "./commands/conventions.command.js";
@@ -110,6 +118,8 @@ import { lintCommand } from "./commands/lint.command.js";
110
118
  import { changesCommand } from "./commands/changes.command.js";
111
119
  import { exploreCommand } from "./commands/explore.command.js";
112
120
  import { prCommand } from "./commands/pr.command.js";
121
+ import { completionCommand } from "./commands/completion.command.js";
122
+ import { codeIntelCommand } from "./commands/code-intel.command.js";
113
123
  import { suggestDidYouMean } from '@shrkcrft/inspector';
114
124
  import { COMMAND_CATALOG } from "./commands/command-catalog.js";
115
125
  import { errorFooterFor, renderErrorFooter } from "./output/failure-hints.js";
@@ -120,33 +130,6 @@ import { buildSurfaceSummary, findCommandInSummary } from "./surface/surface-sum
120
130
  import { makeSurfaceNotEnabledError, renderSurfaceNotEnabledText, SURFACE_NOT_ENABLED_EXIT_CODE, } from "./surface/not-enabled-error.js";
121
131
  import { extractCommandPath, recordUsage, sanitizeFlagNames, } from "./usage/usage-log.js";
122
132
  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
- }
150
133
  export function buildRegistry() {
151
134
  const registry = new CommandRegistry();
152
135
  registry.register(initCommand);
@@ -189,10 +172,19 @@ export function buildRegistry() {
189
172
  registry.register(taskCommand);
190
173
  registry.register(explainCommand);
191
174
  registry.register(checkCommand);
175
+ registry.register(diffCheckCommand);
192
176
  // changed-only preflight orchestrator.
193
177
  registry.register(preflightCommand);
194
178
  registry.register(driftCommand);
195
179
  registry.register(graphCommand);
180
+ registry.register(ruleGraphCommand);
181
+ registry.register(searchStructuralCommand);
182
+ registry.register(planContextCommand);
183
+ registry.register(archCommand);
184
+ registry.register(frameworkCommand);
185
+ registry.register(apiDiffCommand);
186
+ registry.register(gateCommand);
187
+ registry.register(migrateCommand);
196
188
  registry.register(coverageCommand);
197
189
  registry.register(statsCommand);
198
190
  registry.register(reviewCommand);
@@ -219,7 +211,6 @@ export function buildRegistry() {
219
211
  registry.register(eslintCommand);
220
212
  registry.register(biomeCommand);
221
213
  registry.register(ideCommand);
222
- registry.register(pluginCommand);
223
214
  registry.register(profilesCommand);
224
215
  registry.registerSubcommand('audit', auditProjectCouplingCommand);
225
216
  registry.register(conventionsCommand);
@@ -240,6 +231,8 @@ export function buildRegistry() {
240
231
  registry.register(lintCommand);
241
232
  registry.register(changesCommand);
242
233
  registry.register(prCommand);
234
+ registry.register(completionCommand);
235
+ registry.register(codeIntelCommand);
243
236
  registry.register(searchCommand);
244
237
  registry.register(briefCommand);
245
238
  registry.register(releaseCommand);
@@ -518,15 +511,9 @@ async function isUsageEnabled(cwd) {
518
511
  }
519
512
  }
520
513
  async function runCliInner(argv) {
521
- await ensureTokenizerReady();
522
514
  const registry = buildRegistry();
523
515
  // Pre-parse the global --cwd so it can appear anywhere (incl. before the command).
524
516
  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
- }
530
517
  const [first] = cleanArgv;
531
518
  // bare invocation lands on the curated tiered view.
532
519
  if (!first) {
@@ -539,7 +526,14 @@ async function runCliInner(argv) {
539
526
  return registry.get('help').run(parseArgs([], { globalCwd }));
540
527
  }
541
528
  if (first === '--full-help') {
542
- return registry.get('help').run(parseArgs(['--full'], { globalCwd }));
529
+ // Pass through `--all` (catalog dump) and `--verbose` if the user
530
+ // included them after `--full-help`.
531
+ const extra = [];
532
+ if (argv.includes('--all'))
533
+ extra.push('--all');
534
+ if (argv.includes('--verbose') || argv.includes('-v'))
535
+ extra.push('--verbose');
536
+ return registry.get('help').run(parseArgs(['--full', ...extra], { globalCwd }));
543
537
  }
544
538
  if (first === '--version' || first === '-v') {
545
539
  return registry.get('version').run(parseArgs([], { globalCwd }));
@@ -583,7 +577,7 @@ async function runCliInner(argv) {
583
577
  return 2;
584
578
  }
585
579
  const attempted = probe.slice(0, 2).join(' ');
586
- process.stderr.write(`Unknown command: ${attempted}\n`);
580
+ process.stderr.write(`shrk doesn't have a \`${attempted}\` command.\n`);
587
581
  printDidYouMean(attempted);
588
582
  return 2;
589
583
  }
@@ -691,28 +685,125 @@ async function checkSurfaceGate(matchedPath, cwd) {
691
685
  return null;
692
686
  }
693
687
  }
688
+ // Score thresholds for did-you-mean output. Picked from observed
689
+ // scoring: 1-char-off typos score 8+ on plain commands; 3-4-char-off
690
+ // near-misses score ~5; loose / token-overlap matches score 1-3.
691
+ // Junk matches (frobnicate → bundle diff) can score 8 too because of
692
+ // token overlap, so we sharpen by also requiring the suggestion's
693
+ // command name to be reasonably close in length to the attempt.
694
+ const SUGGEST_CONFIDENT_SCORE = 7;
695
+ const SUGGEST_VISIBLE_SCORE = 3;
696
+ function reorderCandidates(attempted, candidates) {
697
+ // Stable sort: higher score first, then shorter command (more likely
698
+ // canonical), then lexicographic. The base suggester returns ties in
699
+ // arbitrary order — this makes the top suggestion more predictable.
700
+ const ranked = [...candidates];
701
+ ranked.sort((a, b) => {
702
+ if (b.score !== a.score)
703
+ return b.score - a.score;
704
+ if (a.command.length !== b.command.length) {
705
+ return a.command.length - b.command.length;
706
+ }
707
+ return a.command < b.command ? -1 : a.command > b.command ? 1 : 0;
708
+ });
709
+ return ranked;
710
+ }
711
+ /** Edit distance (Levenshtein). Used to gate did-you-mean confidence. */
712
+ function editDistance(a, b) {
713
+ const m = a.length;
714
+ const n = b.length;
715
+ if (m === 0)
716
+ return n;
717
+ if (n === 0)
718
+ return m;
719
+ const dp = new Array(n + 1);
720
+ for (let j = 0; j <= n; j += 1)
721
+ dp[j] = j;
722
+ for (let i = 1; i <= m; i += 1) {
723
+ let prev = dp[0];
724
+ dp[0] = i;
725
+ for (let j = 1; j <= n; j += 1) {
726
+ const tmp = dp[j];
727
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
728
+ dp[j] = Math.min(dp[j] + 1, dp[j - 1] + 1, prev + cost);
729
+ prev = tmp;
730
+ }
731
+ }
732
+ return dp[n];
733
+ }
734
+ /**
735
+ * Suggestion is "confident" when the candidate's top token is close
736
+ * to the attempt in edit-distance terms — `doctorz`→`doctor` (1 edit)
737
+ * or `inspct`→`inspect` (1 edit) qualify; `frobnicate`→`bundle` (10
738
+ * edits) does not, even when the suggester scores them similarly
739
+ * because of incidental token overlap in descriptions.
740
+ *
741
+ * Threshold: edit distance ≤ max(1, attempt.length / 4) AND raw score
742
+ * meets `SUGGEST_VISIBLE_SCORE`. This catches typical fingers-on-keys
743
+ * typos while rejecting "you typed something totally different."
744
+ */
745
+ function isConfidentMatch(attempted, suggestion) {
746
+ if (suggestion.score < SUGGEST_VISIBLE_SCORE)
747
+ return false;
748
+ const lower = attempted.toLowerCase();
749
+ const head = (suggestion.command.split(/\s+/)[0] ?? suggestion.command).toLowerCase();
750
+ const dist = editDistance(lower, head);
751
+ const tolerance = Math.max(1, Math.floor(lower.length / 4));
752
+ return dist <= tolerance;
753
+ }
694
754
  function printDidYouMean(attempted) {
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");
755
+ const rawCandidates = suggestDidYouMean(COMMAND_CATALOG, [attempted], 5);
756
+ const reordered = reorderCandidates(attempted, rawCandidates).filter((c) => c.score >= SUGGEST_VISIBLE_SCORE);
757
+ if (reordered.length === 0) {
758
+ process.stderr.write('Run `shrk help` to see the curated commands, or `shrk --full-help` for the full catalog.\n');
759
+ const footer = errorFooterFor('unknown-command', { task: attempted });
760
+ if (footer)
761
+ process.stderr.write(renderErrorFooter(footer));
762
+ return;
763
+ }
764
+ // Confident single-match path: surface ONE suggestion clearly.
765
+ const top = reordered[0];
766
+ if (isConfidentMatch(attempted, top)) {
767
+ process.stderr.write(`Did you mean \`shrk ${top.command}\`?\n`);
768
+ process.stderr.write(` ${top.description}\n`);
769
+ // Second-tier suggestions only if they're also strong.
770
+ const others = reordered.slice(1, 3).filter((c) => isConfidentMatch(attempted, c));
771
+ if (others.length > 0) {
772
+ process.stderr.write('Other close matches:\n');
773
+ for (const c of others) {
774
+ process.stderr.write(` shrk ${c.command} — ${c.description}\n`);
775
+ }
776
+ }
698
777
  const footer = errorFooterFor('unknown-command', { task: attempted });
699
778
  if (footer)
700
779
  process.stderr.write(renderErrorFooter(footer));
701
780
  return;
702
781
  }
703
- process.stderr.write('Did you mean:\n');
704
- for (const c of candidates) {
782
+ // Low-confidence: show up to 3 as "closest matches", honest about
783
+ // not knowing which is right.
784
+ process.stderr.write('Closest matches in the catalog:\n');
785
+ for (const c of reordered.slice(0, 3)) {
705
786
  process.stderr.write(` shrk ${c.command} — ${c.description}\n`);
706
787
  }
707
- // append the standardised next-command footer so the user
708
- // always has a deterministic exit route.
788
+ process.stderr.write("If none of those look right, run `shrk help` or `shrk \"<task>\"` to route as a free-form task.\n");
709
789
  const footer = errorFooterFor('unknown-command', { task: attempted });
710
790
  if (footer)
711
791
  process.stderr.write(renderErrorFooter(footer));
712
792
  }
713
793
  // Entry point when invoked directly.
794
+ //
795
+ // Bun exposes `import.meta.main`; Node does not. When Node runs the
796
+ // compiled `dist/main.js` directly the path-suffix check (`main.js`)
797
+ // catches it. The npm bin shim points at `shrk` so that suffix also
798
+ // triggers it. Source dev under Bun still runs via `main.ts`.
714
799
  const isMain = typeof import.meta !== 'undefined' && import.meta.main === true;
715
- if (isMain || process.argv[1]?.endsWith('main.ts') || process.argv[1]?.endsWith('shrk')) {
800
+ const entryPath = process.argv[1] ?? '';
801
+ if (isMain ||
802
+ entryPath.endsWith('main.ts') ||
803
+ entryPath.endsWith('main.js') ||
804
+ entryPath.endsWith('shrk') ||
805
+ entryPath.endsWith('shrk.js') ||
806
+ entryPath.endsWith('shrk.cmd')) {
716
807
  const argv = process.argv.slice(2);
717
808
  runCli(argv).then((code) => process.exit(code), (err) => {
718
809
  process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
@@ -12,15 +12,7 @@ export interface IFailureHint {
12
12
  doc?: string;
13
13
  }
14
14
  export declare function renderFailureHints(hints: readonly IFailureHint[]): string;
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[];
15
+ export declare function doctorHints(): IFailureHint[];
24
16
  export declare function staleKnowledgeHints(): IFailureHint[];
25
17
  export declare function templateDriftHints(): IFailureHint[];
26
18
  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,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"}
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"}
@@ -11,14 +11,8 @@ export function renderFailureHints(hints) {
11
11
  }
12
12
  return lines.join('\n') + '\n';
13
13
  }
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
- }
14
+ // ── Convenience hint builders ──────────────────────────────────────────
15
+ export function doctorHints() {
22
16
  return [
23
17
  { label: 'preview fix suggestions', command: 'shrk fix preview --action-hints' },
24
18
  { label: 'list suppressions', command: 'shrk doctor suppressions list' },
@@ -27,11 +27,19 @@ 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
+ }
30
38
  /**
31
39
  * Run a command's `run` function inside a watch loop when --watch is set.
32
40
  *
33
41
  * @returns null if --watch is not set (caller proceeds as before), otherwise
34
42
  * the exit code of the watch loop.
35
43
  */
36
- export declare function maybeRunInWatchMode(args: ParsedArgs, runner: (innerArgs: ParsedArgs) => Promise<number>): Promise<number | null>;
44
+ export declare function maybeRunInWatchMode(args: ParsedArgs, runner: (innerArgs: ParsedArgs) => Promise<number>, options?: IWatchModeOptions): Promise<number | null>;
37
45
  //# 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;;;;;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"}
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"}
@@ -81,31 +81,41 @@ export function buildWatchPlan(options, steps) {
81
81
  steps,
82
82
  };
83
83
  }
84
- import { flagBool, flagNumber, resolveCwd } from "../command-registry.js";
84
+ import { flagBool, flagNumber, flagString, 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) {
91
+ export async function maybeRunInWatchMode(args, runner, options = {}) {
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'];
97
106
  // Strip --watch so the inner snapshot doesn't recurse.
98
107
  const innerFlags = new Map(args.flags);
99
108
  innerFlags.delete('watch');
100
109
  innerFlags.delete('once');
101
110
  innerFlags.delete('debounce');
111
+ innerFlags.delete('paths');
102
112
  const innerArgs = {
103
113
  positional: args.positional,
104
114
  flags: innerFlags,
105
115
  multiFlags: args.multiFlags,
106
116
  ...(args.globalCwd ? { globalCwd: args.globalCwd } : {}),
107
117
  };
108
- return runWatchLoop({ cwd, debounce, once }, {
118
+ return runWatchLoop({ cwd, debounce, once, paths }, {
109
119
  snapshot: async () => {
110
120
  const ts = new Date().toLocaleTimeString();
111
121
  process.stdout.write(`\n[watch] ${ts}\n`);