@shrkcrft/cli 0.1.0-alpha.1 → 0.1.0-alpha.10
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/README.md +1 -1
- package/dist/commands/api-diff.command.d.ts +11 -0
- package/dist/commands/api-diff.command.d.ts.map +1 -0
- package/dist/commands/api-diff.command.js +116 -0
- package/dist/commands/arch.command.d.ts +9 -0
- package/dist/commands/arch.command.d.ts.map +1 -0
- package/dist/commands/arch.command.js +186 -0
- package/dist/commands/boundaries.command.d.ts.map +1 -1
- package/dist/commands/boundaries.command.js +0 -12
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +20 -30
- package/dist/commands/code-intel.command.d.ts +18 -0
- package/dist/commands/code-intel.command.d.ts.map +1 -0
- package/dist/commands/code-intel.command.js +146 -0
- package/dist/commands/command-catalog.d.ts +7 -3
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +201 -47
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +4 -4
- package/dist/commands/completion.command.d.ts +10 -0
- package/dist/commands/completion.command.d.ts.map +1 -0
- package/dist/commands/completion.command.js +121 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +5 -22
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +89 -0
- package/dist/commands/diff-check.command.d.ts +30 -0
- package/dist/commands/diff-check.command.d.ts.map +1 -0
- package/dist/commands/diff-check.command.js +210 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +42 -9
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +76 -3
- package/dist/commands/framework.command.d.ts +12 -0
- package/dist/commands/framework.command.d.ts.map +1 -0
- package/dist/commands/framework.command.js +180 -0
- package/dist/commands/gate.command.d.ts +15 -0
- package/dist/commands/gate.command.d.ts.map +1 -0
- package/dist/commands/gate.command.js +296 -0
- package/dist/commands/graph-code-subverbs.d.ts +11 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
- package/dist/commands/graph-code-subverbs.js +818 -0
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +22 -0
- package/dist/commands/help.command.d.ts +4 -3
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +77 -21
- package/dist/commands/helper.command.js +1 -1
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +170 -1
- package/dist/commands/import.command.d.ts.map +1 -1
- package/dist/commands/import.command.js +121 -5
- package/dist/commands/init.command.d.ts.map +1 -1
- package/dist/commands/init.command.js +184 -16
- package/dist/commands/mcp.command.d.ts.map +1 -1
- package/dist/commands/mcp.command.js +2 -131
- package/dist/commands/migrate.command.d.ts +13 -0
- package/dist/commands/migrate.command.d.ts.map +1 -0
- package/dist/commands/migrate.command.js +152 -0
- package/dist/commands/onboard.command.d.ts.map +1 -1
- package/dist/commands/onboard.command.js +3 -15
- package/dist/commands/packs-new.d.ts +1 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +5 -36
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +3 -17
- package/dist/commands/plan-context.command.d.ts +11 -0
- package/dist/commands/plan-context.command.d.ts.map +1 -0
- package/dist/commands/plan-context.command.js +77 -0
- package/dist/commands/profiles.command.js +4 -4
- package/dist/commands/release.command.js +13 -13
- package/dist/commands/review.command.d.ts.map +1 -1
- package/dist/commands/review.command.js +2 -28
- package/dist/commands/rule-graph-subverbs.d.ts +3 -0
- package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
- package/dist/commands/rule-graph-subverbs.js +132 -0
- package/dist/commands/search-structural.command.d.ts +18 -0
- package/dist/commands/search-structural.command.d.ts.map +1 -0
- package/dist/commands/search-structural.command.js +376 -0
- package/dist/commands/search.command.js +1 -1
- package/dist/commands/task-context.command.js +0 -16
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +8 -2
- package/dist/dashboard/code-intelligence-data.d.ts +33 -0
- package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
- package/dist/dashboard/code-intelligence-data.js +307 -0
- package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
- package/dist/dashboard/dashboard-api-server.js +137 -1
- package/dist/export/claude-commands-export.d.ts +60 -0
- package/dist/export/claude-commands-export.d.ts.map +1 -0
- package/dist/export/claude-commands-export.js +276 -0
- package/dist/export/export-formats.d.ts +1 -1
- package/dist/export/export-formats.d.ts.map +1 -1
- package/dist/export/export-formats.js +139 -12
- package/dist/init/init-templates.d.ts.map +1 -1
- package/dist/init/init-templates.js +133 -113
- package/dist/init/paths-advisory.d.ts +20 -0
- package/dist/init/paths-advisory.d.ts.map +1 -0
- package/dist/init/paths-advisory.js +88 -0
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +137 -46
- package/dist/output/failure-hints.d.ts +1 -9
- package/dist/output/failure-hints.d.ts.map +1 -1
- package/dist/output/failure-hints.js +2 -8
- package/dist/output/watch-loop.d.ts +9 -1
- package/dist/output/watch-loop.d.ts.map +1 -1
- package/dist/output/watch-loop.js +13 -3
- package/dist/schemas/json-schemas.d.ts +36 -36
- package/dist/schemas/json-schemas.js +36 -36
- package/dist/surface/about.d.ts.map +1 -1
- package/dist/surface/about.js +37 -15
- package/dist/surface/no-args-landing.d.ts.map +1 -1
- package/dist/surface/no-args-landing.js +9 -13
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +23 -11
- package/package.json +36 -25
- package/dist/commands/plugin.command.d.ts +0 -11
- package/dist/commands/plugin.command.d.ts.map +0 -1
- package/dist/commands/plugin.command.js +0 -394
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
-
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
return path;
|
|
8
|
-
};
|
|
9
1
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
10
2
|
import * as nodePath from 'node:path';
|
|
11
3
|
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
12
4
|
import { asJson, header, kv } from "../output/format-output.js";
|
|
5
|
+
import { importModuleViaLoader } from '@shrkcrft/core';
|
|
13
6
|
const VALID_KINDS = new Set([
|
|
14
7
|
'generic',
|
|
15
8
|
'framework',
|
|
16
9
|
'architecture',
|
|
17
10
|
'enterprise',
|
|
18
|
-
'platform-adopter',
|
|
19
11
|
]);
|
|
20
12
|
/** Pure: compute the file set to write. No IO. */
|
|
21
13
|
export function planPackScaffold(input) {
|
|
@@ -108,12 +100,6 @@ export function planPackScaffold(input) {
|
|
|
108
100
|
body: renderBoundariesAsset(),
|
|
109
101
|
});
|
|
110
102
|
}
|
|
111
|
-
if (input.kind === 'platform-adopter' || input.withExamples) {
|
|
112
|
-
files.push({
|
|
113
|
-
relativePath: 'src/assets/contracts/plugin-contract.example.ts',
|
|
114
|
-
body: renderPluginContractExample(),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
103
|
if (input.kind === 'enterprise') {
|
|
118
104
|
files.push({
|
|
119
105
|
relativePath: 'docs/review-workflow.md',
|
|
@@ -239,12 +225,6 @@ function renderKnowledgeAsset(input) {
|
|
|
239
225
|
['framework.overview', 'Framework overview', 'High', 'What this framework is for.'],
|
|
240
226
|
]);
|
|
241
227
|
}
|
|
242
|
-
if (input.kind === 'platform-adopter') {
|
|
243
|
-
return knowledgeBody([
|
|
244
|
-
['platform.policy', 'Policy capability', 'Medium', 'Describe the policy/capability model your platform exposes.'],
|
|
245
|
-
['platform.adapter', 'Adapter contract', 'Medium', 'Describe the adapter contract your platform expects.'],
|
|
246
|
-
]);
|
|
247
|
-
}
|
|
248
228
|
return knowledgeBody([
|
|
249
229
|
['pack.overview', 'Pack overview', 'Medium', 'Short overview of what this pack contributes.'],
|
|
250
230
|
]);
|
|
@@ -357,17 +337,6 @@ function renderBoundariesAsset() {
|
|
|
357
337
|
``,
|
|
358
338
|
].join('\n');
|
|
359
339
|
}
|
|
360
|
-
function renderPluginContractExample() {
|
|
361
|
-
return [
|
|
362
|
-
`// Example: an adapter-style plugin contract.`,
|
|
363
|
-
`// Replace with the actual interface your platform expects.`,
|
|
364
|
-
`export interface IPluginCapability {`,
|
|
365
|
-
` id: string;`,
|
|
366
|
-
` invoke(input: unknown): Promise<unknown>;`,
|
|
367
|
-
`}`,
|
|
368
|
-
``,
|
|
369
|
-
].join('\n');
|
|
370
|
-
}
|
|
371
340
|
function renderEnterpriseReviewDocs() {
|
|
372
341
|
return [
|
|
373
342
|
`# Review workflow`,
|
|
@@ -414,11 +383,11 @@ function renderDocsOverview(input, fullName) {
|
|
|
414
383
|
export const packsNewCommand = {
|
|
415
384
|
name: 'new',
|
|
416
385
|
description: 'Scaffold a new SharkCraft pack package (rules / paths / templates / pipelines / presets / boundaries). Dry-run by default — pass --write to materialize. No install, no publish, no overwrite without --force.',
|
|
417
|
-
usage: 'shrk [--cwd <dir>] packs new <name> [--scope @org] [--preset <id>] [--kind generic|framework|architecture|enterprise
|
|
386
|
+
usage: 'shrk [--cwd <dir>] packs new <name> [--scope @org] [--preset <id>] [--kind generic|framework|architecture|enterprise] [--with-examples] [--write] [--force] [--json]',
|
|
418
387
|
async run(args) {
|
|
419
388
|
const name = args.positional[0];
|
|
420
389
|
if (!name) {
|
|
421
|
-
process.stderr.write('Usage: shrk packs new <name> [--scope @org] [--preset <id>] [--kind generic|framework|architecture|enterprise
|
|
390
|
+
process.stderr.write('Usage: shrk packs new <name> [--scope @org] [--preset <id>] [--kind generic|framework|architecture|enterprise] [--with-examples] [--write]\n');
|
|
422
391
|
return 2;
|
|
423
392
|
}
|
|
424
393
|
const cwd = resolveCwd(args);
|
|
@@ -645,7 +614,7 @@ async function runRuntimePackTest(input) {
|
|
|
645
614
|
if (existsSync(entry)) {
|
|
646
615
|
try {
|
|
647
616
|
const { pathToFileURL } = await import('node:url');
|
|
648
|
-
const mod = (await
|
|
617
|
+
const mod = (await importModuleViaLoader(entry));
|
|
649
618
|
const value = mod.default ?? mod;
|
|
650
619
|
const shape = describeShape(value);
|
|
651
620
|
modules.push({
|
|
@@ -692,7 +661,7 @@ async function runRuntimePackTest(input) {
|
|
|
692
661
|
continue;
|
|
693
662
|
try {
|
|
694
663
|
const { pathToFileURL } = await import('node:url');
|
|
695
|
-
const mod = (await
|
|
664
|
+
const mod = (await importModuleViaLoader(full));
|
|
696
665
|
const value = mod.default;
|
|
697
666
|
const arr = Array.isArray(value) ? value : null;
|
|
698
667
|
modules.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packs.command.d.ts","sourceRoot":"","sources":["../../src/commands/packs.command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"packs.command.d.ts","sourceRoot":"","sources":["../../src/commands/packs.command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,yBAAyB,EAAE,eAoCvC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,eAsGzC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,eA+CnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAuD9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAsE7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAqDjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAyFhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAqEhC,CAAC;AA4DF,eAAO,MAAM,gBAAgB,EAAE,eA+K9B,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAmCtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAmFhC,CAAC;AAMF,eAAO,MAAM,qBAAqB,EAAE,eA4BnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,eA+E/B,CAAC"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
-
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
return path;
|
|
8
|
-
};
|
|
9
1
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
10
2
|
import * as nodePath from 'node:path';
|
|
11
|
-
import { pathToFileURL } from 'node:url';
|
|
12
3
|
import { buildPackDoctorReport, buildPackSignatureStatusReport, checkPackSymbolCompat, explainPackSignatureStatus, inspectSharkcraft, mergePackReleaseChecks, runPackReleaseCheck, runPackReleaseChecksForReport, } from '@shrkcrft/inspector';
|
|
13
4
|
import { PACK_SECRET_ENV, signPackManifest, validatePackManifest, verifyPackManifest, } from '@shrkcrft/plugin-api';
|
|
14
5
|
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
15
6
|
import { asJson, header, kv } from "../output/format-output.js";
|
|
7
|
+
import { importModuleViaLoader } from '@shrkcrft/core';
|
|
16
8
|
function statusLabel(valid) {
|
|
17
9
|
return valid ? 'OK ' : 'INVALID';
|
|
18
10
|
}
|
|
@@ -553,7 +545,7 @@ async function loadManifestFromPath(manifestPath) {
|
|
|
553
545
|
if (manifestPath.endsWith('.json')) {
|
|
554
546
|
return JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
555
547
|
}
|
|
556
|
-
const mod = (await
|
|
548
|
+
const mod = (await importModuleViaLoader(manifestPath));
|
|
557
549
|
return (mod.default ?? mod);
|
|
558
550
|
}
|
|
559
551
|
export const packsSignCommand = {
|
|
@@ -773,17 +765,11 @@ export const packsCompatCommand = {
|
|
|
773
765
|
: nodePath.resolve(cwd, consumerRootRaw)
|
|
774
766
|
: null;
|
|
775
767
|
const distAware = flagBool(args, 'dist-aware');
|
|
776
|
-
const fastMode = flagBool(args, 'fast');
|
|
777
768
|
// Run a release-check first; surfaces helper-missing diagnostics.
|
|
778
769
|
const release = await runPackReleaseCheck(abs);
|
|
779
770
|
const helperMissing = release.findings.filter((f) => f.code === 'contribution-helper-missing');
|
|
780
771
|
// Symbol-level diff against the consumer's installed plugin-api.
|
|
781
|
-
const symbol = checkPackSymbolCompat({
|
|
782
|
-
packPath: abs,
|
|
783
|
-
consumerRoot,
|
|
784
|
-
distAware,
|
|
785
|
-
mode: fastMode ? 'fast' : 'ts',
|
|
786
|
-
});
|
|
772
|
+
const symbol = checkPackSymbolCompat({ packPath: abs, consumerRoot, distAware });
|
|
787
773
|
const passed = helperMissing.length === 0 && symbol.compatible;
|
|
788
774
|
if (flagBool(args, 'json')) {
|
|
789
775
|
process.stdout.write(asJson({
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ICommandHandler } from '../command-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* `shrk plan-context` — produce a deterministic, token-budgeted context
|
|
4
|
+
* pack for an AI coding agent. Reads the code graph + (optionally) the
|
|
5
|
+
* rule-graph bridge.
|
|
6
|
+
*
|
|
7
|
+
* Read-only. The pack is whatever the planner decides; the agent uses
|
|
8
|
+
* it as the starting point for its conversation.
|
|
9
|
+
*/
|
|
10
|
+
export declare const planContextCommand: ICommandHandler;
|
|
11
|
+
//# sourceMappingURL=plan-context.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-context.command.d.ts","sourceRoot":"","sources":["../../src/commands/plan-context.command.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,eA2DhC,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { planContext } from '@shrkcrft/context-planner';
|
|
2
|
+
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
3
|
+
import { asJson, header, kv } from "../output/format-output.js";
|
|
4
|
+
/**
|
|
5
|
+
* `shrk plan-context` — produce a deterministic, token-budgeted context
|
|
6
|
+
* pack for an AI coding agent. Reads the code graph + (optionally) the
|
|
7
|
+
* rule-graph bridge.
|
|
8
|
+
*
|
|
9
|
+
* Read-only. The pack is whatever the planner decides; the agent uses
|
|
10
|
+
* it as the starting point for its conversation.
|
|
11
|
+
*/
|
|
12
|
+
export const planContextCommand = {
|
|
13
|
+
name: 'plan-context',
|
|
14
|
+
description: 'Produce a deterministic, token-budgeted context pack (`sharkcraft.context-pack/v1`) for an AI agent: ranked files, applicable rules, likely tests, surfaced risks, do-not-touch zones.',
|
|
15
|
+
usage: 'shrk plan-context "<task>" [--budget N] [--max-files N] [--hint-file <path>] [--hint-package <prefix>] [--json]',
|
|
16
|
+
async run(args) {
|
|
17
|
+
const cwd = resolveCwd(args);
|
|
18
|
+
const wantJson = flagBool(args, 'json');
|
|
19
|
+
const task = args.positional[0];
|
|
20
|
+
if (!task) {
|
|
21
|
+
process.stderr.write(this.usage + '\n');
|
|
22
|
+
return 2;
|
|
23
|
+
}
|
|
24
|
+
const budget = Number(flagString(args, 'budget') ?? '8000');
|
|
25
|
+
const maxFiles = Number(flagString(args, 'max-files') ?? '30');
|
|
26
|
+
const hintedFiles = collectMulti(args, 'hint-file');
|
|
27
|
+
const hintedPackages = collectMulti(args, 'hint-package');
|
|
28
|
+
const pack = planContext({
|
|
29
|
+
projectRoot: cwd,
|
|
30
|
+
task,
|
|
31
|
+
budgetTokens: budget,
|
|
32
|
+
maxFiles,
|
|
33
|
+
...(hintedFiles.length > 0 ? { hintedFiles } : {}),
|
|
34
|
+
...(hintedPackages.length > 0 ? { hintedPackages } : {}),
|
|
35
|
+
});
|
|
36
|
+
if (wantJson) {
|
|
37
|
+
process.stdout.write(asJson(pack) + '\n');
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
process.stdout.write(header(`Context pack: ${task}`));
|
|
41
|
+
process.stdout.write(kv('intent', pack.intent) + '\n');
|
|
42
|
+
process.stdout.write(kv('files', String(pack.files.length)) + '\n');
|
|
43
|
+
process.stdout.write(kv('rules', String(pack.rules.length)) + '\n');
|
|
44
|
+
process.stdout.write(kv('paths', String(pack.paths.length)) + '\n');
|
|
45
|
+
process.stdout.write(kv('templates', String(pack.templates.length)) + '\n');
|
|
46
|
+
process.stdout.write(kv('tests', String(pack.tests.length)) + '\n');
|
|
47
|
+
process.stdout.write(kv('risks', String(pack.risks.length)) + '\n');
|
|
48
|
+
process.stdout.write(kv('budget', `${pack.budget.used}/${pack.budget.requested} tokens` + (pack.budget.truncated ? ' (truncated)' : '')) + '\n');
|
|
49
|
+
if (pack.files.length > 0) {
|
|
50
|
+
process.stdout.write('\nTop files:\n');
|
|
51
|
+
for (const f of pack.files.slice(0, 15)) {
|
|
52
|
+
const reason = f.reasons[0] ? ` [${f.reasons[0]}]` : '';
|
|
53
|
+
process.stdout.write(` ${f.score.toFixed(2)} ${f.path}${reason}\n`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (pack.tests.length > 0) {
|
|
57
|
+
process.stdout.write('\nLikely tests:\n');
|
|
58
|
+
for (const t of pack.tests.slice(0, 5))
|
|
59
|
+
process.stdout.write(` ${t}\n`);
|
|
60
|
+
}
|
|
61
|
+
if (pack.risks.length > 0) {
|
|
62
|
+
process.stdout.write('\nRisks:\n');
|
|
63
|
+
for (const r of pack.risks)
|
|
64
|
+
process.stdout.write(` • [${r.kind}] ${r.label}\n`);
|
|
65
|
+
}
|
|
66
|
+
for (const d of pack.diagnostics.slice(0, 5))
|
|
67
|
+
process.stdout.write(`! ${d}\n`);
|
|
68
|
+
return 0;
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
function collectMulti(args, name) {
|
|
72
|
+
const list = args.multiFlags.get(name);
|
|
73
|
+
if (list)
|
|
74
|
+
return [...list];
|
|
75
|
+
const single = flagString(args, name);
|
|
76
|
+
return single ? [single] : [];
|
|
77
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `shrk profiles ...` — unified read-only surface for all pack-/local-
|
|
3
|
-
* contributed profiles (
|
|
3
|
+
* contributed profiles (migration, and future kinds).
|
|
4
4
|
*/
|
|
5
5
|
import { findProfile, inspectSharkcraft, listProfileIssues, listProfiles, ProfileKind, } from '@shrkcrft/inspector';
|
|
6
6
|
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
@@ -15,7 +15,7 @@ function parseKind(value) {
|
|
|
15
15
|
}
|
|
16
16
|
export const profilesListCommand = {
|
|
17
17
|
name: 'list',
|
|
18
|
-
description: 'List all registered profiles (
|
|
18
|
+
description: 'List all registered profiles (migration, ...).',
|
|
19
19
|
usage: 'shrk profiles list [--kind <kind>] [--json]',
|
|
20
20
|
async run(args) {
|
|
21
21
|
const cwd = resolveCwd(args);
|
|
@@ -28,7 +28,7 @@ export const profilesListCommand = {
|
|
|
28
28
|
}
|
|
29
29
|
process.stdout.write(header(`Profiles (${entries.length}${kind ? `, kind=${kind}` : ''})`));
|
|
30
30
|
if (entries.length === 0) {
|
|
31
|
-
process.stdout.write(' (none — contribute via packs:
|
|
31
|
+
process.stdout.write(' (none — contribute via packs: migrationProfileFiles, etc.)\n');
|
|
32
32
|
return 0;
|
|
33
33
|
}
|
|
34
34
|
for (const e of entries) {
|
|
@@ -132,7 +132,7 @@ export const profilesSearchCommand = {
|
|
|
132
132
|
};
|
|
133
133
|
export const profilesCommand = {
|
|
134
134
|
name: 'profiles',
|
|
135
|
-
description: 'List / inspect pack-contributed profiles (
|
|
135
|
+
description: 'List / inspect pack-contributed profiles (migration, conventions, …).',
|
|
136
136
|
usage: 'shrk profiles list|get|doctor|search ...',
|
|
137
137
|
async run(args) {
|
|
138
138
|
const sub = args.positional[0];
|
|
@@ -204,8 +204,8 @@ function resolveSmokeFlags(args) {
|
|
|
204
204
|
const noAssertions = flagBool(args, 'no-assertions');
|
|
205
205
|
return { assertionsEnabled: !noAssertions };
|
|
206
206
|
}
|
|
207
|
-
// Generic
|
|
208
|
-
const BUILTIN_TARGET_IDS = ['sharkcraft', 'dogfood', 'synthetic', '
|
|
207
|
+
// Generic consumer target replaces the previous hardcoded project target.
|
|
208
|
+
const BUILTIN_TARGET_IDS = ['sharkcraft', 'dogfood', 'synthetic', 'consumer'];
|
|
209
209
|
function resolveTargets(cwd, args, requested) {
|
|
210
210
|
const want = (id) => requested.length === 0 || requested.includes(id);
|
|
211
211
|
const out = [];
|
|
@@ -224,19 +224,19 @@ function resolveTargets(cwd, args, requested) {
|
|
|
224
224
|
writeFileSync(nodePath.join(root, 'package.json'), JSON.stringify({ name: 'sharkcraft-synth', version: '0.0.0', type: 'module' }, null, 2), 'utf8');
|
|
225
225
|
out.push({ id: 'synthetic', cwd: root, label: 'synthetic-fixture' });
|
|
226
226
|
}
|
|
227
|
-
if (want('
|
|
228
|
-
const
|
|
229
|
-
process.env['
|
|
227
|
+
if (want('consumer')) {
|
|
228
|
+
const consumerRoot = flagString(args, 'consumer-root') ??
|
|
229
|
+
process.env['SHARKCRAFT_CONSUMER_ROOT'] ??
|
|
230
230
|
'';
|
|
231
|
-
if (
|
|
232
|
-
out.push({ id: '
|
|
231
|
+
if (consumerRoot && existsSync(consumerRoot)) {
|
|
232
|
+
out.push({ id: 'consumer', cwd: consumerRoot, label: `consumer:${consumerRoot}` });
|
|
233
233
|
}
|
|
234
234
|
else {
|
|
235
235
|
out.push({
|
|
236
|
-
id: '
|
|
237
|
-
cwd:
|
|
238
|
-
label: '
|
|
239
|
-
warning: '
|
|
236
|
+
id: 'consumer',
|
|
237
|
+
cwd: consumerRoot || '(unset)',
|
|
238
|
+
label: 'consumer target',
|
|
239
|
+
warning: 'Consumer root not set (pass --consumer-root or set SHARKCRAFT_CONSUMER_ROOT) — skipped.',
|
|
240
240
|
});
|
|
241
241
|
}
|
|
242
242
|
}
|
|
@@ -292,7 +292,7 @@ async function runReleaseSmoke(args) {
|
|
|
292
292
|
* examples/dogfood-target as the fixture.
|
|
293
293
|
* - `synthetic` runs the scenarios that don't depend on a prepared source
|
|
294
294
|
* (unconfigured-repo + pack-authoring).
|
|
295
|
-
* - `
|
|
295
|
+
* - `consumer` runs the read-only scenarios that don't write outside the
|
|
296
296
|
* fixture (e.g. an external project that consumes a SharkCraft pack).
|
|
297
297
|
*/
|
|
298
298
|
function isScenarioApplicableTo(scenario, target) {
|
|
@@ -304,7 +304,7 @@ function isScenarioApplicableTo(scenario, target) {
|
|
|
304
304
|
if (target.id === 'dogfood') {
|
|
305
305
|
return scenario === 'dev-workflow' || scenario === 'pr-review' || scenario === 'governance';
|
|
306
306
|
}
|
|
307
|
-
if (target.id === '
|
|
307
|
+
if (target.id === 'consumer') {
|
|
308
308
|
return scenario === 'unconfigured-repo' || scenario === 'pack-authoring' || scenario === 'governance';
|
|
309
309
|
}
|
|
310
310
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.command.d.ts","sourceRoot":"","sources":["../../src/commands/review.command.ts"],"names":[],"mappings":"AAgBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA6GhC,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"review.command.d.ts","sourceRoot":"","sources":["../../src/commands/review.command.ts"],"names":[],"mappings":"AAgBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA6GhC,eAAO,MAAM,aAAa,EAAE,eA+E3B,CAAC"}
|
|
@@ -95,21 +95,8 @@ export const reviewCommand = {
|
|
|
95
95
|
if (args.positional[0] === 'packet') {
|
|
96
96
|
return runPacket(args);
|
|
97
97
|
}
|
|
98
|
-
const
|
|
99
|
-
const inspection = await inspectSharkcraft({ cwd });
|
|
98
|
+
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
100
99
|
const since = flagString(args, 'since');
|
|
101
|
-
if (since) {
|
|
102
|
-
const { verifyGitRef } = await import('@shrkcrft/inspector');
|
|
103
|
-
const verify = verifyGitRef(cwd, since);
|
|
104
|
-
if (!verify.valid) {
|
|
105
|
-
process.stderr.write(`error: --since ref "${since}" does not resolve to a commit in this repository.\n` +
|
|
106
|
-
(verify.suggestions && verify.suggestions.length > 0
|
|
107
|
-
? `\nDid you mean:\n${verify.suggestions.map((s) => ` --since ${s}`).join('\n')}\n`
|
|
108
|
-
: '') +
|
|
109
|
-
'\nUse `git branch -a` to list available refs.\n');
|
|
110
|
-
return 2;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
100
|
const files = flagList(args, 'files');
|
|
114
101
|
const packet = buildReviewPacket(inspection, {
|
|
115
102
|
...(since ? { since } : {}),
|
|
@@ -308,21 +295,8 @@ function isReviewPacketV3Shape(v) {
|
|
|
308
295
|
return v.schema === REVIEW_PACKET_V3_SCHEMA;
|
|
309
296
|
}
|
|
310
297
|
async function runPacket(args) {
|
|
311
|
-
const
|
|
312
|
-
const inspection = await inspectSharkcraft({ cwd });
|
|
298
|
+
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
313
299
|
const since = flagString(args, 'since');
|
|
314
|
-
if (since) {
|
|
315
|
-
const { verifyGitRef } = await import('@shrkcrft/inspector');
|
|
316
|
-
const verify = verifyGitRef(cwd, since);
|
|
317
|
-
if (!verify.valid) {
|
|
318
|
-
process.stderr.write(`error: --since ref "${since}" does not resolve to a commit in this repository.\n` +
|
|
319
|
-
(verify.suggestions && verify.suggestions.length > 0
|
|
320
|
-
? `\nDid you mean:\n${verify.suggestions.map((s) => ` --since ${s}`).join('\n')}\n`
|
|
321
|
-
: '') +
|
|
322
|
-
'\nUse `git branch -a` to list available refs.\n');
|
|
323
|
-
return 2;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
300
|
const files = flagList(args, 'files');
|
|
327
301
|
const v2 = flagBool(args, 'v2');
|
|
328
302
|
const baselineFile = flagString(args, 'quality-baseline');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-graph-subverbs.d.ts","sourceRoot":"","sources":["../../src/commands/rule-graph-subverbs.ts"],"names":[],"mappings":"AAQA,OAAO,EAAwB,KAAK,eAAe,EAAmB,MAAM,wBAAwB,CAAC;AAGrG,eAAO,MAAM,gBAAgB,EAAE,eAc9B,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subverbs for `@shrkcrft/rule-graph`.
|
|
3
|
+
*
|
|
4
|
+
* Sub-namespace: `shrk rule-graph <verb>`. Lives in its own command
|
|
5
|
+
* because the verbs operate on a separate `.sharkcraft/bridge/` store
|
|
6
|
+
* and don't conceptually belong under `shrk graph`.
|
|
7
|
+
*/
|
|
8
|
+
import { buildBridge, RuleGraphQueryApi } from '@shrkcrft/rule-graph';
|
|
9
|
+
import { flagBool, resolveCwd } from "../command-registry.js";
|
|
10
|
+
import { asJson, header, kv } from "../output/format-output.js";
|
|
11
|
+
export const ruleGraphCommand = {
|
|
12
|
+
name: 'rule-graph',
|
|
13
|
+
description: 'Bridge the SharkCraft code graph to asset registries (boundary rules, path conventions, templates). Sub-verbs: index, status, for <file>.',
|
|
14
|
+
usage: 'shrk rule-graph index [--json] | shrk rule-graph status [--json] | shrk rule-graph for <file> [--json]',
|
|
15
|
+
async run(args) {
|
|
16
|
+
const sub = args.positional[0];
|
|
17
|
+
if (sub === 'index')
|
|
18
|
+
return runIndex(args);
|
|
19
|
+
if (sub === 'status')
|
|
20
|
+
return runStatus(args);
|
|
21
|
+
if (sub === 'for')
|
|
22
|
+
return runFor(args);
|
|
23
|
+
process.stderr.write(this.usage + '\n');
|
|
24
|
+
return 2;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
async function runIndex(args) {
|
|
28
|
+
const cwd = resolveCwd(args);
|
|
29
|
+
const wantJson = flagBool(args, 'json');
|
|
30
|
+
const r = await buildBridge({ projectRoot: cwd });
|
|
31
|
+
if (wantJson) {
|
|
32
|
+
process.stdout.write(asJson({ ok: true, manifest: r.manifest, durationMs: r.durationMs }) + '\n');
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
process.stdout.write(header('Rule-graph bridge'));
|
|
36
|
+
process.stdout.write(kv('schema', r.manifest.schema) + '\n');
|
|
37
|
+
process.stdout.write(kv('bridge edges', String(sumValues(r.manifest.edgesByKind))) + '\n');
|
|
38
|
+
process.stdout.write(kv('rules → files', String(r.manifest.sourceCounts['rule'] ?? 0)) + '\n');
|
|
39
|
+
process.stdout.write(kv('paths → files', String(r.manifest.sourceCounts['path'] ?? 0)) + '\n');
|
|
40
|
+
process.stdout.write(kv('templates → files', String(r.manifest.sourceCounts['template'] ?? 0)) + '\n');
|
|
41
|
+
process.stdout.write(kv('duration', `${r.durationMs}ms`) + '\n');
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
async function runStatus(args) {
|
|
45
|
+
const cwd = resolveCwd(args);
|
|
46
|
+
const wantJson = flagBool(args, 'json');
|
|
47
|
+
const missing = RuleGraphQueryApi.missingDescription(cwd);
|
|
48
|
+
if (missing) {
|
|
49
|
+
if (wantJson) {
|
|
50
|
+
process.stdout.write(asJson({ ok: false, state: 'missing', message: missing, nextCommand: 'shrk rule-graph index' }) + '\n');
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
process.stderr.write(missing + '\n');
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
const api = RuleGraphQueryApi.fromStores(cwd);
|
|
57
|
+
// No public counters from the API itself — just confirm it loads.
|
|
58
|
+
if (wantJson) {
|
|
59
|
+
process.stdout.write(asJson({ ok: true, state: 'fresh' }) + '\n');
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
process.stdout.write(header('Rule-graph status'));
|
|
63
|
+
process.stdout.write(kv('state', 'fresh') + '\n');
|
|
64
|
+
void api;
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
async function runFor(args) {
|
|
68
|
+
const cwd = resolveCwd(args);
|
|
69
|
+
const wantJson = flagBool(args, 'json');
|
|
70
|
+
const file = args.positional[1];
|
|
71
|
+
if (!file) {
|
|
72
|
+
process.stderr.write('Usage: shrk rule-graph for <file>\n');
|
|
73
|
+
return 2;
|
|
74
|
+
}
|
|
75
|
+
const missing = RuleGraphQueryApi.missingDescription(cwd);
|
|
76
|
+
if (missing) {
|
|
77
|
+
if (wantJson) {
|
|
78
|
+
process.stdout.write(asJson({ ok: false, message: missing, nextCommand: 'shrk rule-graph index' }) + '\n');
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
process.stderr.write(missing + '\n');
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
const api = RuleGraphQueryApi.fromStores(cwd);
|
|
85
|
+
const r = api.forFile(file);
|
|
86
|
+
if (!r) {
|
|
87
|
+
const payload = { ok: false, error: 'not-found', file };
|
|
88
|
+
if (wantJson) {
|
|
89
|
+
process.stdout.write(asJson(payload) + '\n');
|
|
90
|
+
return 1;
|
|
91
|
+
}
|
|
92
|
+
process.stderr.write(`No file node for "${file}".\n`);
|
|
93
|
+
return 1;
|
|
94
|
+
}
|
|
95
|
+
const payload = {
|
|
96
|
+
schema: 'sharkcraft.rule-graph-for-file/v1',
|
|
97
|
+
file: r.path,
|
|
98
|
+
rules: r.rules.map((h) => ({ id: h.target.id, label: h.target.label, severity: h.edge.data?.['severity'] ?? undefined })),
|
|
99
|
+
paths: r.paths.map((h) => ({ id: h.target.id, label: h.target.label })),
|
|
100
|
+
templates: r.templates.map((h) => ({ id: h.target.id, label: h.target.label })),
|
|
101
|
+
};
|
|
102
|
+
if (wantJson) {
|
|
103
|
+
process.stdout.write(asJson(payload) + '\n');
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
process.stdout.write(header(`Rule-graph for: ${r.path}`));
|
|
107
|
+
if (payload.rules.length > 0) {
|
|
108
|
+
process.stdout.write('\nRules (boundary):\n');
|
|
109
|
+
for (const h of payload.rules)
|
|
110
|
+
process.stdout.write(` ${h.id} — ${h.label}${h.severity ? ' [' + h.severity + ']' : ''}\n`);
|
|
111
|
+
}
|
|
112
|
+
if (payload.paths.length > 0) {
|
|
113
|
+
process.stdout.write('\nPath conventions:\n');
|
|
114
|
+
for (const h of payload.paths)
|
|
115
|
+
process.stdout.write(` ${h.id} — ${h.label}\n`);
|
|
116
|
+
}
|
|
117
|
+
if (payload.templates.length > 0) {
|
|
118
|
+
process.stdout.write('\nTemplates:\n');
|
|
119
|
+
for (const h of payload.templates)
|
|
120
|
+
process.stdout.write(` ${h.id} — ${h.label}\n`);
|
|
121
|
+
}
|
|
122
|
+
if (payload.rules.length === 0 && payload.paths.length === 0 && payload.templates.length === 0) {
|
|
123
|
+
process.stdout.write(' (no bridge edges for this file)\n');
|
|
124
|
+
}
|
|
125
|
+
return 0;
|
|
126
|
+
}
|
|
127
|
+
function sumValues(record) {
|
|
128
|
+
let n = 0;
|
|
129
|
+
for (const v of Object.values(record))
|
|
130
|
+
n += v;
|
|
131
|
+
return n;
|
|
132
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ICommandHandler } from '../command-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* `shrk search structural` — declarative AST pattern matching with
|
|
4
|
+
* optional rewrite mode (Wave 8). Patterns are JSON (no executable
|
|
5
|
+
* predicates) — either inline via --pattern or from a file via
|
|
6
|
+
* --pattern-file.
|
|
7
|
+
*
|
|
8
|
+
* Rewrite flow:
|
|
9
|
+
* 1. Pass `--rewrite '<json>'` (a `RewriteRecipe`) to compute a
|
|
10
|
+
* rewrite plan.
|
|
11
|
+
* 2. Preview is shown by default (no fs writes).
|
|
12
|
+
* 3. Pass `--apply` to actually write the changes.
|
|
13
|
+
*
|
|
14
|
+
* The plan can be inspected as JSON via `--json` and replayed via
|
|
15
|
+
* `--plan-in <path>` (write the plan with `--plan-out <path>` first).
|
|
16
|
+
*/
|
|
17
|
+
export declare const searchStructuralCommand: ICommandHandler;
|
|
18
|
+
//# sourceMappingURL=search-structural.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-structural.command.d.ts","sourceRoot":"","sources":["../../src/commands/search-structural.command.ts"],"names":[],"mappings":"AAgBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,EAAE,eAkErC,CAAC"}
|