@shrkcrft/cli 0.1.0-alpha.27 → 0.1.0-alpha.28

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.
Files changed (36) hide show
  1. package/dist/commands/baseline.command.d.ts +8 -0
  2. package/dist/commands/baseline.command.d.ts.map +1 -0
  3. package/dist/commands/baseline.command.js +511 -0
  4. package/dist/commands/changelog-data.d.ts.map +1 -1
  5. package/dist/commands/changelog-data.js +22 -0
  6. package/dist/commands/check.command.d.ts.map +1 -1
  7. package/dist/commands/check.command.js +28 -1
  8. package/dist/commands/command-catalog.d.ts.map +1 -1
  9. package/dist/commands/command-catalog.js +112 -0
  10. package/dist/commands/gates.command.d.ts +6 -0
  11. package/dist/commands/gates.command.d.ts.map +1 -0
  12. package/dist/commands/gates.command.js +334 -0
  13. package/dist/commands/generated.command.d.ts +6 -0
  14. package/dist/commands/generated.command.d.ts.map +1 -0
  15. package/dist/commands/generated.command.js +514 -0
  16. package/dist/commands/ingest.command.d.ts +11 -0
  17. package/dist/commands/ingest.command.d.ts.map +1 -1
  18. package/dist/commands/ingest.command.js +49 -23
  19. package/dist/commands/policy-lint.command.d.ts +37 -0
  20. package/dist/commands/policy-lint.command.d.ts.map +1 -1
  21. package/dist/commands/policy-lint.command.js +119 -2
  22. package/dist/commands/registry.command.d.ts.map +1 -1
  23. package/dist/commands/registry.command.js +36 -4
  24. package/dist/commands/wiring.command.d.ts.map +1 -1
  25. package/dist/commands/wiring.command.js +25 -0
  26. package/dist/finish/run-finish.d.ts.map +1 -1
  27. package/dist/finish/run-finish.js +9 -3
  28. package/dist/gates/gate-rule-view.d.ts +35 -0
  29. package/dist/gates/gate-rule-view.d.ts.map +1 -0
  30. package/dist/gates/gate-rule-view.js +80 -0
  31. package/dist/gates/rule-coverage.d.ts +53 -0
  32. package/dist/gates/rule-coverage.d.ts.map +1 -0
  33. package/dist/gates/rule-coverage.js +165 -0
  34. package/dist/main.d.ts.map +1 -1
  35. package/dist/main.js +25 -2
  36. package/package.json +33 -33
