@shrkcrft/cli 0.1.0-alpha.11 → 0.1.0-alpha.13
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/dist/audit/knowledge-audit-llm.d.ts +19 -0
- package/dist/audit/knowledge-audit-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-audit-llm.js +164 -0
- package/dist/audit/knowledge-audit.d.ts +61 -0
- package/dist/audit/knowledge-audit.d.ts.map +1 -0
- package/dist/audit/knowledge-audit.js +203 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts +11 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan-llm.js +141 -0
- package/dist/audit/knowledge-fix-plan.d.ts +41 -0
- package/dist/audit/knowledge-fix-plan.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan.js +125 -0
- package/dist/audit/pipeline-audit-llm.d.ts +11 -0
- package/dist/audit/pipeline-audit-llm.d.ts.map +1 -0
- package/dist/audit/pipeline-audit-llm.js +134 -0
- package/dist/audit/pipeline-audit.d.ts +69 -0
- package/dist/audit/pipeline-audit.d.ts.map +1 -0
- package/dist/audit/pipeline-audit.js +166 -0
- package/dist/audit/templates-audit-llm.d.ts +19 -0
- package/dist/audit/templates-audit-llm.d.ts.map +1 -0
- package/dist/audit/templates-audit-llm.js +207 -0
- package/dist/audit/templates-audit.d.ts +63 -0
- package/dist/audit/templates-audit.d.ts.map +1 -0
- package/dist/audit/templates-audit.js +171 -0
- package/dist/audit/templates-fix-plan-llm.d.ts +19 -0
- package/dist/audit/templates-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan-llm.js +162 -0
- package/dist/audit/templates-fix-plan.d.ts +37 -0
- package/dist/audit/templates-fix-plan.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan.js +174 -0
- package/dist/commands/ai-status.command.d.ts +19 -0
- package/dist/commands/ai-status.command.d.ts.map +1 -0
- package/dist/commands/ai-status.command.js +94 -0
- package/dist/commands/ask.command.d.ts.map +1 -1
- package/dist/commands/ask.command.js +10 -9
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +110 -1
- package/dist/commands/deps-audit.command.d.ts +23 -0
- package/dist/commands/deps-audit.command.d.ts.map +1 -0
- package/dist/commands/deps-audit.command.js +266 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +100 -3
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
- package/dist/commands/graph-code-subverbs.js +144 -26
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +3 -2
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +22 -1
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +3 -2
- package/dist/commands/move-plan.command.d.ts +23 -0
- package/dist/commands/move-plan.command.d.ts.map +1 -0
- package/dist/commands/move-plan.command.js +360 -0
- package/dist/commands/scaffold-validate.command.d.ts +22 -0
- package/dist/commands/scaffold-validate.command.d.ts.map +1 -0
- package/dist/commands/scaffold-validate.command.js +215 -0
- package/dist/commands/smart-context.command.d.ts +58 -0
- package/dist/commands/smart-context.command.d.ts.map +1 -0
- package/dist/commands/smart-context.command.js +4524 -0
- package/dist/commands/spike.command.d.ts +22 -0
- package/dist/commands/spike.command.d.ts.map +1 -0
- package/dist/commands/spike.command.js +235 -0
- package/dist/commands/surface.command.d.ts +1 -0
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +10 -3
- package/dist/commands/template-quality.command.d.ts.map +1 -1
- package/dist/commands/template-quality.command.js +39 -3
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +37 -2
- package/dist/commands/watch.command.d.ts +26 -0
- package/dist/commands/watch.command.d.ts.map +1 -0
- package/dist/commands/watch.command.js +456 -0
- package/dist/env/load-dotenv.d.ts +15 -0
- package/dist/env/load-dotenv.d.ts.map +1 -0
- package/dist/env/load-dotenv.js +70 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +105 -2
- package/dist/schemas/json-schemas.d.ts +384 -36
- package/dist/schemas/json-schemas.d.ts.map +1 -1
- package/dist/schemas/json-schemas.js +247 -36
- package/package.json +33 -31
|
@@ -350,13 +350,15 @@ export async function runGraphStatus(args) {
|
|
|
350
350
|
}
|
|
351
351
|
const verify = store.verifyDigest();
|
|
352
352
|
const snap = store.loadSnapshot();
|
|
353
|
+
const manifestNodeCount = sumValues(snap.manifest.nodesByKind);
|
|
354
|
+
const manifestEdgeCount = sumValues(snap.manifest.edgesByKind);
|
|
353
355
|
const payload = {
|
|
354
356
|
ok: verify.ok,
|
|
355
357
|
state: verify.ok ? 'fresh' : 'corrupt',
|
|
356
358
|
schema: snap.manifest.schema,
|
|
357
359
|
fileCount: snap.manifest.filesIndexed,
|
|
358
|
-
nodeCount:
|
|
359
|
-
edgeCount:
|
|
360
|
+
nodeCount: manifestNodeCount,
|
|
361
|
+
edgeCount: manifestEdgeCount,
|
|
360
362
|
lastIndexedAt: snap.manifest.lastIndexedAt,
|
|
361
363
|
lastIndexDurationMs: snap.manifest.lastIndexDurationMs,
|
|
362
364
|
workspacePackages: snap.manifest.workspacePackages,
|
|
@@ -394,8 +396,10 @@ export async function runGraphSearch(args) {
|
|
|
394
396
|
const cwd = resolveCwd(args);
|
|
395
397
|
const wantJson = flagBool(args, 'json');
|
|
396
398
|
const query = args.positional[1];
|
|
397
|
-
|
|
398
|
-
|
|
399
|
+
const hasUnresolved = flagBool(args, 'has-unresolved-imports');
|
|
400
|
+
if (!query && !hasUnresolved) {
|
|
401
|
+
process.stderr.write('Usage: shrk graph search <query> [--kind file|symbol|package] [--limit N]\n' +
|
|
402
|
+
' shrk graph search --kind file --has-unresolved-imports [--limit N]\n');
|
|
399
403
|
return 2;
|
|
400
404
|
}
|
|
401
405
|
const kindFlag = flagString(args, 'kind');
|
|
@@ -403,7 +407,16 @@ export async function runGraphSearch(args) {
|
|
|
403
407
|
const api = loadOrFail(cwd, wantJson);
|
|
404
408
|
if (!api)
|
|
405
409
|
return 1;
|
|
406
|
-
|
|
410
|
+
let matches;
|
|
411
|
+
if (hasUnresolved) {
|
|
412
|
+
const all = api.filesWithUnresolvedImports();
|
|
413
|
+
matches = (query
|
|
414
|
+
? all.filter((n) => (n.path ?? '').toLowerCase().includes(query.toLowerCase()))
|
|
415
|
+
: [...all]).slice(0, limit);
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
matches = collectSearchMatches(api, query, kindFlag, limit);
|
|
419
|
+
}
|
|
407
420
|
if (wantJson) {
|
|
408
421
|
process.stdout.write(asJson({
|
|
409
422
|
schema: 'sharkcraft.graph-search/v1',
|
|
@@ -414,11 +427,12 @@ export async function runGraphSearch(args) {
|
|
|
414
427
|
}) + '\n');
|
|
415
428
|
return 0;
|
|
416
429
|
}
|
|
430
|
+
const headerLabel = query ?? (hasUnresolved ? 'files with unresolved imports' : '');
|
|
417
431
|
if (matches.length === 0) {
|
|
418
|
-
process.stdout.write(`No matches for "${
|
|
432
|
+
process.stdout.write(`No matches for "${headerLabel}".\n`);
|
|
419
433
|
return 0;
|
|
420
434
|
}
|
|
421
|
-
process.stdout.write(header(`Graph search: ${
|
|
435
|
+
process.stdout.write(header(`Graph search: ${headerLabel}`));
|
|
422
436
|
for (const m of matches) {
|
|
423
437
|
process.stdout.write(` ${m.kind.padEnd(8)} ${m.label}${m.path ? ' ' + m.path : ''}${m.line ? ':' + m.line : ''}\n`);
|
|
424
438
|
}
|
|
@@ -449,22 +463,29 @@ export async function runGraphContext(args) {
|
|
|
449
463
|
process.stderr.write(`No graph node matched "${target}".\n`);
|
|
450
464
|
return 1;
|
|
451
465
|
}
|
|
452
|
-
const
|
|
466
|
+
const anchorFile = anchor.kind === NodeKind.File
|
|
467
|
+
? anchor
|
|
468
|
+
: declaringFileOf(api, anchor.id) ?? (anchor.path ? api.findFile(anchor.path) : undefined);
|
|
469
|
+
const subjectNodeId = anchorFile?.id ?? anchor.id;
|
|
470
|
+
const neighbours = api.neighbours(subjectNodeId);
|
|
453
471
|
const symbols = anchor.kind === NodeKind.File ? api.symbolsIn(anchor.id) : [];
|
|
472
|
+
const references = anchor.kind === NodeKind.Symbol ? dedupeNodes(api.referencesOf(anchor.id)) : [];
|
|
473
|
+
const callers = anchor.kind === NodeKind.Symbol ? dedupeNodes(api.callersOf(anchor.id)) : [];
|
|
454
474
|
// Optional bridge enrichment: rules / paths / templates applying to
|
|
455
|
-
// the anchor file (
|
|
475
|
+
// the anchor file (or a symbol's containing file).
|
|
456
476
|
const bridgeStore = new BridgeStore(cwd);
|
|
457
|
-
const bridgeFor = (includeBridge && bridgeStore.exists() &&
|
|
458
|
-
? RuleGraphQueryApi.fromStores(cwd).forFile(
|
|
477
|
+
const bridgeFor = (includeBridge && bridgeStore.exists() && anchorFile?.path)
|
|
478
|
+
? RuleGraphQueryApi.fromStores(cwd).forFile(anchorFile.path)
|
|
459
479
|
: undefined;
|
|
460
480
|
// Optional framework enrichment.
|
|
461
481
|
const frameworkStore = new FrameworkStore(cwd);
|
|
462
|
-
const frameworkEntities = (includeFramework && frameworkStore.exists() &&
|
|
463
|
-
? FrameworkQueryApi.fromStore(cwd).forFile(
|
|
482
|
+
const frameworkEntities = (includeFramework && frameworkStore.exists() && anchorFile?.path)
|
|
483
|
+
? FrameworkQueryApi.fromStore(cwd).forFile(anchorFile.path)
|
|
464
484
|
: [];
|
|
465
485
|
const payload = {
|
|
466
486
|
schema: 'sharkcraft.graph-context/v1',
|
|
467
487
|
anchor: nodeSummary(anchor),
|
|
488
|
+
declaredIn: anchor.kind === NodeKind.Symbol && anchorFile ? nodeSummary(anchorFile) : null,
|
|
468
489
|
depth,
|
|
469
490
|
importsFrom: neighbours.out
|
|
470
491
|
.filter((o) => o.edge.kind === 'imports-file')
|
|
@@ -475,6 +496,8 @@ export async function runGraphContext(args) {
|
|
|
475
496
|
.slice(0, 50)
|
|
476
497
|
.map((i) => 'source' in i ? sourceSummary(i.source) : { id: 'unknown', resolved: false }),
|
|
477
498
|
symbols: symbols.slice(0, 50).map(nodeSummary),
|
|
499
|
+
referencedBy: references.slice(0, 50).map(nodeSummary),
|
|
500
|
+
calledBy: callers.slice(0, 50).map(nodeSummary),
|
|
478
501
|
bridge: bridgeFor
|
|
479
502
|
? {
|
|
480
503
|
rules: bridgeFor.rules.map((h) => ({
|
|
@@ -503,12 +526,29 @@ export async function runGraphContext(args) {
|
|
|
503
526
|
}
|
|
504
527
|
process.stdout.write(header(`Graph context: ${anchor.kind}:${anchor.label}`));
|
|
505
528
|
process.stdout.write(kv('path', anchor.path ?? '(none)') + '\n');
|
|
529
|
+
if (anchor.line)
|
|
530
|
+
process.stdout.write(kv('line', String(anchor.line)) + '\n');
|
|
531
|
+
if (payload.declaredIn) {
|
|
532
|
+
process.stdout.write(kv('declared in', payload.declaredIn.path ?? payload.declaredIn.id) + '\n');
|
|
533
|
+
}
|
|
506
534
|
if (payload.symbols.length > 0) {
|
|
507
535
|
process.stdout.write(`\nDeclares ${payload.symbols.length} symbols:\n`);
|
|
508
536
|
for (const s of payload.symbols.slice(0, 20)) {
|
|
509
537
|
process.stdout.write(` ${s.label}${s.line ? ':' + s.line : ''}\n`);
|
|
510
538
|
}
|
|
511
539
|
}
|
|
540
|
+
if (payload.referencedBy.length > 0) {
|
|
541
|
+
process.stdout.write(`\nReferenced by (${payload.referencedBy.length}):\n`);
|
|
542
|
+
for (const r of payload.referencedBy.slice(0, 20)) {
|
|
543
|
+
process.stdout.write(` ← ${r.path ?? r.id}\n`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
if (payload.calledBy.length > 0) {
|
|
547
|
+
process.stdout.write(`\nCalled by (${payload.calledBy.length}):\n`);
|
|
548
|
+
for (const c of payload.calledBy.slice(0, 20)) {
|
|
549
|
+
process.stdout.write(` ← ${c.path ?? c.id}\n`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
512
552
|
if (payload.importsFrom.length > 0) {
|
|
513
553
|
process.stdout.write(`\nImports from (${payload.importsFrom.length}):\n`);
|
|
514
554
|
for (const o of payload.importsFrom.slice(0, 20)) {
|
|
@@ -610,7 +650,7 @@ export async function runGraphImpact(args) {
|
|
|
610
650
|
process.stderr.write(`No graph node matched "${target}".\n`);
|
|
611
651
|
return 1;
|
|
612
652
|
}
|
|
613
|
-
const closure = reverseClosure(api, anchor
|
|
653
|
+
const closure = reverseClosure(api, anchor, maxDepth, limit);
|
|
614
654
|
const direct = closure.layer[1] ?? [];
|
|
615
655
|
const transitive = closure.all.filter((id) => id !== anchor.id && !direct.includes(id));
|
|
616
656
|
const payload = {
|
|
@@ -740,6 +780,26 @@ function collectSearchMatches(api, query, kind, limit) {
|
|
|
740
780
|
const f = api.findFile(query);
|
|
741
781
|
if (f)
|
|
742
782
|
out.push(f);
|
|
783
|
+
// Fuzzy fallback: substring match on path/basename so `shrk graph
|
|
784
|
+
// search Foo --kind file` finds `libs/x/y/Foo.ts` without forcing the
|
|
785
|
+
// caller to type the full path. Skips the node if exact match already
|
|
786
|
+
// included it.
|
|
787
|
+
if (out.length < limit) {
|
|
788
|
+
const q = query.toLowerCase();
|
|
789
|
+
const seen = new Set(out.map((n) => n.id));
|
|
790
|
+
for (const node of api.allFiles()) {
|
|
791
|
+
if (seen.has(node.id))
|
|
792
|
+
continue;
|
|
793
|
+
const p = node.path?.toLowerCase() ?? '';
|
|
794
|
+
const base = p.includes('/') ? p.slice(p.lastIndexOf('/') + 1) : p;
|
|
795
|
+
if (base.includes(q) || p.includes(q)) {
|
|
796
|
+
out.push(node);
|
|
797
|
+
seen.add(node.id);
|
|
798
|
+
if (out.length >= limit)
|
|
799
|
+
break;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
743
803
|
}
|
|
744
804
|
if (!kind || kind === 'symbol') {
|
|
745
805
|
for (const s of api.findSymbol(query, { exact: false, limit }))
|
|
@@ -752,21 +812,29 @@ function collectSearchMatches(api, query, kind, limit) {
|
|
|
752
812
|
}
|
|
753
813
|
return out.slice(0, limit);
|
|
754
814
|
}
|
|
755
|
-
function reverseClosure(api,
|
|
756
|
-
const seen = new Set([
|
|
815
|
+
function reverseClosure(api, anchor, maxDepth, limit) {
|
|
816
|
+
const seen = new Set([anchor.id]);
|
|
757
817
|
const layer = {};
|
|
758
|
-
let frontier =
|
|
759
|
-
let depth = 1;
|
|
818
|
+
let frontier = directDependentsForAnchor(api, anchor);
|
|
760
819
|
let truncated = false;
|
|
761
|
-
|
|
820
|
+
frontier = frontier.filter((id) => !seen.has(id));
|
|
821
|
+
if (frontier.length > limit) {
|
|
822
|
+
frontier = frontier.slice(0, limit);
|
|
823
|
+
truncated = true;
|
|
824
|
+
}
|
|
825
|
+
for (const id of frontier)
|
|
826
|
+
seen.add(id);
|
|
827
|
+
if (frontier.length > 0)
|
|
828
|
+
layer[1] = frontier;
|
|
829
|
+
let depth = 2;
|
|
830
|
+
while (depth <= maxDepth && frontier.length > 0 && !truncated) {
|
|
762
831
|
const next = [];
|
|
763
832
|
for (const id of frontier) {
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
if (seen.has(imp.id))
|
|
833
|
+
for (const dep of nextDependents(api, anchor.kind, id)) {
|
|
834
|
+
if (seen.has(dep.id))
|
|
767
835
|
continue;
|
|
768
|
-
seen.add(
|
|
769
|
-
next.push(
|
|
836
|
+
seen.add(dep.id);
|
|
837
|
+
next.push(dep.id);
|
|
770
838
|
if (seen.size - 1 >= limit) {
|
|
771
839
|
truncated = true;
|
|
772
840
|
break;
|
|
@@ -779,11 +847,50 @@ function reverseClosure(api, startId, maxDepth, limit) {
|
|
|
779
847
|
layer[depth] = next;
|
|
780
848
|
frontier = next;
|
|
781
849
|
depth += 1;
|
|
782
|
-
if (truncated)
|
|
783
|
-
break;
|
|
784
850
|
}
|
|
785
851
|
return { all: [...seen], layer, truncated };
|
|
786
852
|
}
|
|
853
|
+
function directDependentsForAnchor(api, anchor) {
|
|
854
|
+
if (anchor.kind === NodeKind.Symbol) {
|
|
855
|
+
const owner = declaringFileOf(api, anchor.id);
|
|
856
|
+
const refs = dedupeNodes([...api.referencesOf(anchor.id), ...api.callersOf(anchor.id)])
|
|
857
|
+
.filter((n) => n.kind === NodeKind.File && n.id !== owner?.id)
|
|
858
|
+
.map((n) => n.id);
|
|
859
|
+
if (refs.length > 0)
|
|
860
|
+
return refs;
|
|
861
|
+
return owner ? api.importersOf(owner.id).map((n) => n.id) : [];
|
|
862
|
+
}
|
|
863
|
+
if (anchor.kind === NodeKind.Package) {
|
|
864
|
+
return api.packageDependents(packageNameFor(anchor)).map((n) => n.id);
|
|
865
|
+
}
|
|
866
|
+
return api.importersOf(anchor.id).map((n) => n.id);
|
|
867
|
+
}
|
|
868
|
+
function nextDependents(api, anchorKind, nodeId) {
|
|
869
|
+
if (anchorKind === NodeKind.Package) {
|
|
870
|
+
const node = api.neighbours(nodeId)?.node;
|
|
871
|
+
if (!node)
|
|
872
|
+
return [];
|
|
873
|
+
return api.packageDependents(packageNameFor(node));
|
|
874
|
+
}
|
|
875
|
+
return api.importersOf(nodeId);
|
|
876
|
+
}
|
|
877
|
+
function declaringFileOf(api, symbolId) {
|
|
878
|
+
const neighbours = api.neighbours(symbolId);
|
|
879
|
+
if (!neighbours)
|
|
880
|
+
return undefined;
|
|
881
|
+
for (const incoming of neighbours.in) {
|
|
882
|
+
if (incoming.edge.kind !== EdgeKind.DeclaresSymbol)
|
|
883
|
+
continue;
|
|
884
|
+
if ('resolved' in incoming.source)
|
|
885
|
+
continue;
|
|
886
|
+
if (incoming.source.kind === NodeKind.File)
|
|
887
|
+
return incoming.source;
|
|
888
|
+
}
|
|
889
|
+
return undefined;
|
|
890
|
+
}
|
|
891
|
+
function packageNameFor(node) {
|
|
892
|
+
return node.id.startsWith('package:') ? node.id.slice('package:'.length) : node.label;
|
|
893
|
+
}
|
|
787
894
|
function nodeSummary(n) {
|
|
788
895
|
return {
|
|
789
896
|
id: n.id,
|
|
@@ -816,3 +923,14 @@ function sumValues(record) {
|
|
|
816
923
|
n += v;
|
|
817
924
|
return n;
|
|
818
925
|
}
|
|
926
|
+
function dedupeNodes(nodes) {
|
|
927
|
+
const seen = new Set();
|
|
928
|
+
const out = [];
|
|
929
|
+
for (const node of nodes) {
|
|
930
|
+
if (seen.has(node.id))
|
|
931
|
+
continue;
|
|
932
|
+
seen.add(node.id);
|
|
933
|
+
out.push(node);
|
|
934
|
+
}
|
|
935
|
+
return out;
|
|
936
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.command.d.ts","sourceRoot":"","sources":["../../src/commands/graph.command.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0BhC,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"graph.command.d.ts","sourceRoot":"","sources":["../../src/commands/graph.command.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0BhC,eAAO,MAAM,YAAY,EAAE,eA2M1B,CAAC"}
|
|
@@ -17,8 +17,9 @@ const KNOWN_KINDS = [
|
|
|
17
17
|
];
|
|
18
18
|
export const graphCommand = {
|
|
19
19
|
name: 'graph',
|
|
20
|
-
description: 'Show the SharkCraft knowledge graph
|
|
21
|
-
usage: 'shrk [--cwd <dir>] graph [<id>] [--type <kind>] [--format text|json|dot|mermaid] [--output <file>] [--json]
|
|
20
|
+
description: 'Show the SharkCraft knowledge graph and the code-intelligence graph surface. Use `shrk graph <id>` for asset-graph nodes and `shrk graph index|status|search|context|impact|callers|cycles|unresolved|deps|why|export` for code-graph workflows.',
|
|
21
|
+
usage: 'shrk [--cwd <dir>] graph [<id>] [--type <kind>] [--format text|json|dot|mermaid] [--output <file>] [--json]\n' +
|
|
22
|
+
'shrk graph index|status|search|context|impact|callers|cycles|unresolved|deps|why|export ...',
|
|
22
23
|
async run(args) {
|
|
23
24
|
// Code-intelligence subverbs (R65) don't need the knowledge graph —
|
|
24
25
|
// dispatch them before the expensive inspection so they stay fast.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.command.d.ts","sourceRoot":"","sources":["../../src/commands/help.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"help.command.d.ts","sourceRoot":"","sources":["../../src/commands/help.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAqB9D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAmD1C;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe;;;;cAK3C;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAA;KAAE,GAAG,MAAM;EA2HpF"}
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import { header } from "../output/format-output.js";
|
|
2
2
|
import { COMMAND_CATALOG, defaultShowInHelp } from "./command-catalog.js";
|
|
3
|
+
const EXTRA_HELP_LINES = Object.freeze({
|
|
4
|
+
graph: [
|
|
5
|
+
'',
|
|
6
|
+
'Code-intelligence subverbs:',
|
|
7
|
+
' graph index — build or refresh the code graph',
|
|
8
|
+
' graph status — freshness, counts, and unresolved-import summary',
|
|
9
|
+
' graph search — find files/symbols/packages in the code graph',
|
|
10
|
+
' graph context — inspect one file or symbol with bridge enrichment',
|
|
11
|
+
' graph impact — reverse dependent closure for a file or symbol',
|
|
12
|
+
' graph callers — files that call/reference a symbol',
|
|
13
|
+
' graph cycles — list import cycles',
|
|
14
|
+
' graph unresolved — list unresolved imports grouped by file',
|
|
15
|
+
' graph deps — inbound/outbound package dependencies',
|
|
16
|
+
' graph why — shortest-path explanation in the knowledge graph',
|
|
17
|
+
],
|
|
18
|
+
});
|
|
3
19
|
/**
|
|
4
20
|
* Product start screen for bare `shrk` / `shrk --help`. Shows the
|
|
5
21
|
* curated ~20-command "starter" surface organized by workflow phase.
|
|
@@ -28,6 +44,7 @@ export function renderStartScreen() {
|
|
|
28
44
|
lines.push(' $ shrk recommend "<task>" — what should I do?');
|
|
29
45
|
lines.push(' $ shrk context --task "<task>" — token-budgeted relevant context');
|
|
30
46
|
lines.push(' $ shrk task "<task>" — full AI-ready task packet (JSON)');
|
|
47
|
+
lines.push(' $ shrk code-intel — one-shot code-intelligence health summary');
|
|
31
48
|
lines.push(' $ shrk coverage — what knowledge is missing');
|
|
32
49
|
lines.push('');
|
|
33
50
|
lines.push('Generate code safely:');
|
|
@@ -37,6 +54,7 @@ export function renderStartScreen() {
|
|
|
37
54
|
lines.push(' $ shrk quality — pre-PR gate (doctor + boundaries + coverage + drift)');
|
|
38
55
|
lines.push('');
|
|
39
56
|
lines.push('Browse what shrk knows:');
|
|
57
|
+
lines.push(' $ shrk graph status — current code-graph freshness and health');
|
|
40
58
|
lines.push(' $ shrk knowledge list — knowledge entries');
|
|
41
59
|
lines.push(' $ shrk rules list — rules + conventions');
|
|
42
60
|
lines.push(' $ shrk templates list — generator templates');
|
|
@@ -76,10 +94,13 @@ export function makeHelpCommand(registry) {
|
|
|
76
94
|
? args.positional[0].split(/\s+/).filter(Boolean)
|
|
77
95
|
: args.positional.filter(Boolean);
|
|
78
96
|
const { handler, matchedPath, node } = registry.resolve(tokens);
|
|
79
|
-
if (handler && matchedPath.join(' ') === tokens.join(' ')) {
|
|
97
|
+
if (handler && matchedPath.join(' ') === tokens.join(' ') && node.children.size === 0) {
|
|
80
98
|
// Exact match on a callable command.
|
|
81
99
|
const canonical = registry.listCommandAliases().get(tokens[0]);
|
|
82
100
|
process.stdout.write(`${matchedPath.join(' ')} — ${handler.description}\n${handler.usage}\n`);
|
|
101
|
+
const extra = EXTRA_HELP_LINES[matchedPath.join(' ')];
|
|
102
|
+
if (extra)
|
|
103
|
+
process.stdout.write(extra.join('\n') + '\n');
|
|
83
104
|
if (canonical && tokens.length === 1) {
|
|
84
105
|
process.stdout.write(`(alias for: ${canonical})\n`);
|
|
85
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impact.command.d.ts","sourceRoot":"","sources":["../../src/commands/impact.command.ts"],"names":[],"mappings":"AAsBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"impact.command.d.ts","sourceRoot":"","sources":["../../src/commands/impact.command.ts"],"names":[],"mappings":"AAsBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0VhC,eAAO,MAAM,aAAa,EAAE,eA8V3B,CAAC"}
|
|
@@ -209,13 +209,14 @@ async function runViaGraph(args) {
|
|
|
209
209
|
const cwd = resolveCwd(args);
|
|
210
210
|
const wantJson = flagBool(args, 'json') || flagString(args, 'format') === 'json';
|
|
211
211
|
const positional = args.positional[0];
|
|
212
|
+
const viaGraphRaw = args.flags.get('via-graph');
|
|
212
213
|
const files = flagList(args, 'files');
|
|
213
214
|
const since = flagString(args, 'since');
|
|
214
215
|
const symbol = flagString(args, 'symbol');
|
|
215
216
|
const fileFlag = flagString(args, 'file');
|
|
216
217
|
const limit = flagNumber(args, 'limit') ?? 200;
|
|
217
218
|
const maxDepth = flagNumber(args, 'max-depth') ?? 5;
|
|
218
|
-
const target = positional ?? fileFlag;
|
|
219
|
+
const target = positional ?? fileFlag ?? (typeof viaGraphRaw === 'string' ? viaGraphRaw : undefined);
|
|
219
220
|
const inputs = files.length > 0
|
|
220
221
|
? { kind: 'files', files }
|
|
221
222
|
: symbol
|
|
@@ -295,7 +296,7 @@ export const impactCommand = {
|
|
|
295
296
|
// graph-backed payload (sharkcraft.graph-impact-analysis/v3). Keeps
|
|
296
297
|
// the legacy v2 inspector path as the default so existing
|
|
297
298
|
// consumers don't shift.
|
|
298
|
-
if (
|
|
299
|
+
if (args.flags.has('via-graph')) {
|
|
299
300
|
return runViaGraph(args);
|
|
300
301
|
}
|
|
301
302
|
const cwd = resolveCwd(args);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ICommandHandler } from '../command-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* `shrk move-plan <source> <target>` — emit a structured plan for
|
|
4
|
+
* moving a source file to a new location. Read-only: NEVER moves
|
|
5
|
+
* anything itself, never rewrites imports. The agent (or a human)
|
|
6
|
+
* uses the plan to do the actual work.
|
|
7
|
+
*
|
|
8
|
+
* Covers:
|
|
9
|
+
* - graph-traced importer rewrites (relative + package-name imports)
|
|
10
|
+
* - exports to revisit if the source was re-exported from an index
|
|
11
|
+
* - cross-package warnings (layer-order risks)
|
|
12
|
+
* - a rollback plan that's the literal reverse of the move
|
|
13
|
+
* - validation commands to run after applying
|
|
14
|
+
*
|
|
15
|
+
* Limitations:
|
|
16
|
+
* - single-file only. Directory moves can be approximated by
|
|
17
|
+
* listing the directory and running this command per file, or
|
|
18
|
+
* wait for a `--folder` follow-up.
|
|
19
|
+
* - `from '@shrkcrft/pkg/sub'` deep-import rewrites are best-effort;
|
|
20
|
+
* ambiguous cases get reported as `review-manually`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const movePlanCommand: ICommandHandler;
|
|
23
|
+
//# sourceMappingURL=move-plan.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-plan.command.d.ts","sourceRoot":"","sources":["../../src/commands/move-plan.command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AAqCrG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,eAAe,EAAE,eA4M7B,CAAC"}
|