@shrkcrft/cli 0.1.0-alpha.12 → 0.1.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/knowledge-audit-llm.d.ts +19 -0
- package/dist/audit/knowledge-audit-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-audit-llm.js +164 -0
- package/dist/audit/knowledge-audit.d.ts +61 -0
- package/dist/audit/knowledge-audit.d.ts.map +1 -0
- package/dist/audit/knowledge-audit.js +203 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts +11 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan-llm.js +141 -0
- package/dist/audit/knowledge-fix-plan.d.ts +41 -0
- package/dist/audit/knowledge-fix-plan.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan.js +125 -0
- package/dist/audit/pipeline-audit-llm.d.ts +11 -0
- package/dist/audit/pipeline-audit-llm.d.ts.map +1 -0
- package/dist/audit/pipeline-audit-llm.js +134 -0
- package/dist/audit/pipeline-audit.d.ts +69 -0
- package/dist/audit/pipeline-audit.d.ts.map +1 -0
- package/dist/audit/pipeline-audit.js +166 -0
- package/dist/audit/templates-audit-llm.d.ts +19 -0
- package/dist/audit/templates-audit-llm.d.ts.map +1 -0
- package/dist/audit/templates-audit-llm.js +207 -0
- package/dist/audit/templates-audit.d.ts +63 -0
- package/dist/audit/templates-audit.d.ts.map +1 -0
- package/dist/audit/templates-audit.js +171 -0
- package/dist/audit/templates-fix-plan-llm.d.ts +19 -0
- package/dist/audit/templates-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan-llm.js +162 -0
- package/dist/audit/templates-fix-plan.d.ts +37 -0
- package/dist/audit/templates-fix-plan.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan.js +174 -0
- package/dist/commands/ai-status.command.d.ts +19 -0
- package/dist/commands/ai-status.command.d.ts.map +1 -0
- package/dist/commands/ai-status.command.js +94 -0
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +10 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +40 -2
- package/dist/commands/smart-context.command.d.ts +28 -0
- package/dist/commands/smart-context.command.d.ts.map +1 -1
- package/dist/commands/smart-context.command.js +762 -1
- package/dist/commands/surface.command.d.ts +1 -0
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +10 -3
- package/dist/commands/template-quality.command.d.ts.map +1 -1
- package/dist/commands/template-quality.command.js +39 -3
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +37 -2
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +40 -18
- package/package.json +32 -32
|
@@ -10,6 +10,7 @@ import { type ICommandHandler } from '../command-registry.js';
|
|
|
10
10
|
* - unhide <command> reverse hide
|
|
11
11
|
* - reset clear surface.enabled + surface.hidden
|
|
12
12
|
* - explain <command> why this command has its current tier
|
|
13
|
+
* - profiles [get <id>] list surface profiles (or show one)
|
|
13
14
|
*/
|
|
14
15
|
export declare const surfaceCommand: ICommandHandler;
|
|
15
16
|
//# sourceMappingURL=surface.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.command.d.ts","sourceRoot":"","sources":["../../src/commands/surface.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAiBhC
|
|
1
|
+
{"version":3,"file":"surface.command.d.ts","sourceRoot":"","sources":["../../src/commands/surface.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAiBhC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,EAAE,eAmC5B,CAAC"}
|
|
@@ -15,11 +15,12 @@ import { applySurfaceEdit, defaultConfigFile, planSurfaceEdit, } from "../surfac
|
|
|
15
15
|
* - unhide <command> reverse hide
|
|
16
16
|
* - reset clear surface.enabled + surface.hidden
|
|
17
17
|
* - explain <command> why this command has its current tier
|
|
18
|
+
* - profiles [get <id>] list surface profiles (or show one)
|
|
18
19
|
*/
|
|
19
20
|
export const surfaceCommand = {
|
|
20
21
|
name: 'surface',
|
|
21
22
|
description: 'Inspect or change the adaptive command surface (core / extended / experimental tiers).',
|
|
22
|
-
usage: 'shrk surface <list|enable|disable|hide|unhide|reset|explain> [name] [--write] [--json]',
|
|
23
|
+
usage: 'shrk surface <list|enable|disable|hide|unhide|reset|explain|profiles> [name] [--write] [--json]',
|
|
23
24
|
async run(args) {
|
|
24
25
|
const [verb, ...rest] = args.positional;
|
|
25
26
|
const json = flagBool(args, 'json');
|
|
@@ -84,7 +85,7 @@ async function runProfiles(opts) {
|
|
|
84
85
|
const found = availableProfiles.find((p) => p.id === opts.target);
|
|
85
86
|
if (!found) {
|
|
86
87
|
process.stderr.write(`Unknown profile: ${opts.target}\n`);
|
|
87
|
-
return
|
|
88
|
+
return 2;
|
|
88
89
|
}
|
|
89
90
|
if (opts.json) {
|
|
90
91
|
process.stdout.write(asJson(found) + '\n');
|
|
@@ -171,10 +172,16 @@ async function runExplain({ cwd, json, target }) {
|
|
|
171
172
|
process.stderr.write('Usage: shrk surface explain <command>\n');
|
|
172
173
|
return 2;
|
|
173
174
|
}
|
|
174
|
-
const { context, activeProfile } = await loadSurfaceContext({ cwd });
|
|
175
|
+
const { context, activeProfile, availableProfiles } = await loadSurfaceContext({ cwd });
|
|
175
176
|
const summary = buildSurfaceSummary(context);
|
|
176
177
|
const view = findCommandInSummary(summary, target);
|
|
177
178
|
if (!view) {
|
|
179
|
+
// A common mix-up: `surface explain <profile>`. `explain` is for commands;
|
|
180
|
+
// point the user at the profile-aware verb instead of a bare "unknown".
|
|
181
|
+
if (availableProfiles.some((p) => p.id === target)) {
|
|
182
|
+
process.stderr.write(`'${target}' is a surface profile, not a command. Try: shrk surface profiles get ${target}\n`);
|
|
183
|
+
return 2;
|
|
184
|
+
}
|
|
178
185
|
process.stderr.write(`Unknown command: ${target}\n`);
|
|
179
186
|
return 2;
|
|
180
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-quality.command.d.ts","sourceRoot":"","sources":["../../src/commands/template-quality.command.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"template-quality.command.d.ts","sourceRoot":"","sources":["../../src/commands/template-quality.command.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,oBAAoB,EAAE,eAsDlC,CAAC;AA4EF,eAAO,MAAM,oBAAoB,EAAE,eAmBlC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAuBtC,CAAC"}
|
|
@@ -3,18 +3,32 @@ import * as nodePath from 'node:path';
|
|
|
3
3
|
import { inspectSharkcraft, lintTemplates, testTemplates, } from '@shrkcrft/inspector';
|
|
4
4
|
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
5
5
|
import { asJson, header } from "../output/format-output.js";
|
|
6
|
+
import { enrichWithLlmRecommendations, renderRecommendationsMarkdown, } from '@shrkcrft/ai';
|
|
6
7
|
export const templatesLintCommand = {
|
|
7
8
|
name: 'lint',
|
|
8
|
-
description: 'Lint registered templates (titles, vars, target safety, placeholders). --fix-preview emits a TODO patch per finding under .sharkcraft/fixes/templates-lint/ (preview only — never mutates source).',
|
|
9
|
-
usage: 'shrk templates lint [<id>] [--fix-preview] [--json]',
|
|
9
|
+
description: 'Lint registered templates (titles, vars, target safety, placeholders). --fix-preview emits a TODO patch per finding under .sharkcraft/fixes/templates-lint/ (preview only — never mutates source). --llm-recommendations layers concrete next-steps onto the deterministic findings when a local LLM is reachable.',
|
|
10
|
+
usage: 'shrk templates lint [<id>] [--fix-preview] [--json] [--llm-recommendations] [--provider auto|ollama|llamacpp]',
|
|
10
11
|
async run(args) {
|
|
11
12
|
const cwd = resolveCwd(args);
|
|
12
13
|
const inspection = await inspectSharkcraft({ cwd });
|
|
13
14
|
const ids = args.positional.length > 0 ? args.positional : undefined;
|
|
14
15
|
const report = lintTemplates(inspection, ids);
|
|
15
16
|
const fixPreview = flagBool(args, 'fix-preview');
|
|
17
|
+
const wantLlm = flagBool(args, 'llm-recommendations');
|
|
18
|
+
const llmEnvelope = wantLlm
|
|
19
|
+
? await enrichWithLlmRecommendations({
|
|
20
|
+
surface: 'templates-lint',
|
|
21
|
+
deterministicSummary: summariseLintResults(report.results),
|
|
22
|
+
providerKind: flagString(args, 'provider') ?? undefined,
|
|
23
|
+
ask: 'For each non-passing template, suggest ONE concrete edit in sharkcraft/templates.ts: name the field (description, variables[i].examples, related[i], etc.) and the literal value or removal. Skip templates with only `info`-level issues unless a clear improvement exists.',
|
|
24
|
+
maxTokens: 1024,
|
|
25
|
+
})
|
|
26
|
+
: null;
|
|
16
27
|
if (flagBool(args, 'json')) {
|
|
17
|
-
process.stdout.write(asJson(
|
|
28
|
+
process.stdout.write(asJson({
|
|
29
|
+
...report,
|
|
30
|
+
...(llmEnvelope ? { llmRecommendations: llmEnvelope } : {}),
|
|
31
|
+
}) + '\n');
|
|
18
32
|
if (fixPreview)
|
|
19
33
|
writeFixPreviewPatches(cwd, report.results);
|
|
20
34
|
return report.summary.errors > 0 ? 1 : 0;
|
|
@@ -35,9 +49,31 @@ export const templatesLintCommand = {
|
|
|
35
49
|
process.stdout.write('\nNo fix-preview patches needed.\n');
|
|
36
50
|
}
|
|
37
51
|
}
|
|
52
|
+
if (llmEnvelope) {
|
|
53
|
+
process.stdout.write('\n');
|
|
54
|
+
process.stdout.write(renderRecommendationsMarkdown(llmEnvelope));
|
|
55
|
+
}
|
|
38
56
|
return report.summary.errors > 0 ? 1 : 0;
|
|
39
57
|
},
|
|
40
58
|
};
|
|
59
|
+
function summariseLintResults(results) {
|
|
60
|
+
const lines = [];
|
|
61
|
+
for (const r of results) {
|
|
62
|
+
lines.push(`## ${r.passed ? 'OK' : 'FAIL'} ${r.templateId}`);
|
|
63
|
+
if (r.issues.length === 0) {
|
|
64
|
+
lines.push('(no issues)');
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
for (const i of r.issues) {
|
|
68
|
+
lines.push(`- ${i.severity} \`${i.code}\` — ${i.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
lines.push('');
|
|
72
|
+
}
|
|
73
|
+
if (lines.length === 0)
|
|
74
|
+
lines.push('(no templates registered)');
|
|
75
|
+
return lines.join('\n');
|
|
76
|
+
}
|
|
41
77
|
/** Write a per-template TODO patch under `.sharkcraft/fixes/templates-lint/`. */
|
|
42
78
|
function writeFixPreviewPatches(cwd, results) {
|
|
43
79
|
const dir = nodePath.join(cwd, '.sharkcraft', 'fixes', 'templates-lint');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.command.d.ts","sourceRoot":"","sources":["../../src/commands/templates.command.ts"],"names":[],"mappings":"AAyBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.command.d.ts","sourceRoot":"","sources":["../../src/commands/templates.command.ts"],"names":[],"mappings":"AAyBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAUhC,eAAO,MAAM,oBAAoB,EAAE,eA6DlC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAmBlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eA+CjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAgBpC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAiDrC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,eAWnC,CAAC;AAgNF,eAAO,MAAM,2BAA2B,EAAE,eA+BzC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,eAOnC,CAAC;AA2GF,eAAO,MAAM,wBAAwB,EAAE,eA+FtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAKjC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAyCpC,CAAC;AAwHF,eAAO,MAAM,sBAAsB,EAAE,eAiKpC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAkEpC,CAAC"}
|
|
@@ -9,6 +9,7 @@ import { flagBool, flagList, flagString, flagVars, resolveCwd, } from "../comman
|
|
|
9
9
|
import { asJson, header, kv } from "../output/format-output.js";
|
|
10
10
|
import { maybeRunInWatchMode } from "../output/watch-loop.js";
|
|
11
11
|
import { renderFailureHints, templateDriftHints } from "../output/failure-hints.js";
|
|
12
|
+
import { enrichWithLlmRecommendations, renderRecommendationsMarkdown, } from '@shrkcrft/ai';
|
|
12
13
|
export const templatesVarsCommand = {
|
|
13
14
|
name: 'vars',
|
|
14
15
|
description: 'Show the variables a template accepts (required/optional/defaults/examples).',
|
|
@@ -209,8 +210,8 @@ export const templatesPreviewCommand = {
|
|
|
209
210
|
};
|
|
210
211
|
export const templatesDriftCommand = {
|
|
211
212
|
name: 'drift',
|
|
212
|
-
description: 'Verify every registered template against the workspace. Severity controls and `--watch [--once] [--debounce N]` supported. Read-only.',
|
|
213
|
-
usage: 'shrk templates drift [--template <id>] [--pack <packId>] [--var key=value ...] [--min-severity error|warning|info] [--hide <code>[,<code>...]] [--strict] [--ci] [--format text|markdown|html|json] [--report] [--output <path>] [--json] [--watch [--once] [--debounce N]]',
|
|
213
|
+
description: 'Verify every registered template against the workspace. Severity controls and `--watch [--once] [--debounce N]` supported. `--llm-recommendations` layers a local-LLM-derived list of concrete next-steps on top of the deterministic findings (no-op when no provider reachable). Read-only.',
|
|
214
|
+
usage: 'shrk templates drift [--template <id>] [--pack <packId>] [--var key=value ...] [--min-severity error|warning|info] [--hide <code>[,<code>...]] [--strict] [--ci] [--format text|markdown|html|json] [--report] [--output <path>] [--json] [--llm-recommendations] [--provider auto|ollama|llamacpp] [--watch [--once] [--debounce N]]',
|
|
214
215
|
async run(args) {
|
|
215
216
|
const watchExit = await maybeRunInWatchMode(args, templatesDriftImpl);
|
|
216
217
|
if (watchExit !== null)
|
|
@@ -272,6 +273,16 @@ async function templatesDriftImpl(args) {
|
|
|
272
273
|
else
|
|
273
274
|
filteredFail++;
|
|
274
275
|
}
|
|
276
|
+
const wantLlmRecs = flagBool(args, 'llm-recommendations');
|
|
277
|
+
const llmEnvelope = wantLlmRecs
|
|
278
|
+
? await enrichWithLlmRecommendations({
|
|
279
|
+
surface: 'templates-drift',
|
|
280
|
+
deterministicSummary: summariseDriftEntries(filteredEntries),
|
|
281
|
+
providerKind: flagString(args, 'provider') ?? undefined,
|
|
282
|
+
ask: 'For each FAIL or WARN entry, propose ONE concrete fix the maintainer can apply — name the specific field in `sharkcraft/templates.ts` (or a peer file) to edit. Skip PASS entries unless something is genuinely worth nudging.',
|
|
283
|
+
maxTokens: 1024,
|
|
284
|
+
})
|
|
285
|
+
: null;
|
|
275
286
|
const ciPayload = {
|
|
276
287
|
...report,
|
|
277
288
|
entries: filteredEntries,
|
|
@@ -284,6 +295,7 @@ async function templatesDriftImpl(args) {
|
|
|
284
295
|
minSeverity: minSeverityRaw || 'info',
|
|
285
296
|
hideCodes: [...hideCodes],
|
|
286
297
|
},
|
|
298
|
+
...(llmEnvelope ? { llmRecommendations: llmEnvelope } : {}),
|
|
287
299
|
};
|
|
288
300
|
const exitNonZero = ci
|
|
289
301
|
? filteredFail > 0 || (strict && filteredWarn > 0)
|
|
@@ -330,8 +342,31 @@ async function templatesDriftImpl(args) {
|
|
|
330
342
|
if (exitNonZero) {
|
|
331
343
|
process.stdout.write(renderFailureHints(templateDriftHints()));
|
|
332
344
|
}
|
|
345
|
+
if (llmEnvelope) {
|
|
346
|
+
process.stdout.write('\n');
|
|
347
|
+
process.stdout.write(renderRecommendationsMarkdown(llmEnvelope));
|
|
348
|
+
}
|
|
333
349
|
return exitNonZero ? 1 : 0;
|
|
334
350
|
}
|
|
351
|
+
function summariseDriftEntries(entries) {
|
|
352
|
+
const lines = [];
|
|
353
|
+
for (const e of entries) {
|
|
354
|
+
const tag = e.status === TemplateDriftStatus.Pass ? 'PASS' : e.status === TemplateDriftStatus.Warn ? 'WARN' : 'FAIL';
|
|
355
|
+
lines.push(`## [${tag}] ${e.templateId}${e.templateName ? ` — ${e.templateName}` : ''}`);
|
|
356
|
+
if (e.issues.length === 0) {
|
|
357
|
+
lines.push('(no issues)');
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
for (const i of e.issues) {
|
|
361
|
+
lines.push(`- ${i.severity} \`${i.code}\` — ${i.message}${i.suggestedFix ? ` (suggested: ${i.suggestedFix})` : ''}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
lines.push('');
|
|
365
|
+
}
|
|
366
|
+
if (lines.length === 0)
|
|
367
|
+
lines.push('(no templates in this drift report)');
|
|
368
|
+
return lines.join('\n');
|
|
369
|
+
}
|
|
335
370
|
function renderDriftMarkdown(p) {
|
|
336
371
|
const out = [];
|
|
337
372
|
out.push('# Template drift');
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,eAAe,EAIhB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,eAAe,EAIhB,MAAM,uBAAuB,CAAC;AAoX/B,wBAAgB,aAAa,IAAI,eAAe,CAuX/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BrE;AAkGD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CA4CxE"}
|
package/dist/main.js
CHANGED
|
@@ -56,7 +56,8 @@ import { dashboardCommand } from "./commands/dashboard.command.js";
|
|
|
56
56
|
import { dashboardDiffCommand, dashboardExportCommand, } from "./commands/dashboard-export.command.js";
|
|
57
57
|
import { importCommand } from "./commands/import.command.js";
|
|
58
58
|
import { askCommand } from "./commands/ask.command.js";
|
|
59
|
-
import {
|
|
59
|
+
import { aiStatusCommand } from "./commands/ai-status.command.js";
|
|
60
|
+
import { smartContextAuditKnowledgeCommand, smartContextAuditPipelinesCommand, smartContextAuditTemplatesCommand, smartContextCommand, smartContextEmbeddingsBuildCommand, smartContextEmbeddingsStatusCommand, smartContextListCommand, smartContextPlanAheadCommand, smartContextShowCommand, } from "./commands/smart-context.command.js";
|
|
60
61
|
import { spikeCommand } from "./commands/spike.command.js";
|
|
61
62
|
import { depsAuditCommand } from "./commands/deps-audit.command.js";
|
|
62
63
|
import { scaffoldValidateCommand } from "./commands/scaffold-validate.command.js";
|
|
@@ -142,6 +143,7 @@ export function buildRegistry() {
|
|
|
142
143
|
registry.register(initCommand);
|
|
143
144
|
registry.register(inspectCommand);
|
|
144
145
|
registry.register(doctorCommand);
|
|
146
|
+
registry.register(aiStatusCommand);
|
|
145
147
|
registry.registerSubcommand('doctor', doctorSuppressCommand);
|
|
146
148
|
registry.registerSubcommand('doctor', doctorSuppressionsCommand);
|
|
147
149
|
// Acknowledgements with required reason + expiry.
|
|
@@ -217,6 +219,9 @@ export function buildRegistry() {
|
|
|
217
219
|
registry.registerSubcommand('smart-context', smartContextShowCommand);
|
|
218
220
|
registry.registerSubcommand('smart-context', smartContextEmbeddingsBuildCommand);
|
|
219
221
|
registry.registerSubcommand('smart-context', smartContextEmbeddingsStatusCommand);
|
|
222
|
+
registry.registerSubcommand('smart-context', smartContextAuditTemplatesCommand);
|
|
223
|
+
registry.registerSubcommand('smart-context', smartContextAuditKnowledgeCommand);
|
|
224
|
+
registry.registerSubcommand('smart-context', smartContextAuditPipelinesCommand);
|
|
220
225
|
registry.register(spikeCommand);
|
|
221
226
|
registry.register(depsAuditCommand);
|
|
222
227
|
registry.register(scaffoldValidateCommand);
|
|
@@ -864,24 +869,41 @@ if (isMain ||
|
|
|
864
869
|
catch {
|
|
865
870
|
// ignore flush failures
|
|
866
871
|
}
|
|
867
|
-
// Prefer
|
|
868
|
-
//
|
|
869
|
-
// still
|
|
870
|
-
//
|
|
871
|
-
//
|
|
872
|
-
// `ggml_metal_device_free
|
|
873
|
-
//
|
|
874
|
-
//
|
|
875
|
-
//
|
|
876
|
-
//
|
|
872
|
+
// Prefer a low-level exit over `process.exit` on Node. Without
|
|
873
|
+
// this, libc++ static destructors run during `process.exit`, and
|
|
874
|
+
// native bindings still resident in memory abort with libc++abi
|
|
875
|
+
// errors AFTER the user's result has already printed:
|
|
876
|
+
// - node-llama-cpp's libggml-metal hits `GGML_ASSERT([rsets->data
|
|
877
|
+
// count] == 0)` in `ggml_metal_device_free` → `zsh: abort`.
|
|
878
|
+
// - onnxruntime-node's worker pool aborts with
|
|
879
|
+
// `libc++abi: mutex lock failed: Invalid argument` after a
|
|
880
|
+
// successful `shrk smart-context embeddings-build`. NOTE:
|
|
881
|
+
// `pipeline.dispose()` returns cleanly, but ONNX worker threads
|
|
882
|
+
// are not actually joined — they continue running briefly and
|
|
883
|
+
// hit the pthread mutex teardown race. There is no JS-layer
|
|
884
|
+
// fix for this; upstream onnxruntime-node 1.21 has the bug.
|
|
885
|
+
// The low-level exit at least suppresses the destructor pass
|
|
886
|
+
// so the failure mode is "noisy stderr, exit code preserved"
|
|
887
|
+
// rather than "destructor cascade".
|
|
877
888
|
//
|
|
878
|
-
//
|
|
879
|
-
//
|
|
880
|
-
//
|
|
881
|
-
//
|
|
882
|
-
// `
|
|
883
|
-
|
|
884
|
-
|
|
889
|
+
// Node exposes the low-level exit under two names depending on the
|
|
890
|
+
// version:
|
|
891
|
+
// - `process._exit` — public alias (older Node; removed from
|
|
892
|
+
// the public surface on Node 22+).
|
|
893
|
+
// - `process.reallyExit` — Node-internal name; still present on
|
|
894
|
+
// Node 22 even when `_exit` is undefined.
|
|
895
|
+
// Try both in order. Bun's process object doesn't expose either,
|
|
896
|
+
// but Bun also doesn't drive shutdown through libuv + libc++ static
|
|
897
|
+
// destructors the same way Node does, so the crash doesn't
|
|
898
|
+
// reproduce there. Fall back to `process.exit` when no low-level
|
|
899
|
+
// hook is available.
|
|
900
|
+
const proc = process;
|
|
901
|
+
const lowLevelExit = typeof proc._exit === 'function'
|
|
902
|
+
? proc._exit
|
|
903
|
+
: typeof proc.reallyExit === 'function'
|
|
904
|
+
? proc.reallyExit
|
|
905
|
+
: null;
|
|
906
|
+
if (lowLevelExit !== null) {
|
|
885
907
|
lowLevelExit(code);
|
|
886
908
|
}
|
|
887
909
|
process.exit(code);
|
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.14",
|
|
4
4
|
"description": "SharkCraft CLI (`shrk`): structured project intelligence for AI coding agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SharkCraft contributors",
|
|
@@ -47,37 +47,37 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@shrkcrft/core": "^0.1.0-alpha.
|
|
51
|
-
"@shrkcrft/config": "^0.1.0-alpha.
|
|
52
|
-
"@shrkcrft/workspace": "^0.1.0-alpha.
|
|
53
|
-
"@shrkcrft/knowledge": "^0.1.0-alpha.
|
|
54
|
-
"@shrkcrft/context": "^0.1.0-alpha.
|
|
55
|
-
"@shrkcrft/rules": "^0.1.0-alpha.
|
|
56
|
-
"@shrkcrft/paths": "^0.1.0-alpha.
|
|
57
|
-
"@shrkcrft/templates": "^0.1.0-alpha.
|
|
58
|
-
"@shrkcrft/plugin-api": "^0.1.0-alpha.
|
|
59
|
-
"@shrkcrft/dashboard": "^0.1.0-alpha.
|
|
60
|
-
"@shrkcrft/dashboard-api": "^0.1.0-alpha.
|
|
61
|
-
"@shrkcrft/pipelines": "^0.1.0-alpha.
|
|
62
|
-
"@shrkcrft/presets": "^0.1.0-alpha.
|
|
63
|
-
"@shrkcrft/boundaries": "^0.1.0-alpha.
|
|
64
|
-
"@shrkcrft/graph": "^0.1.0-alpha.
|
|
65
|
-
"@shrkcrft/rule-graph": "^0.1.0-alpha.
|
|
66
|
-
"@shrkcrft/structural-search": "^0.1.0-alpha.
|
|
67
|
-
"@shrkcrft/impact-engine": "^0.1.0-alpha.
|
|
68
|
-
"@shrkcrft/context-planner": "^0.1.0-alpha.
|
|
69
|
-
"@shrkcrft/architecture-guard": "^0.1.0-alpha.
|
|
70
|
-
"@shrkcrft/framework-scanners": "^0.1.0-alpha.
|
|
71
|
-
"@shrkcrft/api-surface-diff": "^0.1.0-alpha.
|
|
72
|
-
"@shrkcrft/quality-gates": "^0.1.0-alpha.
|
|
73
|
-
"@shrkcrft/migrate": "^0.1.0-alpha.
|
|
74
|
-
"@shrkcrft/generator": "^0.1.0-alpha.
|
|
75
|
-
"@shrkcrft/importer": "^0.1.0-alpha.
|
|
76
|
-
"@shrkcrft/inspector": "^0.1.0-alpha.
|
|
77
|
-
"@shrkcrft/ai": "^0.1.0-alpha.
|
|
78
|
-
"@shrkcrft/embeddings": "^0.1.0-alpha.
|
|
79
|
-
"@shrkcrft/shared": "^0.1.0-alpha.
|
|
80
|
-
"@shrkcrft/mcp-server": "^0.1.0-alpha.
|
|
50
|
+
"@shrkcrft/core": "^0.1.0-alpha.14",
|
|
51
|
+
"@shrkcrft/config": "^0.1.0-alpha.14",
|
|
52
|
+
"@shrkcrft/workspace": "^0.1.0-alpha.14",
|
|
53
|
+
"@shrkcrft/knowledge": "^0.1.0-alpha.14",
|
|
54
|
+
"@shrkcrft/context": "^0.1.0-alpha.14",
|
|
55
|
+
"@shrkcrft/rules": "^0.1.0-alpha.14",
|
|
56
|
+
"@shrkcrft/paths": "^0.1.0-alpha.14",
|
|
57
|
+
"@shrkcrft/templates": "^0.1.0-alpha.14",
|
|
58
|
+
"@shrkcrft/plugin-api": "^0.1.0-alpha.14",
|
|
59
|
+
"@shrkcrft/dashboard": "^0.1.0-alpha.14",
|
|
60
|
+
"@shrkcrft/dashboard-api": "^0.1.0-alpha.14",
|
|
61
|
+
"@shrkcrft/pipelines": "^0.1.0-alpha.14",
|
|
62
|
+
"@shrkcrft/presets": "^0.1.0-alpha.14",
|
|
63
|
+
"@shrkcrft/boundaries": "^0.1.0-alpha.14",
|
|
64
|
+
"@shrkcrft/graph": "^0.1.0-alpha.14",
|
|
65
|
+
"@shrkcrft/rule-graph": "^0.1.0-alpha.14",
|
|
66
|
+
"@shrkcrft/structural-search": "^0.1.0-alpha.14",
|
|
67
|
+
"@shrkcrft/impact-engine": "^0.1.0-alpha.14",
|
|
68
|
+
"@shrkcrft/context-planner": "^0.1.0-alpha.14",
|
|
69
|
+
"@shrkcrft/architecture-guard": "^0.1.0-alpha.14",
|
|
70
|
+
"@shrkcrft/framework-scanners": "^0.1.0-alpha.14",
|
|
71
|
+
"@shrkcrft/api-surface-diff": "^0.1.0-alpha.14",
|
|
72
|
+
"@shrkcrft/quality-gates": "^0.1.0-alpha.14",
|
|
73
|
+
"@shrkcrft/migrate": "^0.1.0-alpha.14",
|
|
74
|
+
"@shrkcrft/generator": "^0.1.0-alpha.14",
|
|
75
|
+
"@shrkcrft/importer": "^0.1.0-alpha.14",
|
|
76
|
+
"@shrkcrft/inspector": "^0.1.0-alpha.14",
|
|
77
|
+
"@shrkcrft/ai": "^0.1.0-alpha.14",
|
|
78
|
+
"@shrkcrft/embeddings": "^0.1.0-alpha.14",
|
|
79
|
+
"@shrkcrft/shared": "^0.1.0-alpha.14",
|
|
80
|
+
"@shrkcrft/mcp-server": "^0.1.0-alpha.14",
|
|
81
81
|
"@huggingface/transformers": "^3.7.5"
|
|
82
82
|
},
|
|
83
83
|
"publishConfig": {
|