@@ -0,0 +1,165 @@
1
+ import { inspectSource, runPolicyLint, scanGeneratedFiles, wiringSourceSide, } from '@shrkcrft/boundaries';
2
+ export const GATE_COVERAGE_SCHEMA = 'sharkcraft.gate-coverage/v1';
3
+ /** Evaluate the author's declared expectations against what the rule extracted. */
4
+ function checkExpectations(selfTest, ids, unitsMatched) {
5
+ if (!selfTest)
6
+ return [];
7
+ const out = [];
8
+ if (selfTest.expectMatchesAtLeast !== undefined &&
9
+ unitsMatched < selfTest.expectMatchesAtLeast) {
10
+ out.push(`expected at least ${selfTest.expectMatchesAtLeast} match(es), got ${unitsMatched}`);
11
+ }
12
+ const present = new Set(ids);
13
+ for (const id of selfTest.expectIds ?? []) {
14
+ if (!present.has(id))
15
+ out.push(`expected id "${id}" was NOT extracted`);
16
+ }
17
+ for (const id of selfTest.expectNotIds ?? []) {
18
+ if (present.has(id))
19
+ out.push(`id "${id}" was extracted but is listed in expectNotIds`);
20
+ }
21
+ return out;
22
+ }
23
+ function matchWiring(cwd, rule, excludeDirs) {
24
+ const side = wiringSourceSide(rule);
25
+ if (!side)
26
+ return { filesMatched: 0, unitsMatched: 0, unitLabel: 'ids', ids: [], error: 'rule sets no source side' };
27
+ const insp = inspectSource(cwd, side, excludeDirs);
28
+ return {
29
+ filesMatched: insp.filesScanned,
30
+ unitsMatched: insp.ids.length,
31
+ unitLabel: 'ids',
32
+ ids: insp.ids,
33
+ ...(insp.error ? { error: insp.error } : {}),
34
+ };
35
+ }
36
+ function matchPolicy(cwd, rule, excludeDirs) {
37
+ const report = runPolicyLint(cwd, [rule], { excludeDirs });
38
+ const result = report.rules[0];
39
+ return {
40
+ // A policy rule's "files" and "units" differ only for inline templates.
41
+ filesMatched: result?.unitsScanned ?? 0,
42
+ unitsMatched: result?.unitsScanned ?? 0,
43
+ unitLabel: 'content units',
44
+ ids: [],
45
+ ...(result?.error ? { error: result.error } : {}),
46
+ };
47
+ }
48
+ function matchRegistry(cwd, decl, excludeDirs) {
49
+ const insp = inspectSource(cwd, decl.source, excludeDirs);
50
+ return {
51
+ filesMatched: insp.filesScanned,
52
+ unitsMatched: insp.ids.length,
53
+ unitLabel: 'ids',
54
+ ids: insp.ids,
55
+ ...(insp.error ? { error: insp.error } : {}),
56
+ };
57
+ }
58
+ function matchRegistration(cwd, idiom, excludeDirs) {
59
+ const insp = inspectSource(cwd, idiom.declared, excludeDirs);
60
+ return {
61
+ filesMatched: insp.filesScanned,
62
+ unitsMatched: insp.ids.length,
63
+ unitLabel: 'declared tokens',
64
+ ids: insp.ids,
65
+ ...(insp.error ? { error: insp.error } : {}),
66
+ };
67
+ }
68
+ function matchBaseline(cwd, rule, excludeDirs) {
69
+ // Only the EXTRACTOR half can be inspected without spawning. A command
70
+ // compute is reported honestly as un-inspectable rather than guessed at —
71
+ // `shrk baseline explain --id X` runs it on purpose.
72
+ if (rule.compute.kind !== 'extractor' || !rule.compute.source) {
73
+ return {
74
+ filesMatched: 0,
75
+ unitsMatched: 0,
76
+ unitLabel: 'entries (command compute — not inspected)',
77
+ ids: [],
78
+ };
79
+ }
80
+ const insp = inspectSource(cwd, rule.compute.source, excludeDirs);
81
+ return {
82
+ filesMatched: insp.filesScanned,
83
+ unitsMatched: insp.ids.length,
84
+ unitLabel: 'entries',
85
+ ids: insp.ids,
86
+ ...(insp.error ? { error: insp.error } : {}),
87
+ };
88
+ }
89
+ function matchGenerated(cwd, rule, excludeDirs) {
90
+ const scan = scanGeneratedFiles(cwd, rule, excludeDirs);
91
+ const files = [...scan.generated.keys()];
92
+ return {
93
+ filesMatched: files.length,
94
+ unitsMatched: files.length,
95
+ unitLabel: 'generated files',
96
+ ids: files,
97
+ };
98
+ }
99
+ /**
100
+ * Resolve every declared rule against the live tree and report what it matched.
101
+ *
102
+ * The `command`-compute baseline is the one rule kind that cannot be inspected
103
+ * without side effects; it is reported as un-inspected (never as `empty`), so
104
+ * the report never claims a fact it did not check.
105
+ */
106
+ export function buildGateCoverage(cwd, rules, excludeDirs = []) {
107
+ const out = [];
108
+ for (const view of rules) {
109
+ let match;
110
+ switch (view.plane) {
111
+ case 'wiring':
112
+ match = matchWiring(cwd, view.raw, excludeDirs);
113
+ break;
114
+ case 'policy':
115
+ match = matchPolicy(cwd, view.raw, excludeDirs);
116
+ break;
117
+ case 'registry':
118
+ match = matchRegistry(cwd, view.raw, excludeDirs);
119
+ break;
120
+ case 'registration':
121
+ match = matchRegistration(cwd, view.raw, excludeDirs);
122
+ break;
123
+ case 'baseline':
124
+ match = matchBaseline(cwd, view.raw, excludeDirs);
125
+ break;
126
+ default:
127
+ match = matchGenerated(cwd, view.raw, excludeDirs);
128
+ break;
129
+ }
130
+ const expectationFailures = checkExpectations(view.selfTest, match.ids, match.unitsMatched);
131
+ const uninspected = match.unitLabel.includes('not inspected');
132
+ const status = match.error !== undefined
133
+ ? 'error'
134
+ : expectationFailures.length > 0
135
+ ? 'failed-expectation'
136
+ : match.unitsMatched === 0 && !uninspected
137
+ ? 'empty'
138
+ : 'ok';
139
+ out.push({
140
+ id: view.id,
141
+ plane: view.plane,
142
+ ...(view.description ? { description: view.description } : {}),
143
+ status,
144
+ filesMatched: match.filesMatched,
145
+ unitsMatched: match.unitsMatched,
146
+ unitLabel: match.unitLabel,
147
+ sampleIds: match.ids.slice(0, 5),
148
+ failOnEmpty: view.failOnEmpty,
149
+ ...(match.error ? { error: match.error } : {}),
150
+ expectationFailures,
151
+ });
152
+ }
153
+ const empty = out.filter((r) => r.status === 'empty').length;
154
+ const errored = out.filter((r) => r.status === 'error').length;
155
+ const expectationFailures = out.filter((r) => r.status === 'failed-expectation').length;
156
+ return {
157
+ schema: GATE_COVERAGE_SCHEMA,
158
+ rules: out,
159
+ total: out.length,
160
+ empty,
161
+ errored,
162
+ expectationFailures,
163
+ verdict: empty + errored + expectationFailures > 0 ? 'stale' : 'pass',
164
+ };
165
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,eAAe,EAMhB,MAAM,uBAAuB,CAAC;AA8X/B,wBAAgB,aAAa,IAAI,eAAe,CAiY/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CrE;AAwID;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAoDxE"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,eAAe,EAMhB,MAAM,uBAAuB,CAAC;AAoZ/B,wBAAgB,aAAa,IAAI,eAAe,CAqZ/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CrE;AAwID;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAoDxE"}
package/dist/main.js CHANGED
@@ -34,7 +34,10 @@ import { archCommand } from "./commands/arch.command.js";
34
34
  import { frameworkCommand } from "./commands/framework.command.js";
