@shrkcrft/cli 0.1.0-alpha.11 → 0.1.0-alpha.12
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/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 +100 -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 +60 -1
- 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 +30 -0
- package/dist/commands/smart-context.command.d.ts.map +1 -0
- package/dist/commands/smart-context.command.js +3763 -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/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 +83 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.command.d.ts","sourceRoot":"","sources":["../../src/commands/ask.command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ask.command.d.ts","sourceRoot":"","sources":["../../src/commands/ask.command.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAIhC,eAAO,MAAM,UAAU,EAAE,eA6DxB,CAAC"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { inspectSharkcraft, buildProjectOverview, renderOverviewText } from '@shrkcrft/inspector';
|
|
2
2
|
import { buildContext } from '@shrkcrft/context';
|
|
3
|
-
import {
|
|
3
|
+
import { AiMessageRole, buildPromptMessages, selectAiProvider, } from '@shrkcrft/ai';
|
|
4
4
|
import { flagBool, flagNumber, flagString, resolveCwd, } from "../command-registry.js";
|
|
5
5
|
import { header } from "../output/format-output.js";
|
|
6
6
|
import { printError } from "../output/print-error.js";
|
|
7
7
|
export const askCommand = {
|
|
8
8
|
name: 'ask',
|
|
9
|
-
description: 'Ask a question. Builds repository context, sends prompt to
|
|
10
|
-
usage: 'shrk ask "<question>" [--max-tokens 3000] [--model
|
|
9
|
+
description: 'Ask a question. Builds repository context, sends prompt to the local LLM (Ollama / llama.cpp).',
|
|
10
|
+
usage: 'shrk ask "<question>" [--max-tokens 3000] [--provider auto|ollama|llamacpp] [--model <id>] [--dry-run]',
|
|
11
11
|
async run(args) {
|
|
12
12
|
const question = args.positional.join(' ').trim();
|
|
13
13
|
if (!question) {
|
|
@@ -16,6 +16,7 @@ export const askCommand = {
|
|
|
16
16
|
}
|
|
17
17
|
const maxTokens = flagNumber(args, 'max-tokens') ?? 3000;
|
|
18
18
|
const model = flagString(args, 'model');
|
|
19
|
+
const providerKind = flagString(args, 'provider');
|
|
19
20
|
const dryRun = flagBool(args, 'dry-run');
|
|
20
21
|
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
21
22
|
const overview = buildProjectOverview(inspection.workspace, inspection.config?.projectName);
|
|
@@ -36,14 +37,14 @@ export const askCommand = {
|
|
|
36
37
|
}
|
|
37
38
|
return 0;
|
|
38
39
|
}
|
|
39
|
-
const
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
if (!provider.isReady()) {
|
|
43
|
-
process.stderr.write('ANTHROPIC_API_KEY is not set. Use --dry-run to print the prompt instead.\n');
|
|
40
|
+
const selection = selectAiProvider(providerKind);
|
|
41
|
+
if (!selection.provider) {
|
|
42
|
+
process.stderr.write('No local LLM is ready. Start Ollama (`ollama serve`) or set LLAMACPP_MODEL_PATH=/path/to/model.gguf in .env. Use --dry-run to print the prompt instead.\n');
|
|
44
43
|
return 1;
|
|
45
44
|
}
|
|
46
|
-
|
|
45
|
+
if (model)
|
|
46
|
+
selection.provider.configure({ model });
|
|
47
|
+
const res = await selection.provider.send({
|
|
47
48
|
messages: [...messages, { role: AiMessageRole.User, content: question }],
|
|
48
49
|
maxTokens: 1024,
|
|
49
50
|
model,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/command-catalog.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,QAAQ,cAAc;IACtB,iBAAiB,mBAAmB;IACpC,gBAAgB,kBAAkB;IAClC,YAAY,kBAAkB;IAC9B,SAAS,eAAe;IACxB,cAAc,oBAAoB;CACnC;AAED;;;;;;GAMG;AACH,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAED,8BAA8B;AAC9B,oBAAY,eAAe;IACzB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,EAAE,OAAO;IACT,UAAU,gBAAgB;IAC1B,UAAU,eAAe;CAC1B;AAED;;;;;;GAMG;AACH,oBAAY,eAAe;IACzB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,MAAM,WAAW;CAClB;AAED;;;;;;GAMG;AACH,oBAAY,gBAAgB;IAC1B,MAAM,WAAW;IACjB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,UAAU,eAAe;IACzB,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,YAAY,iBAAiB;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,kCAAkC;IAClC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,oBAAoB,
|
|
1
|
+
{"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/command-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -256,7 +256,7 @@ export const COMMAND_CATALOG = Object.freeze([
|
|
|
256
256
|
}),
|
|
257
257
|
entry({
|
|
258
258
|
command: 'graph',
|
|
259
|
-
description: 'Knowledge graph
|
|
259
|
+
description: 'Knowledge graph plus code-intelligence subverbs (`index`, `status`, `search`, `context`, `impact`, `callers`, `cycles`, `unresolved`, `deps`, `why`, `export`).',
|
|
260
260
|
category: 'core',
|
|
261
261
|
safetyLevel: SafetyLevel.ReadOnly,
|
|
262
262
|
mcpAvailable: true,
|
|
@@ -1182,6 +1182,104 @@ export const COMMAND_CATALOG = Object.freeze([
|
|
|
1182
1182
|
category: 'core',
|
|
1183
1183
|
safetyLevel: SafetyLevel.ReadOnly,
|
|
1184
1184
|
}),
|
|
1185
|
+
entry({
|
|
1186
|
+
command: 'smart-context',
|
|
1187
|
+
description: 'Build deterministic context and ask an AI provider to synthesise an enriched brief (default), structured plan (--plan), or two-stage development plan (--ai-plan). Opt-in; defaults to Gemini. CLAUDE.md is auto-included in the seed.',
|
|
1188
|
+
category: 'core',
|
|
1189
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1190
|
+
taskRole: CommandTaskRole.Context,
|
|
1191
|
+
}),
|
|
1192
|
+
entry({
|
|
1193
|
+
command: 'smart-context plan-ahead',
|
|
1194
|
+
description: 'Batch-generate AI-backed plans for a queue of upcoming tasks and save each under .sharkcraft/smart-context/.',
|
|
1195
|
+
category: 'core',
|
|
1196
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1197
|
+
taskRole: CommandTaskRole.Context,
|
|
1198
|
+
}),
|
|
1199
|
+
entry({
|
|
1200
|
+
command: 'smart-context list',
|
|
1201
|
+
description: 'List saved smart-context entries under .sharkcraft/smart-context/.',
|
|
1202
|
+
category: 'core',
|
|
1203
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1204
|
+
taskRole: CommandTaskRole.Inspect,
|
|
1205
|
+
}),
|
|
1206
|
+
entry({
|
|
1207
|
+
command: 'smart-context show',
|
|
1208
|
+
description: 'Print a saved smart-context entry by slug.',
|
|
1209
|
+
category: 'core',
|
|
1210
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1211
|
+
taskRole: CommandTaskRole.Inspect,
|
|
1212
|
+
}),
|
|
1213
|
+
entry({
|
|
1214
|
+
command: 'smart-context embeddings-build',
|
|
1215
|
+
description: 'Build or incrementally refresh the semantic file index used by smart-context. Downloads the embedding model on first run.',
|
|
1216
|
+
category: 'core',
|
|
1217
|
+
safetyLevel: SafetyLevel.WritesSessionOnly,
|
|
1218
|
+
taskRole: CommandTaskRole.Context,
|
|
1219
|
+
}),
|
|
1220
|
+
entry({
|
|
1221
|
+
command: 'smart-context embeddings-status',
|
|
1222
|
+
description: 'Report semantic index freshness without loading the embedding model.',
|
|
1223
|
+
category: 'core',
|
|
1224
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1225
|
+
taskRole: CommandTaskRole.Inspect,
|
|
1226
|
+
}),
|
|
1227
|
+
entry({
|
|
1228
|
+
command: 'spike',
|
|
1229
|
+
description: 'Scaffold starter files for a saved smart-context plan\'s recommended MVP. Reads .sharkcraft/smart-context/<slug>.plan.json.',
|
|
1230
|
+
category: 'core',
|
|
1231
|
+
safetyLevel: SafetyLevel.WritesSource,
|
|
1232
|
+
taskRole: CommandTaskRole.Generate,
|
|
1233
|
+
}),
|
|
1234
|
+
entry({
|
|
1235
|
+
command: 'deps-audit',
|
|
1236
|
+
description: 'Compare declared package dependencies (package.json) with actually imported specifiers (graph). Reports missing + unused deps. Read-only.',
|
|
1237
|
+
category: 'core',
|
|
1238
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1239
|
+
taskRole: CommandTaskRole.Inspect,
|
|
1240
|
+
}),
|
|
1241
|
+
entry({
|
|
1242
|
+
command: 'scaffold-validate',
|
|
1243
|
+
description: 'Validate that the files in a saved generation plan exist on disk and look intact (size envelope + type match). Read-only.',
|
|
1244
|
+
category: 'core',
|
|
1245
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1246
|
+
taskRole: CommandTaskRole.Validate,
|
|
1247
|
+
}),
|
|
1248
|
+
entry({
|
|
1249
|
+
command: 'move-plan',
|
|
1250
|
+
description: 'Plan a file move: graph-traced importer rewrites, export touch-ups, cross-package warnings, rollback steps. Read-only.',
|
|
1251
|
+
category: 'core',
|
|
1252
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1253
|
+
taskRole: CommandTaskRole.Generate,
|
|
1254
|
+
}),
|
|
1255
|
+
entry({
|
|
1256
|
+
command: 'watch',
|
|
1257
|
+
description: 'Emit a focused-context packet on stdout JSONL each time the workspace changes. Designed to feed a parallel Claude agent.',
|
|
1258
|
+
category: 'core',
|
|
1259
|
+
safetyLevel: SafetyLevel.WritesSessionOnly,
|
|
1260
|
+
taskRole: CommandTaskRole.Context,
|
|
1261
|
+
}),
|
|
1262
|
+
entry({
|
|
1263
|
+
command: 'watch list',
|
|
1264
|
+
description: 'List active shrk-watch daemons (one per task slug).',
|
|
1265
|
+
category: 'core',
|
|
1266
|
+
safetyLevel: SafetyLevel.ReadOnly,
|
|
1267
|
+
taskRole: CommandTaskRole.Inspect,
|
|
1268
|
+
}),
|
|
1269
|
+
entry({
|
|
1270
|
+
command: 'watch stop',
|
|
1271
|
+
description: 'Stop a running shrk-watch daemon by slug.',
|
|
1272
|
+
category: 'core',
|
|
1273
|
+
safetyLevel: SafetyLevel.WritesSessionOnly,
|
|
1274
|
+
taskRole: CommandTaskRole.Config,
|
|
1275
|
+
}),
|
|
1276
|
+
entry({
|
|
1277
|
+
command: 'watch prune',
|
|
1278
|
+
description: 'Remove stale shrk-watch manifests whose owning processes are no longer alive.',
|
|
1279
|
+
category: 'core',
|
|
1280
|
+
safetyLevel: SafetyLevel.WritesSessionOnly,
|
|
1281
|
+
taskRole: CommandTaskRole.Config,
|
|
1282
|
+
}),
|
|
1185
1283
|
entry({
|
|
1186
1284
|
command: 'safety audit',
|
|
1187
1285
|
description: 'Audit the SharkCraft safety model (commands, MCP, packs, plan signing).',
|
|
@@ -3251,6 +3349,7 @@ const PRIMARY_VERBS_ALLOWLIST = new Set([
|
|
|
3251
3349
|
'search',
|
|
3252
3350
|
'impact',
|
|
3253
3351
|
'graph',
|
|
3352
|
+
'code-intel',
|
|
3254
3353
|
// Generate code safely
|
|
3255
3354
|
'gen',
|
|
3256
3355
|
'apply',
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ICommandHandler } from '../command-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* `shrk deps-audit` — for each workspace package, compare the
|
|
4
|
+
* `package.json` `dependencies` / `devDependencies` / `peerDependencies`
|
|
5
|
+
* against the *specifiers actually imported* from source under
|
|
6
|
+
* `<pkg>/src/` (per the SharkCraft graph).
|
|
7
|
+
*
|
|
8
|
+
* Reports:
|
|
9
|
+
* - missing deps: imported but not declared (likely build failure
|
|
10
|
+
* in the wild — the package depends on its host's resolution)
|
|
11
|
+
* - unused deps: declared but never imported (lint waste)
|
|
12
|
+
*
|
|
13
|
+
* Read-only. JSON output via `--json`. Optionally restricted to one
|
|
14
|
+
* package via `--package <name>`.
|
|
15
|
+
*
|
|
16
|
+
* Known limitations:
|
|
17
|
+
* - Type-only imports (`import type x from 'y'`) still count; the
|
|
18
|
+
* graph can't tell them apart in v3.
|
|
19
|
+
* - Subpath imports (`pkg/sub`) are reduced to their root specifier.
|
|
20
|
+
* - Built-in node modules (`node:fs`, `fs`, …) are ignored.
|
|
21
|
+
*/
|
|
22
|
+
export declare const depsAuditCommand: ICommandHandler;
|
|
23
|
+
//# sourceMappingURL=deps-audit.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-audit.command.d.ts","sourceRoot":"","sources":["../../src/commands/deps-audit.command.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAmBhC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAmE9B,CAAC"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import * as nodePath from 'node:path';
|
|
3
|
+
import { GraphQueryApi, GraphStore, NodeKind } from '@shrkcrft/graph';
|
|
4
|
+
import { flagBool, resolveCwd, } from "../command-registry.js";
|
|
5
|
+
import { asJson, header } from "../output/format-output.js";
|
|
6
|
+
/**
|
|
7
|
+
* `shrk deps-audit` — for each workspace package, compare the
|
|
8
|
+
* `package.json` `dependencies` / `devDependencies` / `peerDependencies`
|
|
9
|
+
* against the *specifiers actually imported* from source under
|
|
10
|
+
* `<pkg>/src/` (per the SharkCraft graph).
|
|
11
|
+
*
|
|
12
|
+
* Reports:
|
|
13
|
+
* - missing deps: imported but not declared (likely build failure
|
|
14
|
+
* in the wild — the package depends on its host's resolution)
|
|
15
|
+
* - unused deps: declared but never imported (lint waste)
|
|
16
|
+
*
|
|
17
|
+
* Read-only. JSON output via `--json`. Optionally restricted to one
|
|
18
|
+
* package via `--package <name>`.
|
|
19
|
+
*
|
|
20
|
+
* Known limitations:
|
|
21
|
+
* - Type-only imports (`import type x from 'y'`) still count; the
|
|
22
|
+
* graph can't tell them apart in v3.
|
|
23
|
+
* - Subpath imports (`pkg/sub`) are reduced to their root specifier.
|
|
24
|
+
* - Built-in node modules (`node:fs`, `fs`, …) are ignored.
|
|
25
|
+
*/
|
|
26
|
+
export const depsAuditCommand = {
|
|
27
|
+
name: 'deps-audit',
|
|
28
|
+
description: 'Audit declared dependencies vs imports actually seen in each package source. Reports missing + unused deps. Read-only.',
|
|
29
|
+
usage: 'shrk deps-audit [--package <name>] [--json]',
|
|
30
|
+
async run(args) {
|
|
31
|
+
const cwd = resolveCwd(args);
|
|
32
|
+
const json = flagBool(args, 'json');
|
|
33
|
+
const onlyPackage = typeof args.flags.get('package') === 'string'
|
|
34
|
+
? args.flags.get('package')
|
|
35
|
+
: null;
|
|
36
|
+
const store = new GraphStore(cwd);
|
|
37
|
+
if (!store.exists()) {
|
|
38
|
+
process.stderr.write('No SharkCraft graph found. Run `shrk graph build` first so deps-audit has import data.\n');
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
const api = GraphQueryApi.fromStore(cwd);
|
|
42
|
+
const packages = listWorkspacePackages(cwd, onlyPackage);
|
|
43
|
+
if (packages.length === 0) {
|
|
44
|
+
process.stderr.write('No packages found (looked under packages/*, libs/*, apps/*).\n');
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
const reports = [];
|
|
48
|
+
for (const pkg of packages) {
|
|
49
|
+
reports.push(buildPackageReport(api, cwd, pkg));
|
|
50
|
+
}
|
|
51
|
+
if (json) {
|
|
52
|
+
process.stdout.write(asJson({ packages: reports }) + '\n');
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
let missingTotal = 0;
|
|
56
|
+
let unusedTotal = 0;
|
|
57
|
+
for (const r of reports) {
|
|
58
|
+
missingTotal += r.missingDeps.length;
|
|
59
|
+
unusedTotal += r.unusedDeps.length;
|
|
60
|
+
}
|
|
61
|
+
process.stdout.write(header(`deps-audit — ${reports.length} package(s), ${missingTotal} missing dep(s), ${unusedTotal} unused dep(s)`));
|
|
62
|
+
for (const r of reports) {
|
|
63
|
+
if (r.missingDeps.length === 0 && r.unusedDeps.length === 0)
|
|
64
|
+
continue;
|
|
65
|
+
process.stdout.write(`\n${r.packageName} (${r.packageDir})\n`);
|
|
66
|
+
if (r.missingDeps.length > 0) {
|
|
67
|
+
process.stdout.write(' missing (imported, not declared):\n');
|
|
68
|
+
for (const m of r.missingDeps) {
|
|
69
|
+
process.stdout.write(` - ${m.specifier} (imported ${m.importedFromCount}×)\n`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (r.unusedDeps.length > 0) {
|
|
73
|
+
process.stdout.write(' unused (declared, never imported):\n');
|
|
74
|
+
for (const u of r.unusedDeps) {
|
|
75
|
+
process.stdout.write(` - ${u.specifier} [${u.section}]\n`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (missingTotal === 0 && unusedTotal === 0) {
|
|
80
|
+
process.stdout.write('\nAll declared deps match actual imports. ✓\n');
|
|
81
|
+
}
|
|
82
|
+
return 0;
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
function listWorkspacePackages(cwd, onlyName) {
|
|
86
|
+
const roots = ['packages', 'libs', 'apps'].map((r) => nodePath.join(cwd, r)).filter((d) => existsSync(d));
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const root of roots) {
|
|
89
|
+
let entries;
|
|
90
|
+
try {
|
|
91
|
+
entries = readdirSync(root);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
const dir = nodePath.join(root, entry);
|
|
98
|
+
let stat;
|
|
99
|
+
try {
|
|
100
|
+
stat = statSync(dir);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (!stat.isDirectory())
|
|
106
|
+
continue;
|
|
107
|
+
const pkgJsonPath = nodePath.join(dir, 'package.json');
|
|
108
|
+
if (!existsSync(pkgJsonPath))
|
|
109
|
+
continue;
|
|
110
|
+
let pkgJson;
|
|
111
|
+
try {
|
|
112
|
+
pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (!pkgJson.name)
|
|
118
|
+
continue;
|
|
119
|
+
if (onlyName !== null && pkgJson.name !== onlyName)
|
|
120
|
+
continue;
|
|
121
|
+
out.push({ name: pkgJson.name, dir, pkgJsonPath });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
function buildPackageReport(api, cwd, pkg) {
|
|
127
|
+
const declared = readDeclaredDeps(pkg.pkgJsonPath);
|
|
128
|
+
const importedSpecifiers = collectImportedSpecifiersForPackage(api, cwd, pkg.dir);
|
|
129
|
+
// Count how many distinct files inside the package import each specifier.
|
|
130
|
+
const importerCounts = new Map();
|
|
131
|
+
for (const spec of importedSpecifiers) {
|
|
132
|
+
importerCounts.set(spec, (importerCounts.get(spec) ?? 0) + 1);
|
|
133
|
+
}
|
|
134
|
+
const distinctImported = new Set(importedSpecifiers);
|
|
135
|
+
const declaredAll = new Map();
|
|
136
|
+
const declaredSections = [
|
|
137
|
+
['dependencies', declared.dependencies],
|
|
138
|
+
['devDependencies', declared.devDependencies],
|
|
139
|
+
['peerDependencies', declared.peerDependencies],
|
|
140
|
+
['optionalDependencies', declared.optionalDependencies],
|
|
141
|
+
];
|
|
142
|
+
for (const [section, map] of declaredSections) {
|
|
143
|
+
for (const k of Object.keys(map))
|
|
144
|
+
declaredAll.set(k, section);
|
|
145
|
+
}
|
|
146
|
+
const missingDeps = [];
|
|
147
|
+
for (const spec of distinctImported) {
|
|
148
|
+
if (declaredAll.has(spec))
|
|
149
|
+
continue;
|
|
150
|
+
if (spec === pkg.name)
|
|
151
|
+
continue; // self-import via package name
|
|
152
|
+
missingDeps.push({ specifier: spec, importedFromCount: importerCounts.get(spec) ?? 0 });
|
|
153
|
+
}
|
|
154
|
+
missingDeps.sort((a, b) => b.importedFromCount - a.importedFromCount);
|
|
155
|
+
const unusedDeps = [];
|
|
156
|
+
for (const [spec, section] of declaredAll.entries()) {
|
|
157
|
+
if (distinctImported.has(spec))
|
|
158
|
+
continue;
|
|
159
|
+
// devDependencies for build/test tools often don't show up in graph
|
|
160
|
+
// imports; we still report them so the user can prune if desired.
|
|
161
|
+
unusedDeps.push({ specifier: spec, section });
|
|
162
|
+
}
|
|
163
|
+
unusedDeps.sort((a, b) => a.specifier.localeCompare(b.specifier));
|
|
164
|
+
return {
|
|
165
|
+
packageName: pkg.name,
|
|
166
|
+
packageDir: nodePath.relative(cwd, pkg.dir) || '.',
|
|
167
|
+
declared,
|
|
168
|
+
importedSpecifiers: [...distinctImported],
|
|
169
|
+
missingDeps,
|
|
170
|
+
unusedDeps,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function readDeclaredDeps(pkgJsonPath) {
|
|
174
|
+
try {
|
|
175
|
+
const body = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
176
|
+
return {
|
|
177
|
+
dependencies: asStringMap(body['dependencies']),
|
|
178
|
+
devDependencies: asStringMap(body['devDependencies']),
|
|
179
|
+
peerDependencies: asStringMap(body['peerDependencies']),
|
|
180
|
+
optionalDependencies: asStringMap(body['optionalDependencies']),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return { dependencies: {}, devDependencies: {}, peerDependencies: {}, optionalDependencies: {} };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function asStringMap(value) {
|
|
188
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
189
|
+
return {};
|
|
190
|
+
const out = {};
|
|
191
|
+
for (const [k, v] of Object.entries(value)) {
|
|
192
|
+
if (typeof v === 'string')
|
|
193
|
+
out[k] = v;
|
|
194
|
+
}
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
function collectImportedSpecifiersForPackage(api, cwd, packageDir) {
|
|
198
|
+
const out = [];
|
|
199
|
+
const relDir = nodePath.relative(cwd, packageDir).replace(/\\/g, '/');
|
|
200
|
+
for (const file of api.allFiles()) {
|
|
201
|
+
if (file.kind !== NodeKind.File)
|
|
202
|
+
continue;
|
|
203
|
+
const p = file.path ?? '';
|
|
204
|
+
if (!p.startsWith(relDir + '/src/') && !p.startsWith(relDir + '/'))
|
|
205
|
+
continue;
|
|
206
|
+
// Each ImportsFile edge resolves to a file node; we want the *raw*
|
|
207
|
+
// import specifier, which the graph carries on the edge's data
|
|
208
|
+
// payload. We don't have direct access here, so we approximate by
|
|
209
|
+
// reading the file contents and extracting from-clauses.
|
|
210
|
+
const abs = nodePath.isAbsolute(p) ? p : nodePath.join(cwd, p);
|
|
211
|
+
if (!existsSync(abs))
|
|
212
|
+
continue;
|
|
213
|
+
let body;
|
|
214
|
+
try {
|
|
215
|
+
body = readFileSync(abs, 'utf8');
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
for (const spec of extractRootSpecifiers(body)) {
|
|
221
|
+
if (isBuiltinModule(spec))
|
|
222
|
+
continue;
|
|
223
|
+
if (spec.startsWith('.') || spec.startsWith('/'))
|
|
224
|
+
continue; // relative
|
|
225
|
+
out.push(rootOfSpecifier(spec));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
const IMPORT_FROM_RE = /(?:^|\n)\s*(?:import|export)\s+[^;]*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
231
|
+
const REQUIRE_RE = /\brequire\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
232
|
+
const DYNAMIC_IMPORT_RE = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
233
|
+
function extractRootSpecifiers(body) {
|
|
234
|
+
const out = [];
|
|
235
|
+
for (const m of body.matchAll(IMPORT_FROM_RE)) {
|
|
236
|
+
if (m[1])
|
|
237
|
+
out.push(m[1]);
|
|
238
|
+
}
|
|
239
|
+
for (const m of body.matchAll(REQUIRE_RE)) {
|
|
240
|
+
if (m[1])
|
|
241
|
+
out.push(m[1]);
|
|
242
|
+
}
|
|
243
|
+
for (const m of body.matchAll(DYNAMIC_IMPORT_RE)) {
|
|
244
|
+
if (m[1])
|
|
245
|
+
out.push(m[1]);
|
|
246
|
+
}
|
|
247
|
+
return out;
|
|
248
|
+
}
|
|
249
|
+
function rootOfSpecifier(spec) {
|
|
250
|
+
if (spec.startsWith('@')) {
|
|
251
|
+
const parts = spec.split('/');
|
|
252
|
+
return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : spec;
|
|
253
|
+
}
|
|
254
|
+
return spec.split('/')[0];
|
|
255
|
+
}
|
|
256
|
+
function isBuiltinModule(spec) {
|
|
257
|
+
if (spec.startsWith('node:'))
|
|
258
|
+
return true;
|
|
259
|
+
// Common bare-name builtins.
|
|
260
|
+
return new Set([
|
|
261
|
+
'fs', 'path', 'os', 'crypto', 'http', 'https', 'url', 'util', 'stream',
|
|
262
|
+
'events', 'child_process', 'process', 'buffer', 'querystring', 'zlib',
|
|
263
|
+
'tls', 'net', 'dns', 'dgram', 'cluster', 'worker_threads', 'perf_hooks',
|
|
264
|
+
'readline', 'tty', 'vm',
|
|
265
|
+
]).has(spec);
|
|
266
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAyOhC,eAAO,MAAM,aAAa,EAAE,eAW3B,CAAC;AA+bF,eAAO,MAAM,qBAAqB,EAAE,eAmCnC,CAAC;AAuDF,eAAO,MAAM,yBAAyB,EAAE,eAavC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,eA2CtC,CAAC;AAgCF,eAAO,MAAM,6BAA6B,EAAE,eAa3C,CAAC"}
|
|
@@ -5,6 +5,7 @@ import { buildSurfaceSummary } from "../surface/surface-summary.js";
|
|
|
5
5
|
import { renderShapeLine } from "../surface/shape-defaults.js";
|
|
6
6
|
import { existsSync } from 'node:fs';
|
|
7
7
|
import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../command-registry.js";
|
|
8
|
+
import { SemanticIndex, listIndexableFiles } from '@shrkcrft/embeddings';
|
|
8
9
|
import { asJson, header, kv } from "../output/format-output.js";
|
|
9
10
|
import { maybeRunInWatchMode } from "../output/watch-loop.js";
|
|
10
11
|
import { doctorHints, renderFailureHints } from "../output/failure-hints.js";
|
|
@@ -139,6 +140,64 @@ function isBlockerCheck(check) {
|
|
|
139
140
|
async function runDoctorOnce(args) {
|
|
140
141
|
return doctorCommandImpl(args);
|
|
141
142
|
}
|
|
143
|
+
function augmentWithSemanticIndexCheck(result, cwd) {
|
|
144
|
+
const current = listIndexableFiles(cwd, 5000);
|
|
145
|
+
const report = SemanticIndex.freshnessReport(cwd, current);
|
|
146
|
+
const check = renderSemanticIndexCheck(report);
|
|
147
|
+
const checks = [...result.checks, check];
|
|
148
|
+
const summary = { ...result.summary };
|
|
149
|
+
if (check.severity === DoctorSeverity.Ok)
|
|
150
|
+
summary.ok = (summary.ok ?? 0) + 1;
|
|
151
|
+
else if (check.severity === DoctorSeverity.Info)
|
|
152
|
+
summary.info = (summary.info ?? 0) + 1;
|
|
153
|
+
else if (check.severity === DoctorSeverity.Warning)
|
|
154
|
+
summary.warnings = (summary.warnings ?? 0) + 1;
|
|
155
|
+
else if (check.severity === DoctorSeverity.Error)
|
|
156
|
+
summary.errors = (summary.errors ?? 0) + 1;
|
|
157
|
+
return { ...result, checks, summary };
|
|
158
|
+
}
|
|
159
|
+
function renderSemanticIndexCheck(report) {
|
|
160
|
+
if (!report.hasIndex) {
|
|
161
|
+
return {
|
|
162
|
+
id: 'semantic-index-missing',
|
|
163
|
+
title: 'Semantic embedding index',
|
|
164
|
+
severity: DoctorSeverity.Info,
|
|
165
|
+
message: `No semantic index found — ${report.untracked} indexable files on disk. ` +
|
|
166
|
+
'Run `shrk smart-context embeddings-build` to enable embedding-backed retrieval in smart-context.',
|
|
167
|
+
category: 'semantic-index',
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (report.corrupt) {
|
|
171
|
+
return {
|
|
172
|
+
id: 'semantic-index-corrupt',
|
|
173
|
+
title: 'Semantic embedding index',
|
|
174
|
+
severity: DoctorSeverity.Error,
|
|
175
|
+
message: 'Semantic index meta is corrupt.',
|
|
176
|
+
fix: 'shrk smart-context embeddings-build --rebuild',
|
|
177
|
+
category: 'semantic-index',
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const driftCount = report.stale + report.missing + report.untracked;
|
|
181
|
+
const driftPct = report.indexed > 0 ? (driftCount * 100) / report.indexed : 0;
|
|
182
|
+
if (driftCount === 0) {
|
|
183
|
+
return {
|
|
184
|
+
id: 'semantic-index-fresh',
|
|
185
|
+
title: 'Semantic embedding index',
|
|
186
|
+
severity: DoctorSeverity.Ok,
|
|
187
|
+
message: `Index fresh — ${report.indexed} files (model ${report.model}).`,
|
|
188
|
+
category: 'semantic-index',
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const severity = driftPct >= 10 ? DoctorSeverity.Warning : DoctorSeverity.Info;
|
|
192
|
+
return {
|
|
193
|
+
id: 'semantic-index-stale',
|
|
194
|
+
title: 'Semantic embedding index',
|
|
195
|
+
severity,
|
|
196
|
+
message: `${report.indexed} indexed; ${report.stale} stale, ${report.missing} deleted, ${report.untracked} new on disk (≈ ${Math.round(driftPct)}% drift).`,
|
|
197
|
+
fix: 'shrk smart-context embeddings-build',
|
|
198
|
+
category: 'semantic-index',
|
|
199
|
+
};
|
|
200
|
+
}
|
|
142
201
|
export const doctorCommand = {
|
|
143
202
|
name: 'doctor',
|
|
144
203
|
description: 'Validate the local SharkCraft setup (config, knowledge, templates, project). `--focus errors|warnings-new|info`, `--hide <category,...>`, `--quiet-known` filter the headline view using `sharkcraft/doctor.suppressions.json`. `--watch`/`--once`/`--debounce` for live mode. `--explain-quality` shows the per-warning "why this matters" line so warnings stop being permanent yellow noise. `--blockers` shows only must-fix findings (errors + warning-category in {config-invalid, pack-signature-invalid, plan-signature-divergent, asset-load-failed}); exit code is non-zero iff a blocker remains. Subcommands: `suppress`, `suppressions list|check`, `watch`.',
|
|
@@ -163,7 +222,7 @@ async function doctorCommandImpl(args) {
|
|
|
163
222
|
inspectOpts.loaderTimeoutMs = loaderTimeout;
|
|
164
223
|
}
|
|
165
224
|
const inspection = await inspectSharkcraft(inspectOpts);
|
|
166
|
-
const result = runDoctor(inspection);
|
|
225
|
+
const result = augmentWithSemanticIndexCheck(runDoctor(inspection), cwd);
|
|
167
226
|
const report = buildAiReadinessReport(inspection);
|
|
168
227
|
if (debug) {
|
|
169
228
|
process.stderr.write(`[debug] inspection elapsed ${inspection.inspectionElapsedMs}ms cache=${inspection.cacheEnabled ? 'on' : 'off'} loaders=${inspection.loaderDiagnostics.length}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-code-subverbs.d.ts","sourceRoot":"","sources":["../../src/commands/graph-code-subverbs.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQ3F,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,CAmEpE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"graph-code-subverbs.d.ts","sourceRoot":"","sources":["../../src/commands/graph-code-subverbs.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQ3F,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,CAmEpE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiEtE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgDtE;AAID,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAsJvE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAwFtE;AAID,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCvE"}
|