@shrkcrft/cli 0.1.0-alpha.1 → 0.1.0-alpha.11
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/commands/api-diff.command.d.ts +11 -0
- package/dist/commands/api-diff.command.d.ts.map +1 -0
- package/dist/commands/api-diff.command.js +116 -0
- package/dist/commands/arch.command.d.ts +9 -0
- package/dist/commands/arch.command.d.ts.map +1 -0
- package/dist/commands/arch.command.js +186 -0
- package/dist/commands/boundaries.command.d.ts.map +1 -1
- package/dist/commands/boundaries.command.js +0 -12
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +20 -30
- package/dist/commands/code-intel.command.d.ts +18 -0
- package/dist/commands/code-intel.command.d.ts.map +1 -0
- package/dist/commands/code-intel.command.js +146 -0
- package/dist/commands/command-catalog.d.ts +7 -3
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +201 -47
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +4 -4
- package/dist/commands/completion.command.d.ts +10 -0
- package/dist/commands/completion.command.d.ts.map +1 -0
- package/dist/commands/completion.command.js +121 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +5 -22
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +89 -0
- package/dist/commands/diff-check.command.d.ts +30 -0
- package/dist/commands/diff-check.command.d.ts.map +1 -0
- package/dist/commands/diff-check.command.js +210 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +42 -9
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +76 -3
- package/dist/commands/framework.command.d.ts +12 -0
- package/dist/commands/framework.command.d.ts.map +1 -0
- package/dist/commands/framework.command.js +180 -0
- package/dist/commands/gate.command.d.ts +15 -0
- package/dist/commands/gate.command.d.ts.map +1 -0
- package/dist/commands/gate.command.js +296 -0
- package/dist/commands/graph-code-subverbs.d.ts +11 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
- package/dist/commands/graph-code-subverbs.js +818 -0
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +22 -0
- package/dist/commands/help.command.d.ts +4 -3
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +77 -21
- package/dist/commands/helper.command.js +1 -1
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +170 -1
- package/dist/commands/import.command.d.ts.map +1 -1
- package/dist/commands/import.command.js +121 -5
- package/dist/commands/init.command.d.ts.map +1 -1
- package/dist/commands/init.command.js +184 -16
- package/dist/commands/mcp.command.d.ts.map +1 -1
- package/dist/commands/mcp.command.js +2 -131
- package/dist/commands/migrate.command.d.ts +13 -0
- package/dist/commands/migrate.command.d.ts.map +1 -0
- package/dist/commands/migrate.command.js +152 -0
- package/dist/commands/onboard.command.d.ts.map +1 -1
- package/dist/commands/onboard.command.js +3 -15
- package/dist/commands/packs-new.d.ts +1 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +5 -36
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +3 -17
- package/dist/commands/plan-context.command.d.ts +11 -0
- package/dist/commands/plan-context.command.d.ts.map +1 -0
- package/dist/commands/plan-context.command.js +77 -0
- package/dist/commands/profiles.command.js +4 -4
- package/dist/commands/release.command.js +13 -13
- package/dist/commands/review.command.d.ts.map +1 -1
- package/dist/commands/review.command.js +2 -28
- package/dist/commands/rule-graph-subverbs.d.ts +3 -0
- package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
- package/dist/commands/rule-graph-subverbs.js +132 -0
- package/dist/commands/search-structural.command.d.ts +18 -0
- package/dist/commands/search-structural.command.d.ts.map +1 -0
- package/dist/commands/search-structural.command.js +376 -0
- package/dist/commands/search.command.js +1 -1
- package/dist/commands/task-context.command.js +0 -16
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +8 -2
- package/dist/dashboard/code-intelligence-data.d.ts +33 -0
- package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
- package/dist/dashboard/code-intelligence-data.js +307 -0
- package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
- package/dist/dashboard/dashboard-api-server.js +162 -1
- package/dist/export/claude-commands-export.d.ts +60 -0
- package/dist/export/claude-commands-export.d.ts.map +1 -0
- package/dist/export/claude-commands-export.js +276 -0
- package/dist/export/export-formats.d.ts +1 -1
- package/dist/export/export-formats.d.ts.map +1 -1
- package/dist/export/export-formats.js +139 -12
- package/dist/init/init-templates.d.ts.map +1 -1
- package/dist/init/init-templates.js +133 -113
- package/dist/init/paths-advisory.d.ts +20 -0
- package/dist/init/paths-advisory.d.ts.map +1 -0
- package/dist/init/paths-advisory.js +88 -0
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +137 -46
- package/dist/output/failure-hints.d.ts +1 -9
- package/dist/output/failure-hints.d.ts.map +1 -1
- package/dist/output/failure-hints.js +2 -8
- package/dist/output/watch-loop.d.ts +9 -1
- package/dist/output/watch-loop.d.ts.map +1 -1
- package/dist/output/watch-loop.js +13 -3
- package/dist/schemas/json-schemas.d.ts +36 -36
- package/dist/schemas/json-schemas.js +36 -36
- package/dist/surface/about.d.ts.map +1 -1
- package/dist/surface/about.js +37 -15
- package/dist/surface/no-args-landing.d.ts.map +1 -1
- package/dist/surface/no-args-landing.js +9 -13
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +23 -11
- package/package.json +37 -25
- package/dist/commands/plugin.command.d.ts +0 -11
- package/dist/commands/plugin.command.d.ts.map +0 -1
- package/dist/commands/plugin.command.js +0 -394
package/dist/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
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
|
-
|
|
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(`
|
|
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
|
|
696
|
-
|
|
697
|
-
|
|
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
|
-
|
|
704
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
15
|
-
|
|
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
|
|
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,
|
|
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`);
|