@shrkcrft/cli 0.1.0-alpha.18 → 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/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +13 -1
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
- package/dist/commands/graph-code-subverbs.js +37 -12
- 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/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/package.json +33 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gen.command.d.ts","sourceRoot":"","sources":["../../src/commands/gen.command.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkBhC,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"gen.command.d.ts","sourceRoot":"","sources":["../../src/commands/gen.command.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkBhC,eAAO,MAAM,UAAU,EAAE,eA+JxB,CAAC"}
|
|
@@ -19,7 +19,7 @@ const CHANGE_LABEL = {
|
|
|
19
19
|
export const genCommand = {
|
|
20
20
|
name: 'gen',
|
|
21
21
|
description: 'Generate code from a template. Defaults to dry-run.',
|
|
22
|
-
usage: 'shrk gen <templateId> [<name>] [--var key=value ...] [--dry-run] [--write] [--force] [--save-plan <file>] [--json]',
|
|
22
|
+
usage: 'shrk gen <templateId> [<name>] [--var key=value ...] [--dry-run] [--write] [--force] [--save-plan <file>] [--show-content] [--json]',
|
|
23
23
|
async run(args) {
|
|
24
24
|
const templateId = args.positional[0];
|
|
25
25
|
const name = args.positional[1];
|
|
@@ -114,6 +114,18 @@ export const genCommand = {
|
|
|
114
114
|
for (const change of plan.changes) {
|
|
115
115
|
process.stdout.write(`${CHANGE_LABEL[change.type]} ${change.relativePath} (${change.sizeBytes} bytes) — ${change.reason}\n`);
|
|
116
116
|
}
|
|
117
|
+
// --show-content: print the already-computed virtual file content so an
|
|
118
|
+
// agent can review what a template would generate WITHOUT writing to disk
|
|
119
|
+
// (the saved plan stays content-free). The bytes are identical in dry-run
|
|
120
|
+
// and --write; this is purely additive.
|
|
121
|
+
if (flagBool(args, 'show-content')) {
|
|
122
|
+
process.stdout.write('\nVirtual content (not written to disk):\n');
|
|
123
|
+
for (const change of plan.changes) {
|
|
124
|
+
const body = change.contents ?? '';
|
|
125
|
+
process.stdout.write(`\n----- ${change.relativePath} (${change.sizeBytes} bytes) -----\n`);
|
|
126
|
+
process.stdout.write(body.endsWith('\n') ? body : body + '\n');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
117
129
|
if (plan.postGenerationNotes.length) {
|
|
118
130
|
process.stdout.write('\nPost-generation notes:\n');
|
|
119
131
|
for (const note of plan.postGenerationNotes)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-code-subverbs.d.ts","sourceRoot":"","sources":["../../src/commands/graph-code-subverbs.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-code-subverbs.d.ts","sourceRoot":"","sources":["../../src/commands/graph-code-subverbs.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAiI3F,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrE;AA4FD,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DtE;AAiBD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAwF1E;AAID,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA8EpE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFtE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiDtE;AAID,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgMvE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAuHtE;AAID;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CpE;AAID,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA0EvE;AAyBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgHpE"}
|
|
@@ -58,19 +58,37 @@ function maybeColumnarize(payload, args) {
|
|
|
58
58
|
return out;
|
|
59
59
|
}
|
|
60
60
|
const STALE_HINT = `Index is missing or stale. Run 'shrk graph index' to build it.`;
|
|
61
|
-
const STALE_RESULT_HINT = 'Some result files changed since the index was built — run `shrk graph index --changed
|
|
61
|
+
const STALE_RESULT_HINT = 'Some result files changed since the index was built — auto-refresh is on by default (you passed --no-refresh / SHRK_GRAPH_NO_REFRESH). Drop the opt-out, or run `shrk graph index --changed`, for fresh results.';
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* Refresh-by-default: incrementally reindex changed/deleted files BEFORE
|
|
64
|
+
* querying so an agent's just-saved edits are reflected, then print a one-line
|
|
65
|
+
* `(refreshed, N files)` notice to stderr. The incremental updater is
|
|
66
|
+
* sub-second on SharkCraft-sized indexes, so this removes the manual `shrk
|
|
67
|
+
* graph index --changed` step that otherwise leaves every read command
|
|
68
|
+
* answering from a silently-stale index — the #1 daily-friction tax.
|
|
69
|
+
*
|
|
70
|
+
* Opt out with `--no-refresh` or `SHRK_GRAPH_NO_REFRESH=1` (e.g. to keep a read
|
|
71
|
+
* perfectly side-effect-free, or on a huge repo where the rewrite is felt).
|
|
72
|
+
* `--refresh` is still accepted as a harmless explicit-on alias.
|
|
73
|
+
*
|
|
74
|
+
* CLI-only — it writes the gitignored `.sharkcraft` cache; MCP never calls this
|
|
75
|
+
* (the read-only contract). When there is no index yet, `detectChangedAndDeleted`
|
|
76
|
+
* returns nothing, so `updateChanged` (which requires an existing store) is
|
|
77
|
+
* never reached. The notice goes to stderr so it never corrupts a `--json`
|
|
78
|
+
* payload on stdout.
|
|
66
79
|
*/
|
|
67
80
|
function maybeRefresh(args, cwd) {
|
|
68
|
-
if (
|
|
81
|
+
if (flagBool(args, 'no-refresh'))
|
|
82
|
+
return;
|
|
83
|
+
if ((process.env.SHRK_GRAPH_NO_REFRESH ?? '').trim().length > 0)
|
|
69
84
|
return;
|
|
70
85
|
const d = detectChangedAndDeleted(cwd);
|
|
71
|
-
if (d.changed.length
|
|
72
|
-
|
|
73
|
-
}
|
|
86
|
+
if (d.changed.length === 0 && d.deleted.length === 0)
|
|
87
|
+
return;
|
|
88
|
+
const result = updateChanged({ projectRoot: cwd, changedFiles: d.changed, deletedFiles: d.deleted });
|
|
89
|
+
const n = result.updated.length + result.deleted.length;
|
|
90
|
+
if (n > 0)
|
|
91
|
+
process.stderr.write(`(refreshed, ${n} file${n === 1 ? '' : 's'})\n`);
|
|
74
92
|
}
|
|
75
93
|
/**
|
|
76
94
|
* Targeted staleness over a query's result file paths: which changed (flag)
|
|
@@ -519,6 +537,7 @@ export async function runGraphSearch(args) {
|
|
|
519
537
|
}
|
|
520
538
|
const kindFlag = flagString(args, 'kind');
|
|
521
539
|
const limit = Number(flagString(args, 'limit') ?? '20');
|
|
540
|
+
maybeRefresh(args, cwd);
|
|
522
541
|
const api = loadOrFail(cwd, wantJson);
|
|
523
542
|
if (!api)
|
|
524
543
|
return 1;
|
|
@@ -923,10 +942,16 @@ export async function runGraphCallers(args) {
|
|
|
923
942
|
const wantJson = flagBool(args, 'json');
|
|
924
943
|
const target = args.positional[1];
|
|
925
944
|
if (!target) {
|
|
926
|
-
process.stderr.write('Usage: shrk graph callers <symbol> [--mode call|reference] [--refresh]\n');
|
|
945
|
+
process.stderr.write('Usage: shrk graph callers <symbol> [--mode call|reference] [--limit N] [--no-refresh]\n');
|
|
927
946
|
return 2;
|
|
928
947
|
}
|
|
929
948
|
const mode = (flagString(args, 'mode') ?? 'call');
|
|
949
|
+
// --limit N: cap the returned call sites (default 200). `total` still reports
|
|
950
|
+
// the true uncapped count, so a truncated result stays honest. Guard against
|
|
951
|
+
// non-numeric input — `Number('foo')` is NaN and `slice(0, NaN)` would zero
|
|
952
|
+
// the callers list while `total` kept showing the real count.
|
|
953
|
+
const parsedLimit = Number.parseInt(flagString(args, 'limit') ?? '200', 10);
|
|
954
|
+
const limit = Number.isFinite(parsedLimit) && parsedLimit > 0 ? parsedLimit : 200;
|
|
930
955
|
maybeRefresh(args, cwd);
|
|
931
956
|
const api = loadOrFail(cwd, wantJson);
|
|
932
957
|
if (!api)
|
|
@@ -961,7 +986,7 @@ export async function runGraphCallers(args) {
|
|
|
961
986
|
symbol: nodeSummary(sym),
|
|
962
987
|
mode,
|
|
963
988
|
total: liveSites.length,
|
|
964
|
-
callers: liveSites.slice(0,
|
|
989
|
+
callers: liveSites.slice(0, limit).map((s) => ({
|
|
965
990
|
...nodeSummary(s.node),
|
|
966
991
|
...(s.line ? { line: s.line } : {}),
|
|
967
992
|
})),
|
|
@@ -978,7 +1003,7 @@ export async function runGraphCallers(args) {
|
|
|
978
1003
|
process.stdout.write(` ⓘ ${note}\n`);
|
|
979
1004
|
// Render `path:line` so the agent jumps straight to the call site instead
|
|
980
1005
|
// of having to grep inside each returned file.
|
|
981
|
-
for (const c of payload.callers.slice(0, 50)) {
|
|
1006
|
+
for (const c of payload.callers.slice(0, Math.min(50, limit))) {
|
|
982
1007
|
process.stdout.write(` ${c.path ?? c.id}${c.line ? ':' + c.line : ''}\n`);
|
|
983
1008
|
}
|
|
984
1009
|
if (fresh.field) {
|
|
@@ -1025,7 +1050,7 @@ export async function runGraphPath(args) {
|
|
|
1025
1050
|
const fromArg = args.positional[1];
|
|
1026
1051
|
const toArg = args.positional[2];
|
|
1027
1052
|
if (!fromArg || !toArg) {
|
|
1028
|
-
process.stderr.write('Usage: shrk graph path <from> <to> [--max-depth N] [--refresh] [--json]\n');
|
|
1053
|
+
process.stderr.write('Usage: shrk graph path <from> <to> [--max-depth N] [--no-refresh] [--json]\n');
|
|
1029
1054
|
return 2;
|
|
1030
1055
|
}
|
|
1031
1056
|
const maxDepth = Math.max(1, Math.min(32, Number(flagString(args, 'max-depth') ?? '16')));
|
|
@@ -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})`));
|
|
@@ -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})`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shrkcrft/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.19",
|
|
4
4
|
"description": "SharkCraft CLI (`shrk`): structured project intelligence for AI coding agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SharkCraft contributors",
|
|
@@ -47,38 +47,38 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@shrkcrft/core": "^0.1.0-alpha.
|
|
51
|
-
"@shrkcrft/compress": "^0.1.0-alpha.
|
|
52
|
-
"@shrkcrft/config": "^0.1.0-alpha.
|
|
53
|
-
"@shrkcrft/workspace": "^0.1.0-alpha.
|
|
54
|
-
"@shrkcrft/knowledge": "^0.1.0-alpha.
|
|
55
|
-
"@shrkcrft/context": "^0.1.0-alpha.
|
|
56
|
-
"@shrkcrft/rules": "^0.1.0-alpha.
|
|
57
|
-
"@shrkcrft/paths": "^0.1.0-alpha.
|
|
58
|
-
"@shrkcrft/templates": "^0.1.0-alpha.
|
|
59
|
-
"@shrkcrft/plugin-api": "^0.1.0-alpha.
|
|
60
|
-
"@shrkcrft/dashboard": "^0.1.0-alpha.
|
|
61
|
-
"@shrkcrft/dashboard-api": "^0.1.0-alpha.
|
|
62
|
-
"@shrkcrft/pipelines": "^0.1.0-alpha.
|
|
63
|
-
"@shrkcrft/presets": "^0.1.0-alpha.
|
|
64
|
-
"@shrkcrft/boundaries": "^0.1.0-alpha.
|
|
65
|
-
"@shrkcrft/graph": "^0.1.0-alpha.
|
|
66
|
-
"@shrkcrft/rule-graph": "^0.1.0-alpha.
|
|
67
|
-
"@shrkcrft/structural-search": "^0.1.0-alpha.
|
|
68
|
-
"@shrkcrft/impact-engine": "^0.1.0-alpha.
|
|
69
|
-
"@shrkcrft/context-planner": "^0.1.0-alpha.
|
|
70
|
-
"@shrkcrft/architecture-guard": "^0.1.0-alpha.
|
|
71
|
-
"@shrkcrft/framework-scanners": "^0.1.0-alpha.
|
|
72
|
-
"@shrkcrft/api-surface-diff": "^0.1.0-alpha.
|
|
73
|
-
"@shrkcrft/quality-gates": "^0.1.0-alpha.
|
|
74
|
-
"@shrkcrft/migrate": "^0.1.0-alpha.
|
|
75
|
-
"@shrkcrft/generator": "^0.1.0-alpha.
|
|
76
|
-
"@shrkcrft/importer": "^0.1.0-alpha.
|
|
77
|
-
"@shrkcrft/inspector": "^0.1.0-alpha.
|
|
78
|
-
"@shrkcrft/ai": "^0.1.0-alpha.
|
|
79
|
-
"@shrkcrft/embeddings": "^0.1.0-alpha.
|
|
80
|
-
"@shrkcrft/shared": "^0.1.0-alpha.
|
|
81
|
-
"@shrkcrft/mcp-server": "^0.1.0-alpha.
|
|
50
|
+
"@shrkcrft/core": "^0.1.0-alpha.19",
|
|
51
|
+
"@shrkcrft/compress": "^0.1.0-alpha.19",
|
|
52
|
+
"@shrkcrft/config": "^0.1.0-alpha.19",
|
|
53
|
+
"@shrkcrft/workspace": "^0.1.0-alpha.19",
|
|
54
|
+
"@shrkcrft/knowledge": "^0.1.0-alpha.19",
|
|
55
|
+
"@shrkcrft/context": "^0.1.0-alpha.19",
|
|
56
|
+
"@shrkcrft/rules": "^0.1.0-alpha.19",
|
|
57
|
+
"@shrkcrft/paths": "^0.1.0-alpha.19",
|
|
58
|
+
"@shrkcrft/templates": "^0.1.0-alpha.19",
|
|
59
|
+
"@shrkcrft/plugin-api": "^0.1.0-alpha.19",
|
|
60
|
+
"@shrkcrft/dashboard": "^0.1.0-alpha.19",
|
|
61
|
+
"@shrkcrft/dashboard-api": "^0.1.0-alpha.19",
|
|
62
|
+
"@shrkcrft/pipelines": "^0.1.0-alpha.19",
|
|
63
|
+
"@shrkcrft/presets": "^0.1.0-alpha.19",
|
|
64
|
+
"@shrkcrft/boundaries": "^0.1.0-alpha.19",
|
|
65
|
+
"@shrkcrft/graph": "^0.1.0-alpha.19",
|
|
66
|
+
"@shrkcrft/rule-graph": "^0.1.0-alpha.19",
|
|
67
|
+
"@shrkcrft/structural-search": "^0.1.0-alpha.19",
|
|
68
|
+
"@shrkcrft/impact-engine": "^0.1.0-alpha.19",
|
|
69
|
+
"@shrkcrft/context-planner": "^0.1.0-alpha.19",
|
|
70
|
+
"@shrkcrft/architecture-guard": "^0.1.0-alpha.19",
|
|
71
|
+
"@shrkcrft/framework-scanners": "^0.1.0-alpha.19",
|
|
72
|
+
"@shrkcrft/api-surface-diff": "^0.1.0-alpha.19",
|
|
73
|
+
"@shrkcrft/quality-gates": "^0.1.0-alpha.19",
|
|
74
|
+
"@shrkcrft/migrate": "^0.1.0-alpha.19",
|
|
75
|
+
"@shrkcrft/generator": "^0.1.0-alpha.19",
|
|
76
|
+
"@shrkcrft/importer": "^0.1.0-alpha.19",
|
|
77
|
+
"@shrkcrft/inspector": "^0.1.0-alpha.19",
|
|
78
|
+
"@shrkcrft/ai": "^0.1.0-alpha.19",
|
|
79
|
+
"@shrkcrft/embeddings": "^0.1.0-alpha.19",
|
|
80
|
+
"@shrkcrft/shared": "^0.1.0-alpha.19",
|
|
81
|
+
"@shrkcrft/mcp-server": "^0.1.0-alpha.19",
|
|
82
82
|
"@huggingface/transformers": "^3.7.5"
|
|
83
83
|
},
|
|
84
84
|
"publishConfig": {
|