@shrkcrft/cli 0.1.0-alpha.17 → 0.1.0-alpha.19
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/command-registry.d.ts +10 -0
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +7 -1
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +12 -0
- package/dist/commands/compress.command.d.ts +0 -7
- package/dist/commands/compress.command.d.ts.map +1 -1
- package/dist/commands/compress.command.js +7 -0
- package/dist/commands/delegate.command.d.ts +65 -0
- package/dist/commands/delegate.command.d.ts.map +1 -0
- package/dist/commands/delegate.command.js +657 -0
- package/dist/commands/deps-audit.command.js +1 -1
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +24 -3
- package/dist/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +13 -1
- package/dist/commands/graph-code-subverbs.d.ts +22 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
- package/dist/commands/graph-code-subverbs.js +476 -55
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +9 -3
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +7 -18
- package/dist/commands/knowledge-author.command.d.ts.map +1 -1
- package/dist/commands/knowledge-author.command.js +9 -0
- package/dist/commands/knowledge-propose.command.d.ts.map +1 -1
- package/dist/commands/knowledge-propose.command.js +4 -2
- package/dist/commands/knowledge.command.d.ts.map +1 -1
- package/dist/commands/knowledge.command.js +22 -2
- package/dist/commands/move-plan.command.js +1 -1
- package/dist/commands/preflight.command.d.ts.map +1 -1
- package/dist/commands/preflight.command.js +15 -0
- package/dist/commands/recommend.command.d.ts +6 -0
- package/dist/commands/recommend.command.d.ts.map +1 -1
- package/dist/commands/recommend.command.js +72 -0
- package/dist/commands/rules.command.d.ts.map +1 -1
- package/dist/commands/rules.command.js +20 -3
- package/dist/commands/smart-context.command.d.ts +26 -17
- package/dist/commands/smart-context.command.d.ts.map +1 -1
- package/dist/commands/smart-context.command.js +113 -16
- package/dist/commands/tests.command.d.ts.map +1 -1
- package/dist/commands/tests.command.js +13 -2
- package/dist/dashboard/code-intelligence-data.d.ts.map +1 -1
- package/dist/dashboard/code-intelligence-data.js +25 -3
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -1
- package/dist/output/ccr-store-config.d.ts +1 -1
- package/dist/output/ccr-store-config.d.ts.map +1 -1
- package/dist/output/ccr-store-config.js +21 -2
- package/package.json +33 -33
|
@@ -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;
|
|
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;AA4BhC,eAAO,MAAM,YAAY,EAAE,eA+M1B,CAAC"}
|
|
@@ -3,7 +3,7 @@ import * as nodePath from 'node:path';
|
|
|
3
3
|
import { analyzeImportGraph, buildKnowledgeGraph, findGraphPath, getGraphNode, inspectSharkcraft, } from '@shrkcrft/inspector';
|
|
4
4
|
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
5
5
|
import { asJson, header, kv } from "../output/format-output.js";
|
|
6
|
-
import { runGraphCallers, runGraphContext, runGraphCycles, runGraphDeps, runGraphImpact, runGraphIndex, runGraphSearch, runGraphStatus, runGraphUnresolved, } from "./graph-code-subverbs.js";
|
|
6
|
+
import { runGraphCallers, runGraphContext, runGraphCycles, runGraphDeps, runGraphHubs, runGraphImpact, runGraphIndex, runGraphPath, runGraphSearch, runGraphStatus, runGraphUnresolved, } from "./graph-code-subverbs.js";
|
|
7
7
|
const KNOWN_KINDS = [
|
|
8
8
|
'knowledge',
|
|
9
9
|
'rule',
|
|
@@ -17,9 +17,11 @@ const KNOWN_KINDS = [
|
|
|
17
17
|
];
|
|
18
18
|
export const graphCommand = {
|
|
19
19
|
name: 'graph',
|
|
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.',
|
|
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|path|hubs|callers|cycles|unresolved|deps|why|export` for code-graph workflows.',
|
|
21
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
|
+
'shrk graph index|status|search|context|impact|path|hubs|callers|cycles|unresolved|deps|why|export ...\n' +
|
|
23
|
+
'shrk graph path <from> <to> — is code A wired to code B? (shortest import/call path)\n' +
|
|
24
|
+
'shrk graph hubs [--limit N] [--path <dir>] — most-depended-on symbols/files (load-bearing code; scope to a subsystem)',
|
|
23
25
|
async run(args) {
|
|
24
26
|
// Code-intelligence subverbs (R65) don't need the knowledge graph —
|
|
25
27
|
// dispatch them before the expensive inspection so they stay fast.
|
|
@@ -34,6 +36,10 @@ export const graphCommand = {
|
|
|
34
36
|
return runGraphContext(args);
|
|
35
37
|
if (earlySub === 'impact')
|
|
36
38
|
return runGraphImpact(args);
|
|
39
|
+
if (earlySub === 'path')
|
|
40
|
+
return runGraphPath(args);
|
|
41
|
+
if (earlySub === 'hubs')
|
|
42
|
+
return runGraphHubs(args);
|
|
37
43
|
if (earlySub === 'callers')
|
|
38
44
|
return runGraphCallers(args);
|
|
39
45
|
if (earlySub === 'cycles')
|
|
@@ -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;AAqB9D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,
|
|
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,CAwC1C;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"}
|
|
@@ -31,21 +31,16 @@ export function renderStartScreen() {
|
|
|
31
31
|
lines.push('Usage: shrk [--cwd <dir>] <command> [...args]');
|
|
32
32
|
lines.push('');
|
|
33
33
|
lines.push('Bootstrap:');
|
|
34
|
-
lines.push(' $ shrk init --infer --write — scan the repo + populate sharkcraft/ from real signals (
|
|
35
|
-
lines.push(' $ shrk import claude-md ./CLAUDE.md --populate --write — populate sharkcraft/ from existing CLAUDE.md / AGENTS.md / .cursor/rules');
|
|
36
|
-
lines.push(' $ shrk init --with-claude-skill --write — scaffold sharkcraft/ AND inline rules into .claude/skills/ (one-step)');
|
|
37
|
-
lines.push(' $ shrk init — scaffold sharkcraft/ + config skeleton (preset defaults)');
|
|
34
|
+
lines.push(' $ shrk init --infer --write — scan the repo + populate sharkcraft/ from real signals (new repos)');
|
|
38
35
|
lines.push(' $ shrk doctor — is the workspace healthy?');
|
|
39
|
-
lines.push(' $ shrk inspect — detect frameworks, paths, package manager');
|
|
40
36
|
lines.push(' $ shrk onboard — analyze an existing repo (advisory)');
|
|
41
37
|
lines.push('');
|
|
42
38
|
lines.push('Use it for a task:');
|
|
43
|
-
lines.push(' $ shrk brief — single-page brief Claude reads first (project + rules + paths + verification)');
|
|
44
39
|
lines.push(' $ shrk recommend "<task>" — what should I do?');
|
|
45
40
|
lines.push(' $ shrk context --task "<task>" — token-budgeted relevant context');
|
|
46
41
|
lines.push(' $ shrk task "<task>" — full AI-ready task packet (JSON)');
|
|
47
|
-
lines.push(' $ shrk
|
|
48
|
-
lines.push(' $ shrk
|
|
42
|
+
lines.push(' $ shrk why <file> — which rules govern this file');
|
|
43
|
+
lines.push(' $ shrk impact <file> — blast radius: what breaks if I change this');
|
|
49
44
|
lines.push('');
|
|
50
45
|
lines.push('Generate code safely:');
|
|
51
46
|
lines.push(' $ shrk gen <template> <name> — generate from template (dry-run by default)');
|
|
@@ -54,22 +49,16 @@ export function renderStartScreen() {
|
|
|
54
49
|
lines.push(' $ shrk quality — pre-PR gate (doctor + boundaries + coverage + drift)');
|
|
55
50
|
lines.push('');
|
|
56
51
|
lines.push('Browse what shrk knows:');
|
|
57
|
-
lines.push(' $ shrk graph status
|
|
52
|
+
lines.push(' $ shrk graph status — code-graph freshness and health');
|
|
53
|
+
lines.push(' $ shrk coverage — what knowledge is missing');
|
|
58
54
|
lines.push(' $ shrk knowledge list — knowledge entries');
|
|
59
|
-
lines.push(' $ shrk rules list — rules + conventions');
|
|
60
|
-
lines.push(' $ shrk templates list — generator templates');
|
|
61
|
-
lines.push(' $ shrk import — parse AGENTS.md / CLAUDE.md / .cursor/rules');
|
|
62
|
-
lines.push(' $ shrk export — render to a flat agent-rule file');
|
|
63
55
|
lines.push('');
|
|
64
56
|
lines.push('Run shrk for an agent:');
|
|
65
|
-
lines.push(' $ shrk export claude-skill --write — generate .claude/skills/<name>/SKILL.md (rules INTO the prompt — no MCP roundtrip)');
|
|
66
|
-
lines.push(' $ shrk export agents-md --write — generate AGENTS.md / CLAUDE.md / .cursor/rules / copilot-instructions');
|
|
67
57
|
lines.push(' $ shrk mcp serve — start the MCP server (stdio) for live queries');
|
|
68
58
|
lines.push(' $ shrk dashboard — start the local read-only dashboard');
|
|
69
59
|
lines.push('');
|
|
70
|
-
lines.push('Discover the rest (
|
|
71
|
-
lines.push(' $ shrk surface list — full
|
|
72
|
-
lines.push(' $ shrk surface profiles — named profiles (small-app / monorepo / ci / agent / pack-author)');
|
|
60
|
+
lines.push('Discover the rest (everything stays callable — this screen shows ~17 of ~70 verbs):');
|
|
61
|
+
lines.push(' $ shrk surface list — full catalog by tier');
|
|
73
62
|
lines.push(' $ shrk help <command> — usage for a specific command');
|
|
74
63
|
lines.push(' $ shrk --full-help — long, exhaustive help');
|
|
75
64
|
lines.push(' $ shrk --about — what shrk is and is not');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge-author.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-author.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoBH,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAwChC,eAAO,MAAM,mBAAmB,EAAE,eAgEjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eA0GpC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAoEpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"knowledge-author.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-author.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoBH,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAwChC,eAAO,MAAM,mBAAmB,EAAE,eAgEjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eA0GpC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAoEpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAsElC,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,eAmB3C,CAAC"}
|
|
@@ -300,6 +300,15 @@ export const knowledgeLintCommand = {
|
|
|
300
300
|
async run(args) {
|
|
301
301
|
const cwd = resolveCwd(args);
|
|
302
302
|
const inspection = await inspectSharkcraft({ cwd });
|
|
303
|
+
// Loud guard: a 0-entry scan is NOT a clean pass — it almost always means
|
|
304
|
+
// the loader found nothing (wrong cwd / no `sharkcraft/` folder / no
|
|
305
|
+
// entries), which otherwise reads as "lint passed". Surface it on stderr so
|
|
306
|
+
// it can't be mistaken for success, while keeping stdout/JSON clean.
|
|
307
|
+
if (inspection.knowledgeEntries.length === 0) {
|
|
308
|
+
process.stderr.write('WARN knowledge lint scanned 0 entries — there is nothing to lint (this is NOT a clean pass).\n' +
|
|
309
|
+
' Likely causes: no `sharkcraft/` folder here, not at the workspace root, or no\n' +
|
|
310
|
+
' knowledge entries are defined. Run `shrk doctor` to confirm how many entries load.\n');
|
|
311
|
+
}
|
|
303
312
|
const entryIds = flagList(args, 'id');
|
|
304
313
|
const includeAdvisory = !flagBool(args, 'no-advisory');
|
|
305
314
|
const stale = buildKnowledgeStaleReport(inspection);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge-propose.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-propose.command.ts"],"names":[],"mappings":"AAqBA,OAAO,
|
|
1
|
+
{"version":3,"file":"knowledge-propose.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-propose.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkDhC,eAAO,MAAM,uBAAuB,EAAE,eA4ErC,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
11
11
|
import * as nodePath from 'node:path';
|
|
12
12
|
import { AssetKind, AssetProvenanceOperation, KNOWLEDGE_PROPOSE_SCHEMA, proposeKnowledge, recordProvenance, renderKnowledgeProposeMarkdown, } from '@shrkcrft/inspector';
|
|
13
|
-
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
13
|
+
import { flagBool, flagNumber, flagString, resolveCwd, } from "../command-registry.js";
|
|
14
14
|
import { asJson } from "../output/format-output.js";
|
|
15
15
|
import { detectAuthoringSource } from "../authoring/authoring-kit.js";
|
|
16
16
|
function renderProposalAsTs(p) {
|
|
@@ -54,13 +54,14 @@ function writeDraftFiles(cwd, report) {
|
|
|
54
54
|
export const knowledgeProposeCommand = {
|
|
55
55
|
name: 'propose',
|
|
56
56
|
description: 'Propose stub knowledge entries for exported top-level constructs that lack coverage. Preview-first; --write materialises drafts under .sharkcraft/authoring/proposed/.',
|
|
57
|
-
usage: 'shrk knowledge propose [--path <file>] [--symbol <name>] [--since <ref>|--all] [--json] [--write]',
|
|
57
|
+
usage: 'shrk knowledge propose [--path <file>] [--symbol <name>] [--since <ref>|--all] [--max <n>] [--json] [--write]',
|
|
58
58
|
async run(args) {
|
|
59
59
|
const cwd = resolveCwd(args);
|
|
60
60
|
const path = flagString(args, 'path');
|
|
61
61
|
const symbol = flagString(args, 'symbol');
|
|
62
62
|
const sinceFlag = flagString(args, 'since');
|
|
63
63
|
const all = flagBool(args, 'all');
|
|
64
|
+
const max = flagNumber(args, 'max');
|
|
64
65
|
const since = path
|
|
65
66
|
? undefined
|
|
66
67
|
: symbol
|
|
@@ -73,6 +74,7 @@ export const knowledgeProposeCommand = {
|
|
|
73
74
|
...(path ? { path } : {}),
|
|
74
75
|
...(symbol ? { symbol } : {}),
|
|
75
76
|
...(since !== undefined ? { since } : {}),
|
|
77
|
+
...(max !== undefined && max >= 0 ? { max } : {}),
|
|
76
78
|
});
|
|
77
79
|
if (flagBool(args, 'json')) {
|
|
78
80
|
const payload = flagBool(args, 'write')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.command.ts"],"names":[],"mappings":"AAaA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAoFhC,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"knowledge.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.command.ts"],"names":[],"mappings":"AAaA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAoFhC,eAAO,MAAM,oBAAoB,EAAE,eA2ClC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAqCpC,CAAC;AAoBF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AA8NF,eAAO,MAAM,sBAAsB,EAAE,eAQpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8CxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAuBrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,eA8B1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8BxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,eAkC1C,CAAC"}
|
|
@@ -54,7 +54,7 @@ ${p.ci.exitNonZero ? `<p style="color:#a40000;font-weight:bold">FAIL: ${esc(p.ci
|
|
|
54
54
|
export const knowledgeListCommand = {
|
|
55
55
|
name: 'list',
|
|
56
56
|
description: 'List knowledge entries.',
|
|
57
|
-
usage: 'shrk knowledge list [--type rule] [--scope x,y] [--json]',
|
|
57
|
+
usage: 'shrk knowledge list [--type rule] [--scope x,y] [--top N] [--brief] [--json]',
|
|
58
58
|
async run(args) {
|
|
59
59
|
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
60
60
|
const types = flagList(args, 'type');
|
|
@@ -64,8 +64,28 @@ export const knowledgeListCommand = {
|
|
|
64
64
|
entries = entries.filter((e) => types.includes(String(e.type)));
|
|
65
65
|
if (scope.length)
|
|
66
66
|
entries = entries.filter((e) => scope.some((s) => e.scope.includes(s)));
|
|
67
|
+
// --top N: a deterministic, token-bounded slice. Sort by id first so the
|
|
68
|
+
// "top N" is stable across machines (entries otherwise load in fs-scan
|
|
69
|
+
// order). Reduce at the source instead of piping through `shrk compress`.
|
|
70
|
+
const top = flagNumber(args, 'top');
|
|
71
|
+
if (top !== undefined && top > 0) {
|
|
72
|
+
entries = [...entries].sort((a, b) => a.id.localeCompare(b.id)).slice(0, top);
|
|
73
|
+
}
|
|
67
74
|
if (flagBool(args, 'json')) {
|
|
68
|
-
|
|
75
|
+
// --brief: project to the high-signal fields, dropping content / examples
|
|
76
|
+
// / metadata (the bulk of the payload) so an agent pays far fewer tokens.
|
|
77
|
+
const payload = flagBool(args, 'brief')
|
|
78
|
+
? entries.map((e) => ({
|
|
79
|
+
id: e.id,
|
|
80
|
+
type: e.type,
|
|
81
|
+
priority: e.priority,
|
|
82
|
+
title: e.title,
|
|
83
|
+
scope: e.scope,
|
|
84
|
+
tags: e.tags,
|
|
85
|
+
appliesWhen: e.appliesWhen,
|
|
86
|
+
}))
|
|
87
|
+
: entries.map((e) => ({ ...e }));
|
|
88
|
+
process.stdout.write(asJson(payload) + '\n');
|
|
69
89
|
return 0;
|
|
70
90
|
}
|
|
71
91
|
process.stdout.write(header(`Knowledge (${entries.length})`));
|
|
@@ -48,7 +48,7 @@ export const movePlanCommand = {
|
|
|
48
48
|
}
|
|
49
49
|
const store = new GraphStore(cwd);
|
|
50
50
|
if (!store.exists()) {
|
|
51
|
-
process.stderr.write('No SharkCraft graph found. Run `shrk graph
|
|
51
|
+
process.stderr.write('No SharkCraft graph found. Run `shrk graph index` so move-plan can trace importers.\n');
|
|
52
52
|
return 1;
|
|
53
53
|
}
|
|
54
54
|
const api = GraphQueryApi.fromStore(cwd);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight.command.d.ts","sourceRoot":"","sources":["../../src/commands/preflight.command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"preflight.command.d.ts","sourceRoot":"","sources":["../../src/commands/preflight.command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAiBhC,eAAO,MAAM,gBAAgB,EAAE,eAoG9B,CAAC"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { planChangedPreflight, PreflightAction, PreflightProfile, renderChangedPreflightText, resolveChangedFiles, } from '@shrkcrft/inspector';
|
|
15
15
|
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
16
|
+
import { loadProjectConfig } from '@shrkcrft/config';
|
|
16
17
|
import { asJson, header } from "../output/format-output.js";
|
|
17
18
|
function parseProfile(value) {
|
|
18
19
|
if (value === 'quick')
|
|
@@ -55,10 +56,24 @@ export const preflightCommand = {
|
|
|
55
56
|
resolveOpts.includeWorktree = true;
|
|
56
57
|
}
|
|
57
58
|
const changed = resolveChangedFiles(resolveOpts);
|
|
59
|
+
// Ground the test/typecheck gates in the project's declared verification
|
|
60
|
+
// commands when present, rather than the generic `bun test` / tsc defaults.
|
|
61
|
+
// Best-effort: a repo without sharkcraft/ config keeps the defaults.
|
|
62
|
+
let testCommand;
|
|
63
|
+
let typecheckCommand;
|
|
64
|
+
const loaded = await loadProjectConfig(cwd);
|
|
65
|
+
if (loaded.ok) {
|
|
66
|
+
const vcs = loaded.value.config.verificationCommands ?? [];
|
|
67
|
+
const pick = (...ids) => vcs.find((v) => ids.includes(v.id))?.command;
|
|
68
|
+
testCommand = pick('test', 'tests', 'unit', 'unit-tests');
|
|
69
|
+
typecheckCommand = pick('typecheck', 'tsc', 'types', 'typecheck-all');
|
|
70
|
+
}
|
|
58
71
|
const plan = planChangedPreflight({
|
|
59
72
|
projectRoot: cwd,
|
|
60
73
|
changedFiles: changed.files,
|
|
61
74
|
profile,
|
|
75
|
+
...(testCommand ? { testCommand } : {}),
|
|
76
|
+
...(typecheckCommand ? { typecheckCommand } : {}),
|
|
62
77
|
});
|
|
63
78
|
if (flagBool(args, 'json')) {
|
|
64
79
|
process.stdout.write(asJson({ plan, scopeMode: changed.mode }) + '\n');
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { type ICommandHandler } from '../command-registry.js';
|
|
2
2
|
export declare const recommendCommand: ICommandHandler;
|
|
3
|
+
/**
|
|
4
|
+
* Does the query look like create/build work (a routing hint's `shrk gen`
|
|
5
|
+
* playbook is most useful here)? Mirrors {@link looksLikePlanning}: a
|
|
6
|
+
* create/build verb leading the query or in slots 1–3.
|
|
7
|
+
*/
|
|
8
|
+
export declare function looksLikeCreateBuild(query: string): boolean;
|
|
3
9
|
export declare function looksLikePlanning(query: string): boolean;
|
|
4
10
|
//# sourceMappingURL=recommend.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recommend.command.d.ts","sourceRoot":"","sources":["../../src/commands/recommend.command.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAShC,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"recommend.command.d.ts","sourceRoot":"","sources":["../../src/commands/recommend.command.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAShC,eAAO,MAAM,gBAAgB,EAAE,eA+M9B,CAAC;AAgHF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAY3D;AAcD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAcxD"}
|
|
@@ -79,6 +79,36 @@ export const recommendCommand = {
|
|
|
79
79
|
searchReport = null;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
// R1 — promote a strongly-matched task-routing hint's recommends.commands
|
|
83
|
+
// into the HEADLINE for create/build intents. Routing hints are scored by
|
|
84
|
+
// explainTaskRouting but were previously only shown under --verbose, so the
|
|
85
|
+
// headline fell back to generic review/report/impact commands even when the
|
|
86
|
+
// pack declared the right `shrk gen <template>` playbook. When the top hint
|
|
87
|
+
// clears the threshold AND the query looks like create/build work, its
|
|
88
|
+
// commands lead and the generic defaults slide to the tail. Deterministic.
|
|
89
|
+
const topHint = routingMatches[0];
|
|
90
|
+
const hintCommands = topHint?.hint.recommends.commands ?? [];
|
|
91
|
+
if (query.length > 0 &&
|
|
92
|
+
looksLikeCreateBuild(query) &&
|
|
93
|
+
topHint &&
|
|
94
|
+
topHint.score >= ROUTING_HINT_PROMOTE_THRESHOLD &&
|
|
95
|
+
hintCommands.length > 0) {
|
|
96
|
+
const promoted = hintCommands.map((command) => ({
|
|
97
|
+
command,
|
|
98
|
+
why: `Routing hint "${topHint.hint.id}" matched (score ${topHint.score}) — project playbook for this create/build task.`,
|
|
99
|
+
safetyLevel: promotedSafetyLevel(command),
|
|
100
|
+
}));
|
|
101
|
+
const promotedSet = new Set(promoted.map((p) => p.command));
|
|
102
|
+
const isGenericDefault = (c) => /^(bun run )?shrk (review|report|impact)\b/i.test(c);
|
|
103
|
+
const existing = report.recommendations;
|
|
104
|
+
const keptNonGeneric = existing.filter((r) => !promotedSet.has(r.command) && !isGenericDefault(r.command));
|
|
105
|
+
const keptGeneric = existing.filter((r) => !promotedSet.has(r.command) && isGenericDefault(r.command));
|
|
106
|
+
report.recommendations = [
|
|
107
|
+
...promoted,
|
|
108
|
+
...keptNonGeneric,
|
|
109
|
+
...keptGeneric,
|
|
110
|
+
];
|
|
111
|
+
}
|
|
82
112
|
if (machineJson) {
|
|
83
113
|
process.stdout.write(asJson({
|
|
84
114
|
...report,
|
|
@@ -250,6 +280,48 @@ const PLANNING_VERBS = new Set([
|
|
|
250
280
|
'evaluate',
|
|
251
281
|
'assess',
|
|
252
282
|
]);
|
|
283
|
+
/**
|
|
284
|
+
* Minimum routing-hint score (from `explainTaskRouting`: +2 per keyword, +3 per
|
|
285
|
+
* phrase, +2 per regex, + confidenceBoost) required to promote a hint's
|
|
286
|
+
* commands into the recommend headline. 3 ⇒ at least one phrase match or two
|
|
287
|
+
* keyword/regex hits — a real match, not a single weak keyword.
|
|
288
|
+
*/
|
|
289
|
+
const ROUTING_HINT_PROMOTE_THRESHOLD = 3;
|
|
290
|
+
const CREATE_BUILD_VERBS = new Set([
|
|
291
|
+
'create', 'build', 'add', 'generate', 'scaffold', 'implement', 'make', 'new', 'introduce', 'write',
|
|
292
|
+
]);
|
|
293
|
+
/**
|
|
294
|
+
* Does the query look like create/build work (a routing hint's `shrk gen`
|
|
295
|
+
* playbook is most useful here)? Mirrors {@link looksLikePlanning}: a
|
|
296
|
+
* create/build verb leading the query or in slots 1–3.
|
|
297
|
+
*/
|
|
298
|
+
export function looksLikeCreateBuild(query) {
|
|
299
|
+
const tokens = query
|
|
300
|
+
.toLowerCase()
|
|
301
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
302
|
+
.split(/\s+/)
|
|
303
|
+
.filter((t) => t.length > 0);
|
|
304
|
+
if (tokens.length === 0)
|
|
305
|
+
return false;
|
|
306
|
+
if (CREATE_BUILD_VERBS.has(tokens[0]))
|
|
307
|
+
return true;
|
|
308
|
+
for (let i = 1; i < Math.min(4, tokens.length); i++) {
|
|
309
|
+
if (CREATE_BUILD_VERBS.has(tokens[i]))
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
/** Conservative safety classification for a promoted routing-hint command. */
|
|
315
|
+
function promotedSafetyLevel(command) {
|
|
316
|
+
if (/^(bun run )?shrk (gen|init|apply|import)\b/i.test(command))
|
|
317
|
+
return 'writes-source';
|
|
318
|
+
if (/^(bun run )?shrk (brief|dev|onboard|simulate|orchestrate|spec)\b/i.test(command)) {
|
|
319
|
+
return 'writes-drafts';
|
|
320
|
+
}
|
|
321
|
+
if (/^(bun|bunx|npm|pnpm|node|git|nx) /i.test(command))
|
|
322
|
+
return 'runs-shell';
|
|
323
|
+
return 'read-only';
|
|
324
|
+
}
|
|
253
325
|
export function looksLikePlanning(query) {
|
|
254
326
|
const tokens = query
|
|
255
327
|
.toLowerCase()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.command.d.ts","sourceRoot":"","sources":["../../src/commands/rules.command.ts"],"names":[],"mappings":"AAcA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"rules.command.d.ts","sourceRoot":"","sources":["../../src/commands/rules.command.ts"],"names":[],"mappings":"AAcA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,gBAAgB,EAAE,eAgC9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAuB7B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAmClC,CAAC;AAuBF,eAAO,MAAM,oBAAoB,EAAE,eAiFlC,CAAC;AAkBF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,eAsB7B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,eA6BhC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,eA6BhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,eA2F9B,CAAC;AAoCF,eAAO,MAAM,kBAAkB,EAAE,eAiChC,CAAC"}
|
|
@@ -8,12 +8,29 @@ import { knowledgeAddCommand, knowledgeRemoveCommand, knowledgeUpdateCommand, }
|
|
|
8
8
|
export const rulesListCommand = {
|
|
9
9
|
name: 'list',
|
|
10
10
|
description: 'List all rules.',
|
|
11
|
-
usage: 'shrk rules list [--json]',
|
|
11
|
+
usage: 'shrk rules list [--top N] [--brief] [--json]',
|
|
12
12
|
async run(args) {
|
|
13
13
|
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
14
|
-
|
|
14
|
+
let rules = inspection.ruleService.list();
|
|
15
|
+
// --top N: deterministic, token-bounded slice (id-sorted so it's stable).
|
|
16
|
+
const top = flagNumber(args, 'top');
|
|
17
|
+
if (top !== undefined && top > 0) {
|
|
18
|
+
rules = [...rules].sort((a, b) => a.id.localeCompare(b.id)).slice(0, top);
|
|
19
|
+
}
|
|
15
20
|
if (flagBool(args, 'json')) {
|
|
16
|
-
|
|
21
|
+
// --brief: project to the high-signal fields (drop content/examples).
|
|
22
|
+
const payload = flagBool(args, 'brief')
|
|
23
|
+
? rules.map((r) => ({
|
|
24
|
+
id: r.id,
|
|
25
|
+
type: r.type,
|
|
26
|
+
priority: r.priority,
|
|
27
|
+
title: r.title,
|
|
28
|
+
scope: r.scope,
|
|
29
|
+
tags: r.tags,
|
|
30
|
+
appliesWhen: r.appliesWhen,
|
|
31
|
+
}))
|
|
32
|
+
: rules;
|
|
33
|
+
process.stdout.write(asJson(payload) + '\n');
|
|
17
34
|
return 0;
|
|
18
35
|
}
|
|
19
36
|
process.stdout.write(header(`Rules (${rules.length})`));
|
|
@@ -1,21 +1,4 @@
|
|
|
1
1
|
import { type ICommandHandler } from '../command-registry.js';
|
|
2
|
-
/**
|
|
3
|
-
* Gemini-backed context enrichment.
|
|
4
|
-
*
|
|
5
|
-
* Sits next to `shrk ask` as an explicit, opt-in AI surface — the
|
|
6
|
-
* deterministic engine (`shrk context`, `shrk brief`, MCP tools) stays
|
|
7
|
-
* AI-free. See docs/smart-context.md and the
|
|
8
|
-
* `.claude/skills/shrk-smart-context/` skill for the agent workflow.
|
|
9
|
-
*
|
|
10
|
-
* Verbs:
|
|
11
|
-
* - `smart-context "<task>"` — single brief (default).
|
|
12
|
-
* - `smart-context "<task>" --plan` — single structured plan.
|
|
13
|
-
* - `smart-context "<task>" --ai-plan` — two-stage AI-assisted plan.
|
|
14
|
-
* - `smart-context "<task>" --save` — persist under .sharkcraft/smart-context/.
|
|
15
|
-
* - `smart-context plan-ahead "t1" "t2"` — batch-save plans for an upcoming queue.
|
|
16
|
-
* - `smart-context list` — list saved entries.
|
|
17
|
-
* - `smart-context show <slug>` — print a saved entry.
|
|
18
|
-
*/
|
|
19
2
|
export declare const smartContextCommand: ICommandHandler;
|
|
20
3
|
/** `shrk smart-context plan-ahead "task1" "task2" ...` — batch-saves plans. */
|
|
21
4
|
export declare const smartContextPlanAheadCommand: ICommandHandler;
|
|
@@ -55,4 +38,30 @@ export declare const smartContextAuditPipelinesCommand: ICommandHandler;
|
|
|
55
38
|
export declare const smartContextEmbeddingsBuildCommand: ICommandHandler;
|
|
56
39
|
/** `shrk smart-context embeddings-status` — freshness report (no model load). */
|
|
57
40
|
export declare const smartContextEmbeddingsStatusCommand: ICommandHandler;
|
|
41
|
+
interface IIndexFreshness {
|
|
42
|
+
/** Files currently in the semantic index. */
|
|
43
|
+
indexed: number;
|
|
44
|
+
/** stale + missing + untracked — how far the index is behind the working tree. */
|
|
45
|
+
behind: number;
|
|
46
|
+
stale: number;
|
|
47
|
+
missing: number;
|
|
48
|
+
untracked: number;
|
|
49
|
+
/** True when this run refreshed the index inline (--refresh or under the auto cap). */
|
|
50
|
+
refreshed: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Deleted-file suggestions DROPPED from this query's results — a stale index
|
|
53
|
+
* returned hits for files no longer on disk; they were pruned before the agent
|
|
54
|
+
* ever saw them. Present (and > 0) only when the prune actually fired.
|
|
55
|
+
*/
|
|
56
|
+
prunedDeleted?: number;
|
|
57
|
+
/** Command to bring the index current, when it is still behind. */
|
|
58
|
+
nextCommand?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Render the one-line freshness warning for a stale semantic index — including
|
|
62
|
+
* how many deleted-file suggestions were dropped from the results this query.
|
|
63
|
+
* Returns null when the index is current (no noise). Pure + testable.
|
|
64
|
+
*/
|
|
65
|
+
export declare function renderIndexFreshnessWarning(f: IIndexFreshness | undefined): string | null;
|
|
66
|
+
export {};
|
|
58
67
|
//# sourceMappingURL=smart-context.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-context.command.d.ts","sourceRoot":"","sources":["../../src/commands/smart-context.command.ts"],"names":[],"mappings":"AAyBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"smart-context.command.d.ts","sourceRoot":"","sources":["../../src/commands/smart-context.command.ts"],"names":[],"mappings":"AAyBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAmFhC,eAAO,MAAM,mBAAmB,EAAE,eAuNjC,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,4BAA4B,EAAE,eAmF1C,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,uBAAuB,EAAE,eAwBrC,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,uBAAuB,EAAE,eAkCrC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iCAAiC,EAAE,eAmH/C,CAAC;AA2JF;;;;;;;GAOG;AACH,eAAO,MAAM,iCAAiC,EAAE,eAoH/C,CAAC;AA2JF;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,EAAE,eAgG/C,CAAC;AAyPF,4EAA4E;AAC5E,eAAO,MAAM,kCAAkC,EAAE,eAuHhD,CAAC;AAMF,iFAAiF;AACjF,eAAO,MAAM,mCAAmC,EAAE,eAsCjD,CAAC;AAqJF,UAAU,eAAe;IACvB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAWzF"}
|