35
35
  import { apiDiffCommand } from "./commands/api-diff.command.js";
36
36
  import { gateCommand } from "./commands/gate.command.js";
37
- import { policyLintCommand } from "./commands/policy-lint.command.js";
37
+ import { policyLintCommand, policyLintExplainCommand } from "./commands/policy-lint.command.js";
38
+ import { baselineCheckCommand, baselineCommand, baselineDiffCommand, baselineExplainCommand, baselineListCommand, baselineUpdateCommand, } from "./commands/baseline.command.js";
39
+ import { generatedCheckCommand, generatedExplainCommand, generatedListCommand, generatedUpdateCommand, } from "./commands/generated.command.js";
40
+ import { gatesCommand, gatesCoverageCommand, gatesExplainCommand, gatesListCommand, } from "./commands/gates.command.js";
38
41
  import { wiringCommand } from "./commands/wiring.command.js";
39
42
  import { reuseCommand } from "./commands/reuse.command.js";
40
43
  import { migrateCommand } from "./commands/migrate.command.js";
@@ -44,7 +47,7 @@ import { compressCommand, expandCommand } from "./commands/compress.command.js";
44
47
  import { alignCommand, unalignCommand } from "./commands/cache-align.command.js";
45
48
  import { reviewCommand } from "./commands/review.command.js";
46
49
  import { onboardCommand } from "./commands/onboard.command.js";
47
- import { contradictionsCommand, generatedCommand, ingestCommand, } from "./commands/ingest.command.js";
50
+ import { contradictionsCommand, generatedCommand, generatedProtectCommand, generatedReportCommand, ingestCommand, } from "./commands/ingest.command.js";
48
51
  import { contextBuildCommand, contextRefreshCommand, contextStatusCommand, understandTaskCommand, validateChangeCommand, } from "./commands/task-context.command.js";
49
52
  import { testCommand } from "./commands/test.command.js";
50
53
  import { planParentCommand, planReviewCommand } from "./commands/plan.command.js";
@@ -206,6 +209,26 @@ export function buildRegistry() {
206
209
  registry.register(apiDiffCommand);
207
210
  registry.register(gateCommand);
208
211
  registry.register(policyLintCommand);
212
+ registry.registerSubcommand('policy-lint', policyLintExplainCommand);
213
+ // The two shell-executing planes (baseline/generated) + the trust layer.
214
+ registry.register(baselineCommand);
215
+ registry.registerSubcommand('baseline', baselineListCommand);
216
+ registry.registerSubcommand('baseline', baselineCheckCommand);
217
+ registry.registerSubcommand('baseline', baselineDiffCommand);
218
+ registry.registerSubcommand('baseline', baselineUpdateCommand);
219
+ registry.registerSubcommand('baseline', baselineExplainCommand);
220
+ // `generated` already exists as the generated-code CLASSIFIER (report /
221
+ // protect). These add the drift GATE under the same noun.
222
+ registry.registerSubcommand('generated', generatedReportCommand);
223
+ registry.registerSubcommand('generated', generatedProtectCommand);
224
+ registry.registerSubcommand('generated', generatedListCommand);
225
+ registry.registerSubcommand('generated', generatedCheckCommand);
226
+ registry.registerSubcommand('generated', generatedUpdateCommand);
227
+ registry.registerSubcommand('generated', generatedExplainCommand);
228
+ registry.register(gatesCommand);
229
+ registry.registerSubcommand('gates', gatesListCommand);
230
+ registry.registerSubcommand('gates', gatesCoverageCommand);
231
+ registry.registerSubcommand('gates', gatesExplainCommand);
209
232
  registry.register(wiringCommand);
210
233
  registry.register(reuseCommand);
211
234
  registry.register(migrateCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shrkcrft/cli",
3
- "version": "0.1.0-alpha.27",
3
+ "version": "0.1.0-alpha.28",
4
4
  "description": "SharkCraft CLI (`shrk`): structured project intelligence for AI coding agents.",
5
5
  "license": "MIT",
6
6
  "author": "SharkCraft contributors",
@@ -47,38 +47,38 @@
47
47
  "typecheck": "tsc --noEmit -p tsconfig.json"
48
48
  },
49
49
  "dependencies": {
50
- "@shrkcrft/core": "^0.1.0-alpha.27",
51
- "@shrkcrft/compress": "^0.1.0-alpha.27",
52
- "@shrkcrft/config": "^0.1.0-alpha.27",
53
- "@shrkcrft/workspace": "^0.1.0-alpha.27",
54
- "@shrkcrft/knowledge": "^0.1.0-alpha.27",
55
- "@shrkcrft/context": "^0.1.0-alpha.27",
56
- "@shrkcrft/rules": "^0.1.0-alpha.27",
57
- "@shrkcrft/paths": "^0.1.0-alpha.27",
58
- "@shrkcrft/templates": "^0.1.0-alpha.27",
59
- "@shrkcrft/plugin-api": "^0.1.0-alpha.27",
60
- "@shrkcrft/dashboard": "^0.1.0-alpha.27",
61
- "@shrkcrft/dashboard-api": "^0.1.0-alpha.27",
62
- "@shrkcrft/pipelines": "^0.1.0-alpha.27",
63
- "@shrkcrft/presets": "^0.1.0-alpha.27",
64
- "@shrkcrft/boundaries": "^0.1.0-alpha.27",
65
- "@shrkcrft/graph": "^0.1.0-alpha.27",
66
- "@shrkcrft/rule-graph": "^0.1.0-alpha.27",
67
- "@shrkcrft/structural-search": "^0.1.0-alpha.27",
68
- "@shrkcrft/impact-engine": "^0.1.0-alpha.27",
69
- "@shrkcrft/context-planner": "^0.1.0-alpha.27",
70
- "@shrkcrft/architecture-guard": "^0.1.0-alpha.27",
71
- "@shrkcrft/framework-scanners": "^0.1.0-alpha.27",
72
- "@shrkcrft/api-surface-diff": "^0.1.0-alpha.27",
73
- "@shrkcrft/quality-gates": "^0.1.0-alpha.27",
74
- "@shrkcrft/migrate": "^0.1.0-alpha.27",
75
- "@shrkcrft/generator": "^0.1.0-alpha.27",
76
- "@shrkcrft/importer": "^0.1.0-alpha.27",
77
- "@shrkcrft/inspector": "^0.1.0-alpha.27",
78
- "@shrkcrft/ai": "^0.1.0-alpha.27",
79
- "@shrkcrft/embeddings": "^0.1.0-alpha.27",
80
- "@shrkcrft/shared": "^0.1.0-alpha.27",
81
- "@shrkcrft/mcp-server": "^0.1.0-alpha.27",
50
+ "@shrkcrft/core": "^0.1.0-alpha.28",
51
+ "@shrkcrft/compress": "^0.1.0-alpha.28",
52
+ "@shrkcrft/config": "^0.1.0-alpha.28",
53
+ "@shrkcrft/workspace": "^0.1.0-alpha.28",
54
+ "@shrkcrft/knowledge": "^0.1.0-alpha.28",
55
+ "@shrkcrft/context": "^0.1.0-alpha.28",
56
+ "@shrkcrft/rules": "^0.1.0-alpha.28",
57
+ "@shrkcrft/paths": "^0.1.0-alpha.28",
58
+ "@shrkcrft/templates": "^0.1.0-alpha.28",
59
+ "@shrkcrft/plugin-api": "^0.1.0-alpha.28",
60
+ "@shrkcrft/dashboard": "^0.1.0-alpha.28",
61
+ "@shrkcrft/dashboard-api": "^0.1.0-alpha.28",
62
+ "@shrkcrft/pipelines": "^0.1.0-alpha.28",
63
+ "@shrkcrft/presets": "^0.1.0-alpha.28",
64
+ "@shrkcrft/boundaries": "^0.1.0-alpha.28",
65
+ "@shrkcrft/graph": "^0.1.0-alpha.28",
66
+ "@shrkcrft/rule-graph": "^0.1.0-alpha.28",
67
+ "@shrkcrft/structural-search": "^0.1.0-alpha.28",
68
+ "@shrkcrft/impact-engine": "^0.1.0-alpha.28",
69
+ "@shrkcrft/context-planner": "^0.1.0-alpha.28",
70
+ "@shrkcrft/architecture-guard": "^0.1.0-alpha.28",
71
+ "@shrkcrft/framework-scanners": "^0.1.0-alpha.28",
72
+ "@shrkcrft/api-surface-diff": "^0.1.0-alpha.28",
73
+ "@shrkcrft/quality-gates": "^0.1.0-alpha.28",
74
+ "@shrkcrft/migrate": "^0.1.0-alpha.28",
75
+ "@shrkcrft/generator": "^0.1.0-alpha.28",
76
+ "@shrkcrft/importer": "^0.1.0-alpha.28",
77
+ "@shrkcrft/inspector": "^0.1.0-alpha.28",
78
+ "@shrkcrft/ai": "^0.1.0-alpha.28",
79
+ "@shrkcrft/embeddings": "^0.1.0-alpha.28",
80
+ "@shrkcrft/shared": "^0.1.0-alpha.28",
81
+ "@shrkcrft/mcp-server": "^0.1.0-alpha.28",
82
82
  "@huggingface/transformers": "^3.7.5"
83
83
  },
84
84
  "publishConfig": {