@shrkcrft/cli 0.1.0-alpha.21 → 0.1.0-alpha.23

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 (94) hide show
  1. package/dist/command-registry.d.ts +9 -0
  2. package/dist/command-registry.d.ts.map +1 -1
  3. package/dist/command-registry.js +15 -0
  4. package/dist/commands/ai-status.command.d.ts.map +1 -1
  5. package/dist/commands/ai-status.command.js +10 -0
  6. package/dist/commands/apply.command.d.ts.map +1 -1
  7. package/dist/commands/apply.command.js +9 -2
  8. package/dist/commands/ask.command.d.ts.map +1 -1
  9. package/dist/commands/ask.command.js +2 -1
  10. package/dist/commands/changes.command.d.ts.map +1 -1
  11. package/dist/commands/changes.command.js +14 -4
  12. package/dist/commands/check.command.d.ts.map +1 -1
  13. package/dist/commands/check.command.js +119 -3
  14. package/dist/commands/command-catalog.d.ts.map +1 -1
  15. package/dist/commands/command-catalog.js +224 -0
  16. package/dist/commands/commands.command.d.ts +15 -0
  17. package/dist/commands/commands.command.d.ts.map +1 -1
  18. package/dist/commands/commands.command.js +162 -3
  19. package/dist/commands/compress.command.d.ts.map +1 -1
  20. package/dist/commands/compress.command.js +39 -4
  21. package/dist/commands/constructs.command.d.ts.map +1 -1
  22. package/dist/commands/constructs.command.js +40 -9
  23. package/dist/commands/context.command.d.ts.map +1 -1
  24. package/dist/commands/context.command.js +3 -1
  25. package/dist/commands/daily.commands.d.ts.map +1 -1
  26. package/dist/commands/daily.commands.js +48 -5
  27. package/dist/commands/diff-check.command.d.ts.map +1 -1
  28. package/dist/commands/diff-check.command.js +6 -2
  29. package/dist/commands/feedback.command.d.ts.map +1 -1
  30. package/dist/commands/feedback.command.js +4 -0
  31. package/dist/commands/framework.command.d.ts.map +1 -1
  32. package/dist/commands/framework.command.js +20 -3
  33. package/dist/commands/gate.command.d.ts.map +1 -1
  34. package/dist/commands/gate.command.js +99 -2
  35. package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
  36. package/dist/commands/graph-code-subverbs.js +183 -68
  37. package/dist/commands/graph.command.d.ts.map +1 -1
  38. package/dist/commands/graph.command.js +6 -0
  39. package/dist/commands/impact.command.d.ts.map +1 -1
  40. package/dist/commands/impact.command.js +91 -1
  41. package/dist/commands/knowledge.command.d.ts.map +1 -1
  42. package/dist/commands/knowledge.command.js +21 -1
  43. package/dist/commands/onboard.command.d.ts.map +1 -1
  44. package/dist/commands/onboard.command.js +11 -2
  45. package/dist/commands/orchestrate.command.d.ts.map +1 -1
  46. package/dist/commands/orchestrate.command.js +6 -1
  47. package/dist/commands/pack-author.command.d.ts.map +1 -1
  48. package/dist/commands/pack-author.command.js +13 -1
  49. package/dist/commands/packs.command.d.ts.map +1 -1
  50. package/dist/commands/packs.command.js +95 -17
  51. package/dist/commands/paths.command.d.ts.map +1 -1
  52. package/dist/commands/paths.command.js +8 -1
  53. package/dist/commands/pipelines.command.d.ts.map +1 -1
  54. package/dist/commands/pipelines.command.js +2 -1
  55. package/dist/commands/plan-context.command.d.ts.map +1 -1
  56. package/dist/commands/plan-context.command.js +6 -3
  57. package/dist/commands/plan-simulate.command.js +1 -1
  58. package/dist/commands/policy-lint.command.d.ts +3 -0
  59. package/dist/commands/policy-lint.command.d.ts.map +1 -0
  60. package/dist/commands/policy-lint.command.js +135 -0
  61. package/dist/commands/recommend.command.d.ts.map +1 -1
  62. package/dist/commands/recommend.command.js +10 -2
  63. package/dist/commands/registry.command.d.ts.map +1 -1
  64. package/dist/commands/registry.command.js +117 -9
  65. package/dist/commands/report.command.js +1 -1
  66. package/dist/commands/reuse.command.d.ts +3 -0
  67. package/dist/commands/reuse.command.d.ts.map +1 -0
  68. package/dist/commands/reuse.command.js +202 -0
  69. package/dist/commands/review.command.d.ts.map +1 -1
  70. package/dist/commands/review.command.js +20 -2
  71. package/dist/commands/rule-graph-subverbs.d.ts.map +1 -1
  72. package/dist/commands/rule-graph-subverbs.js +31 -4
  73. package/dist/commands/search-structural.command.d.ts.map +1 -1
  74. package/dist/commands/search-structural.command.js +2 -2
  75. package/dist/commands/search.command.d.ts.map +1 -1
  76. package/dist/commands/search.command.js +19 -1
  77. package/dist/commands/simulate.command.d.ts.map +1 -1
  78. package/dist/commands/simulate.command.js +6 -1
  79. package/dist/commands/smart-context.command.d.ts.map +1 -1
  80. package/dist/commands/smart-context.command.js +87 -4
  81. package/dist/commands/spec.command.d.ts.map +1 -1
  82. package/dist/commands/spec.command.js +73 -13
  83. package/dist/commands/task-context.command.d.ts.map +1 -1
  84. package/dist/commands/task-context.command.js +26 -2
  85. package/dist/commands/test.command.d.ts.map +1 -1
  86. package/dist/commands/test.command.js +17 -0
  87. package/dist/commands/trace.command.d.ts.map +1 -1
  88. package/dist/commands/trace.command.js +14 -1
  89. package/dist/main.d.ts.map +1 -1
  90. package/dist/main.js +19 -1
  91. package/dist/status/freshness.d.ts +30 -0
  92. package/dist/status/freshness.d.ts.map +1 -0
  93. package/dist/status/freshness.js +81 -0
  94. package/package.json +33 -33
@@ -3,6 +3,8 @@ import * as nodePath from 'node:path';
3
3
  import { analyzeImpact, analyzeTestImpact, findSymbolInProject, FuzzyImpactSourceKind, getChangedFiles, ImpactInputKind, inspectSharkcraft, QueryMatchKind, readFeatureBundle, renderImpactGraph, renderImpactHtml, renderImpactMarkdown, renderImpactText, resolveFuzzyImpact, warmConstructCache, } from '@shrkcrft/inspector';
4
4
  import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../command-registry.js";
5
5
  import { asJson, header, kv } from "../output/format-output.js";
6
+ import { fuzzyImpactAmbiguousHints, renderFailureHints } from "../output/failure-hints.js";
7
+ import { collectChangedPaths } from "../diff/collect-changed-paths.js";
6
8
  function collectFiles(args, cwd) {
7
9
  const diagnostics = [];
8
10
  const explicitFiles = flagList(args, 'files');
@@ -278,10 +280,90 @@ async function runViaGraph(args) {
278
280
  process.stdout.write(`! ${d}\n`);
279
281
  return 0;
280
282
  }
283
+ /**
284
+ * `shrk impact --deleted`: deleted-symbol orphan check. Reads the
285
+ * working-tree diff's DELETED files (relative to `--since <ref>` or the
286
+ * default branch) and queries the graph for surviving files that still
287
+ * import them or reference a symbol they declared (alias-resolved, incl.
288
+ * barrel re-exports). Any surviving importer is reported with `file:line`
289
+ * and the command exits non-zero; with none it exits 0 with
290
+ * "no orphaned importers". Mirrors `--via-graph`'s flag/JSON style.
291
+ *
292
+ * The graph is queried against the CURRENT index snapshot — a not-yet-
293
+ * reindexed delete still carries its inbound edges, which is exactly what
294
+ * lets the check see the broken importers before they hit the build.
295
+ */
296
+ async function runDeletedOrphans(args) {
297
+ const cwd = resolveCwd(args);
298
+ const wantJson = flagBool(args, 'json') || flagString(args, 'format') === 'json';
299
+ const sinceRef = flagString(args, 'since');
300
+ const changed = collectChangedPaths({ cwd, ...(sinceRef ? { ref: sinceRef } : {}) });
301
+ if (!changed.isAvailable) {
302
+ if (wantJson) {
303
+ process.stdout.write(asJson({ ok: false, error: changed.error }) + '\n');
304
+ }
305
+ else {
306
+ process.stderr.write(`Cannot resolve diff: ${changed.error ?? 'unknown'}\n`);
307
+ }
308
+ return 2;
309
+ }
310
+ const deleted = changed.deleted;
311
+ if (deleted.length === 0) {
312
+ if (wantJson) {
313
+ process.stdout.write(asJson({
314
+ schema: 'sharkcraft.deleted-orphans/v1',
315
+ resolvedDeleted: [],
316
+ unresolvedDeleted: [],
317
+ orphans: [],
318
+ diagnostics: [`no deleted files in diff vs ${changed.ref}`],
319
+ }) + '\n');
320
+ return 0;
321
+ }
322
+ process.stdout.write(header('Deleted-symbol orphans'));
323
+ process.stdout.write(`No deleted files in diff vs ${changed.ref}.\n`);
324
+ return 0;
325
+ }
326
+ const { GraphStore, GraphQueryApi } = await import('@shrkcrft/graph');
327
+ if (!new GraphStore(cwd).exists()) {
328
+ const msg = 'code-graph store missing — run `shrk graph index` first.';
329
+ if (wantJson) {
330
+ process.stdout.write(asJson({ ok: false, error: msg }) + '\n');
331
+ }
332
+ else {
333
+ process.stderr.write(msg + '\n');
334
+ }
335
+ return 2;
336
+ }
337
+ const { findDeletedOrphans } = await import('@shrkcrft/impact-engine');
338
+ const report = findDeletedOrphans(GraphQueryApi.fromStore(cwd), deleted);
339
+ if (wantJson) {
340
+ process.stdout.write(asJson(report) + '\n');
341
+ return report.orphans.length > 0 ? 1 : 0;
342
+ }
343
+ process.stdout.write(header('Deleted-symbol orphans'));
344
+ process.stdout.write(`Deleted files (vs ${changed.ref}): ${deleted.length}\n`);
345
+ if (report.orphans.length === 0) {
346
+ process.stdout.write('no orphaned importers\n');
347
+ for (const d of report.diagnostics.slice(0, 5))
348
+ process.stdout.write(`! ${d}\n`);
349
+ return 0;
350
+ }
351
+ process.stdout.write(`\n${report.orphans.length} surviving importer(s) still reference deleted code:\n`);
352
+ for (const o of report.orphans) {
353
+ const loc = o.path ? `${o.path}${o.line ? `:${o.line}` : ''}` : o.id;
354
+ const detail = o.via === 'reference' && o.symbol
355
+ ? `references \`${o.symbol}\``
356
+ : 'imports';
357
+ process.stdout.write(` ✗ ${loc} ${detail} from deleted ${o.deletedFile}\n`);
358
+ }
359
+ for (const d of report.diagnostics.slice(0, 5))
360
+ process.stdout.write(`! ${d}\n`);
361
+ return 1;
362
+ }
281
363
  export const impactCommand = {
282
364
  name: 'impact',
283
365
  description: 'Architecture impact analysis: direct + transitive dependents, risk + suggested commands. Supports fuzzy <query> resolution. Read-only.',
284
- usage: 'shrk impact <fileOrQuery> | --file <path> | --specifier <spec> | --since <ref> | --staged | --files a,b | --plan <plan.json> | --bundle <id> [--max-depth N] [--limit N] [--format text|markdown|html|json] [--output <path>] [--tree|--no-tree] [--json] [--html] [--resolve|--resolve-only|--explain-resolution|--no-resolve]',
366
+ usage: 'shrk impact <fileOrQuery> | --file <path> | --specifier <spec> | --since <ref> | --staged | --files a,b | --plan <plan.json> | --bundle <id> | --deleted [--since <ref>] [--max-depth N] [--limit N] [--format text|markdown|html|json] [--output <path>] [--tree|--no-tree] [--json] [--html] [--resolve|--resolve-only|--explain-resolution|--no-resolve]',
285
367
  async run(args) {
286
368
  if (args.positional[0] === 'tests') {
287
369
  return runImpactTests({ ...args, positional: args.positional.slice(1) });
@@ -299,6 +381,13 @@ export const impactCommand = {
299
381
  if (args.flags.has('via-graph')) {
300
382
  return runViaGraph(args);
301
383
  }
384
+ // --deleted: reverse-of-impact orphan check. Reads the working-tree
385
+ // diff's DELETED files and asks the graph which surviving files still
386
+ // import them or reference a symbol they declared. Any surviving
387
+ // importer is an error (its build breaks once the delete lands).
388
+ if (args.flags.has('deleted')) {
389
+ return runDeletedOrphans(args);
390
+ }
302
391
  const cwd = resolveCwd(args);
303
392
  const inspection = await inspectSharkcraft({ cwd });
304
393
  // Warm construct cache so fuzzy resolution can map plugin keys / events /
@@ -487,6 +576,7 @@ export const impactCommand = {
487
576
  }
488
577
  for (const d of fuzzyResolution.diagnostics)
489
578
  process.stdout.write(` ! ${d}\n`);
579
+ process.stdout.write(renderFailureHints(fuzzyImpactAmbiguousHints()));
490
580
  }
491
581
  return 1;
492
582
  }
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.command.ts"],"names":[],"mappings":"AAkBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAoFhC,eAAO,MAAM,oBAAoB,EAAE,eA8ClC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAqCpC,CAAC;AAoBF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AA8NF,eAAO,MAAM,sBAAsB,EAAE,eAQpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8CxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAuBrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,eA8B1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8BxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,eAkC1C,CAAC"}
1
+ {"version":3,"file":"knowledge.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAoGhC,eAAO,MAAM,oBAAoB,EAAE,eAgDlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAuCpC,CAAC;AAoBF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AA8NF,eAAO,MAAM,sBAAsB,EAAE,eAQpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8CxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAuBrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,eA8B1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8BxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,eAkC1C,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { join as nodePathJoin, resolve as nodePathResolve } from 'node:path';
3
3
  import { buildAnchorUpdatePlan, buildKnowledgeStaleReport, buildRenameFilePlan, buildRenameSymbolPlan, inspectSharkcraft, ReferenceCheckOutcome, resolveChangedFiles, } from '@shrkcrft/inspector';
4
- import { formatEntryCompact, formatEntryFull, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
4
+ import { ALL_KNOWLEDGE_TYPES, formatEntryCompact, formatEntryFull, isKnowledgeType, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
5
5
  import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../command-registry.js";
6
6
  import { asJson, header } from "../output/format-output.js";
7
7
  import { maybeRunInWatchMode } from "../output/watch-loop.js";
@@ -51,6 +51,20 @@ function renderStaleCheckHtml(p) {
51
51
  ${p.ci.exitNonZero ? `<p style="color:#a40000;font-weight:bold">FAIL: ${esc(p.ci.exitReason ?? '')}</p>` : ''}
52
52
  `;
53
53
  }
54
+ /**
55
+ * Validate `--type` filter values against the KnowledgeType vocabulary and
56
+ * reject (exit 2) on any unknown value. Without this a typo'd `--type` would
57
+ * silently filter every entry out and return an empty result with exit 0.
58
+ * Returns the exit code to propagate when a value is unknown, or null when all
59
+ * values are valid (or none were supplied).
60
+ */
61
+ function rejectUnknownKnowledgeTypes(types) {
62
+ const unknown = types.filter((t) => !isKnowledgeType(t));
63
+ if (unknown.length === 0)
64
+ return null;
65
+ process.stderr.write(`Unknown --type ${unknown.join(', ')}. Valid: ${ALL_KNOWLEDGE_TYPES.join(', ')}\n`);
66
+ return 2;
67
+ }
54
68
  export const knowledgeListCommand = {
55
69
  name: 'list',
56
70
  description: 'List knowledge entries.',
@@ -58,6 +72,9 @@ export const knowledgeListCommand = {
58
72
  async run(args) {
59
73
  const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
60
74
  const types = flagList(args, 'type');
75
+ const typeReject = rejectUnknownKnowledgeTypes(types);
76
+ if (typeReject !== null)
77
+ return typeReject;
61
78
  const scope = flagList(args, 'scope');
62
79
  let entries = inspection.knowledgeEntries;
63
80
  if (types.length)
@@ -129,6 +146,9 @@ export const knowledgeSearchCommand = {
129
146
  const query = args.positional.join(' ').trim();
130
147
  const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
131
148
  const types = flagList(args, 'type');
149
+ const typeReject = rejectUnknownKnowledgeTypes(types);
150
+ if (typeReject !== null)
151
+ return typeReject;
132
152
  const scope = flagList(args, 'scope');
133
153
  const tags = flagList(args, 'tag');
134
154
  const appliesWhen = flagList(args, 'appliesWhen');
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.command.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,cAAc,EAAE,eA4N5B,CAAC"}
1
+ {"version":3,"file":"onboard.command.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,cAAc,EAAE,eAwO5B,CAAC"}
@@ -14,13 +14,22 @@ export const onboardCommand = {
14
14
  return runOnboardAdopt(sliced);
15
15
  }
16
16
  const cwd = resolveCwd(args);
17
- const writeDrafts = flagBool(args, 'write-drafts');
17
+ const writeDraftsFlag = flagBool(args, 'write-drafts');
18
+ const dryRunFlag = flagBool(args, 'dry-run');
19
+ // --dry-run is authoritative: it overrides --write-drafts so that
20
+ // `onboard --dry-run --write-drafts` never writes. `writeDrafts` below is
21
+ // the EFFECTIVE value used by every write guard / mode label.
22
+ const writeDrafts = writeDraftsFlag && !dryRunFlag;
23
+ const dryRunOverrodeWrite = writeDraftsFlag && dryRunFlag;
18
24
  const scaffoldTemplates = flagBool(args, 'scaffold-templates');
19
25
  const importAgents = flagBool(args, 'import-agents');
20
26
  const diffMode = flagBool(args, 'diff');
21
- const dryRun = flagBool(args, 'dry-run') || !writeDrafts;
27
+ const dryRun = !writeDrafts;
22
28
  const preferredPreset = flagString(args, 'preset');
23
29
  const asJsonOut = flagBool(args, 'json');
30
+ if (dryRunOverrodeWrite) {
31
+ process.stderr.write('Note: --dry-run overrode --write-drafts; no files were written.\n');
32
+ }
24
33
  const inspection = await inspectSharkcraft({ cwd });
25
34
  const plan = buildOnboardingPlan(inspection, {
26
35
  ...(preferredPreset ? { preferredPreset } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrate.command.d.ts","sourceRoot":"","sources":["../../src/commands/orchestrate.command.ts"],"names":[],"mappings":"AASA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,kBAAkB,EAAE,eA8ChC,CAAC"}
1
+ {"version":3,"file":"orchestrate.command.d.ts","sourceRoot":"","sources":["../../src/commands/orchestrate.command.ts"],"names":[],"mappings":"AASA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAKhC,eAAO,MAAM,kBAAkB,EAAE,eAoDhC,CAAC"}
@@ -3,10 +3,11 @@ import * as nodePath from 'node:path';
3
3
  import { buildAgentOrchestrationPlan, inspectSharkcraft, OrchestrationMode, renderOrchestrationMarkdown, renderOrchestrationText, } from '@shrkcrft/inspector';
4
4
  import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
5
5
  import { asJson } from "../output/format-output.js";
6
+ const VALID_ORCHESTRATION_MODES = ['conservative', 'balanced', 'aggressive'];
6
7
  export const orchestrateCommand = {
7
8
  name: 'orchestrate',
8
9
  description: 'Produce a read-only agent orchestration plan (discovery / plan / review / apply / validate). No execution; no writes.',
9
- usage: 'shrk orchestrate "<task>" [--mode conservative|balanced|aggressive] [--bundle] [--session] [--json] [--output <file.md>]',
10
+ usage: 'shrk orchestrate "<task>" [--mode conservative|balanced|aggressive] [--json] [--output <file.md>]',
10
11
  async run(args) {
11
12
  const task = args.positional.join(' ').trim();
12
13
  if (!task) {
@@ -16,6 +17,10 @@ export const orchestrateCommand = {
16
17
  const cwd = resolveCwd(args);
17
18
  const inspection = await inspectSharkcraft({ cwd });
18
19
  const modeRaw = (flagString(args, 'mode') ?? '').toLowerCase();
20
+ // Warn on a typo'd --mode rather than silently treating it as balanced.
21
+ if (modeRaw && !VALID_ORCHESTRATION_MODES.includes(modeRaw)) {
22
+ process.stderr.write(`Unknown --mode ${modeRaw}. Valid: ${VALID_ORCHESTRATION_MODES.join(', ')} (defaulting to balanced).\n`);
23
+ }
19
24
  const mode = modeRaw === 'conservative'
20
25
  ? OrchestrationMode.Conservative
21
26
  : modeRaw === 'aggressive'
@@ -1 +1 @@
1
- {"version":3,"file":"pack-author.command.d.ts","sourceRoot":"","sources":["../../src/commands/pack-author.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAuChC,eAAO,MAAM,uBAAuB,EAAE,eA2BrC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAoFtC,CAAC;AAKF,eAAO,MAAM,wBAAwB,EAAE,eAgCtC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,eAgBvC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,EAAE,eA2BlC,CAAC"}
1
+ {"version":3,"file":"pack-author.command.d.ts","sourceRoot":"","sources":["../../src/commands/pack-author.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAuChC,eAAO,MAAM,uBAAuB,EAAE,eA2CrC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAoFtC,CAAC;AAKF,eAAO,MAAM,wBAAwB,EAAE,eAgCtC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,eAgBvC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,EAAE,eA2BlC,CAAC"}
@@ -49,8 +49,16 @@ export const packAuthorStatusCommand = {
49
49
  const cwd = resolveCwd(args);
50
50
  const inspection = await inspectSharkcraft({ cwd });
51
51
  const status = buildPackAuthorStatus(inspection);
52
+ // Freshness: the pack authoring state is stale (relative to a signed,
53
+ // applied baseline) while drafts are pending — they have been authored
54
+ // since the last apply/sign but not yet incorporated.
55
+ const state = status.pendingDrafts > 0 ? 'stale' : 'fresh';
52
56
  if (flagBool(args, 'json')) {
53
- process.stdout.write(asJson(status) + '\n');
57
+ process.stdout.write(asJson({
58
+ ...status,
59
+ state,
60
+ ...(state === 'stale' ? { nextCommand: 'shrk pack author pending' } : {}),
61
+ }) + '\n');
54
62
  return 0;
55
63
  }
56
64
  process.stdout.write(header('Pack author status'));
@@ -60,6 +68,10 @@ export const packAuthorStatusCommand = {
60
68
  process.stdout.write(` pending drafts: ${status.pendingDrafts}\n`);
61
69
  for (const f of status.pendingDraftFiles)
62
70
  process.stdout.write(` - ${f}\n`);
71
+ process.stdout.write(` state: ${state}\n`);
72
+ if (state === 'stale') {
73
+ process.stdout.write(` ! stale — ${status.pendingDrafts} pending draft(s) authored since the last apply/sign; run \`shrk pack author pending\`\n`);
74
+ }
63
75
  process.stdout.write(' contribution counts:\n');
64
76
  for (const [k, n] of Object.entries(status.contributionCounts)) {
65
77
  const support = status.authoringSupport[k] ?? 'deferred';
@@ -1 +1 @@
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
+ {"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,eAwD9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAyE7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAqDjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAoGhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eA2IhC,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"}
@@ -201,6 +201,7 @@ export const packsListCommand = {
201
201
  resolvedCounts: p.resolvedCounts,
202
202
  signatureStatus: p.signatureStatus,
203
203
  signatureMessage: p.signatureMessage,
204
+ signatureDev: p.signatureDev,
204
205
  loadError: p.loadError,
205
206
  validationIssues: p.validationIssues,
206
207
  }))) + '\n');
@@ -282,6 +283,9 @@ export const packsGetCommand = {
282
283
  if (pack.signatureStatus) {
283
284
  process.stdout.write('\nSignature:\n');
284
285
  process.stdout.write(` status: ${pack.signatureStatus}\n`);
286
+ if (pack.signatureDev) {
287
+ process.stdout.write(' dev: yes (NOT release-trusted)\n');
288
+ }
285
289
  if (pack.signatureMessage) {
286
290
  process.stdout.write(` message: ${pack.signatureMessage}\n`);
287
291
  }
@@ -355,20 +359,30 @@ export const packsInspectCommand = {
355
359
  export const packsDoctorCommand = {
356
360
  name: 'doctor',
357
361
  description: 'Validate pack discovery: invalid manifests, missing files, empty contributions, duplicates, template/pipeline quality, action-hint coverage, signatures. `--release` folds pack-release-check findings into the report. `--signature-explain` adds per-pack signature explanation.',
358
- usage: 'shrk [--cwd <dir>] packs doctor [--verify-signatures] [--require-signatures] [--release] [--strict] [--secret <secret>] [--signature-explain] [--json]',
362
+ usage: 'shrk [--cwd <dir>] packs doctor [--verify-signatures] [--require-signatures] [--allow-dev-signature] [--release] [--strict] [--secret <secret>] [--signature-explain] [--json]',
359
363
  async run(args) {
360
- const verify = flagBool(args, 'verify-signatures') || flagBool(args, 'require-signatures');
364
+ const signatureExplain = flagBool(args, 'signature-explain');
365
+ // `--signature-explain` implies signature verification so the lifecycle
366
+ // states it prints are backed by a real HMAC check this run — otherwise a
367
+ // bogus-HMAC-but-fresh-timestamp pack would be reported off freshness
368
+ // alone instead of the honest "invalid".
369
+ const verify = flagBool(args, 'verify-signatures') ||
370
+ flagBool(args, 'require-signatures') ||
371
+ signatureExplain;
361
372
  const required = flagBool(args, 'require-signatures');
362
373
  const release = flagBool(args, 'release');
363
374
  const strict = flagBool(args, 'strict');
364
375
  const secret = flagString(args, 'secret');
365
- const signatureExplain = flagBool(args, 'signature-explain');
376
+ const allowDev = flagBool(args, 'allow-dev-signature');
366
377
  const inspection = await inspectSharkcraft({
367
378
  cwd: resolveCwd(args),
368
379
  ...(verify ? { verifyPackSignatures: true } : {}),
369
380
  ...(secret !== undefined ? { packSecret: secret } : {}),
370
381
  });
371
- const report = buildPackDoctorReport(inspection, { requireSignatures: required });
382
+ const report = buildPackDoctorReport(inspection, {
383
+ requireSignatures: required,
384
+ ...(allowDev ? { allowDevSignatures: true } : {}),
385
+ });
372
386
  if (release) {
373
387
  const releaseChecks = await runPackReleaseChecksForReport(inspection);
374
388
  mergePackReleaseChecks(inspection, report, releaseChecks, { strict });
@@ -439,32 +453,93 @@ export const packsDoctorCommand = {
439
453
  };
440
454
  export const packsVerifyCommand = {
441
455
  name: 'verify',
442
- description: 'Verify HMAC signatures on every discovered pack. Unsigned packs are reported but do not fail.',
443
- usage: 'shrk [--cwd <dir>] packs verify [--secret <secret>] [--required] [--json]',
456
+ description: 'Verify HMAC signatures on every discovered pack. Unsigned packs are reported but do not fail. Under --required, a signed pack that could not be verified (no secret) or that carries a dev signature fails too — pass --allow-dev-signature to trust dev signatures for local-only flows.',
457
+ usage: 'shrk [--cwd <dir>] packs verify [--secret <secret>] [--required] [--allow-dev-signature] [--json]',
444
458
  async run(args) {
445
459
  const secret = flagString(args, 'secret');
460
+ const allowDev = flagBool(args, 'allow-dev-signature');
446
461
  const inspection = await inspectSharkcraft({
447
462
  cwd: resolveCwd(args),
448
463
  verifyPackSignatures: true,
449
464
  ...(secret !== undefined ? { packSecret: secret } : {}),
450
465
  });
451
466
  const required = flagBool(args, 'required');
452
- const rows = inspection.packs.discoveredPacks.map((p) => ({
453
- packageName: p.packageName,
454
- packageVersion: p.packageVersion,
455
- valid: p.valid,
456
- signatureStatus: p.signatureStatus ?? 'not-checked',
457
- signatureMessage: p.signatureMessage,
458
- }));
467
+ const rows = inspection.packs.discoveredPacks.map((p) => {
468
+ let signatureStatus = (p.signatureStatus ?? 'not-checked');
469
+ let signatureMessage = p.signatureMessage;
470
+ let signatureDev = p.signatureDev === true;
471
+ // --allow-dev-signature: actually run the HMAC check against the
472
+ // well-known dev secret so a *tampered* dev signature still fails. The
473
+ // default discovery path short-circuits to 'dev-signature' BEFORE
474
+ // hashing, so we must re-verify here rather than blindly trust the tag.
475
+ if (allowDev && signatureStatus === 'dev-signature' && p.manifest) {
476
+ const v = verifyPackManifest(p.manifest, {
477
+ allowDev: true,
478
+ ...(secret !== undefined ? { secret } : {}),
479
+ });
480
+ signatureStatus = (v.ok ? 'verified' : v.status);
481
+ signatureMessage = v.ok ? 'Dev signature verified (--allow-dev-signature).' : v.message;
482
+ signatureDev = true;
483
+ }
484
+ return {
485
+ packageName: p.packageName,
486
+ packageVersion: p.packageVersion,
487
+ valid: p.valid,
488
+ signatureStatus,
489
+ signatureMessage,
490
+ signatureDev,
491
+ };
492
+ });
459
493
  const tampered = rows.some((r) => r.signatureStatus === 'invalid-signature');
460
494
  const unsigned = rows.some((r) => r.signatureStatus === 'missing-signature');
461
- const passed = !tampered && (!required || !unsigned);
495
+ // A SIGNED pack we could NOT actually verify this run: the secret was
496
+ // missing, or it carries a dev signature that is not release-trusted (and
497
+ // --allow-dev-signature was not passed). Reporting these as "OK" was the
498
+ // fail-open hole — required verification that could not run must FAIL.
499
+ const missingSecretCount = rows.filter((r) => r.signatureStatus === 'missing-secret').length;
500
+ const devCount = rows.filter((r) => r.signatureStatus === 'dev-signature').length;
501
+ const unverifiable = missingSecretCount > 0 || devCount > 0;
502
+ const signedCount = rows.filter((r) => r.signatureStatus !== 'missing-signature' && r.signatureStatus !== 'not-checked').length;
503
+ const verifiedCount = rows.filter((r) => r.signatureStatus === 'verified').length;
504
+ const allSignedVerified = signedCount > 0 && verifiedCount === signedCount;
505
+ const passed = !tampered && (!required || (!unsigned && !unverifiable));
506
+ const verdict = (() => {
507
+ if (tampered)
508
+ return 'TAMPERED pack detected — abort!';
509
+ if (required && (unverifiable || unsigned)) {
510
+ const bits = [];
511
+ if (missingSecretCount > 0)
512
+ bits.push(`${missingSecretCount} signed pack(s) could not be verified (no secret) — set ${PACK_SECRET_ENV}`);
513
+ if (devCount > 0)
514
+ bits.push(`${devCount} dev-signed pack(s) are not release-trusted — pass --allow-dev-signature to accept them`);
515
+ if (unsigned)
516
+ bits.push('unsigned pack present');
517
+ return bits.join('; ');
518
+ }
519
+ if (allSignedVerified && !unsigned && !unverifiable)
520
+ return 'all signatures OK ✓';
521
+ if (unverifiable || unsigned) {
522
+ const bits = [];
523
+ if (missingSecretCount > 0)
524
+ bits.push(`${missingSecretCount} signed pack(s) unverified (no secret)`);
525
+ if (devCount > 0)
526
+ bits.push(`${devCount} dev-signed pack(s) not release-trusted`);
527
+ if (unsigned)
528
+ bits.push('unsigned pack present');
529
+ return bits.join('; ') + ' (use --required to fail)';
530
+ }
531
+ return signedCount > 0 ? 'all signatures OK ✓' : 'no signatures to verify';
532
+ })();
462
533
  if (flagBool(args, 'json')) {
463
534
  process.stdout.write(asJson({
464
535
  passed,
465
536
  required,
537
+ allowDevSignature: allowDev,
466
538
  tampered,
467
539
  unsignedPresent: unsigned,
540
+ unverifiable,
541
+ unverifiableCount: missingSecretCount,
542
+ devSignatureCount: devCount,
468
543
  packs: rows,
469
544
  }) + '\n');
470
545
  return passed ? 0 : 1;
@@ -483,10 +558,13 @@ export const packsVerifyCommand = {
483
558
  ? 'UNSIGNED'
484
559
  : r.signatureStatus === 'missing-secret'
485
560
  ? 'NO SECRET'
486
- : 'NOT CHECKED';
487
- process.stdout.write(` ${tag.padEnd(12)} ${r.packageName.padEnd(40)} ${r.signatureMessage ?? ''}\n`);
561
+ : r.signatureStatus === 'dev-signature'
562
+ ? 'DEV'
563
+ : 'NOT CHECKED';
564
+ const devNote = r.signatureStatus === 'dev-signature' ? ' (not release-trusted)' : '';
565
+ process.stdout.write(` ${tag.padEnd(12)} ${r.packageName.padEnd(40)} ${r.signatureMessage ?? ''}${devNote}\n`);
488
566
  }
489
- process.stdout.write(`\nVerdict: ${passed ? 'all signatures OK ✓' : tampered ? 'TAMPERED pack detected — abort!' : 'unsigned pack present (use --required to fail)'}\n`);
567
+ process.stdout.write(`\nVerdict: ${verdict}\n`);
490
568
  if (!secret && !process.env[PACK_SECRET_ENV]) {
491
569
  process.stdout.write(`(Tip: set ${PACK_SECRET_ENV} or pass --secret to verify signed packs.)\n`);
492
570
  }
@@ -1 +1 @@
1
- {"version":3,"file":"paths.command.d.ts","sourceRoot":"","sources":["../../src/commands/paths.command.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,gBAAgB,EAAE,eAmB9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAuB7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAsBhC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eA0B9B,CAAC"}
1
+ {"version":3,"file":"paths.command.d.ts","sourceRoot":"","sources":["../../src/commands/paths.command.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,gBAAgB,EAAE,eAmB9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAuB7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAsBhC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAiC9B,CAAC"}
@@ -82,11 +82,18 @@ export const pathsBestCommand = {
82
82
  }
83
83
  const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
84
84
  const selection = inspection.pathService.findBestForTask(task);
85
+ const wantJson = flagBool(args, 'json');
85
86
  if (!selection) {
87
+ // Keep `--json` machine-parseable on a miss: emit `{match:null}` rather
88
+ // than the human sentence so a consumer can `JSON.parse` the output.
89
+ if (wantJson) {
90
+ process.stdout.write(asJson({ match: null }) + '\n');
91
+ return 0;
92
+ }
86
93
  process.stdout.write('No matching path convention.\n');
87
94
  return 0;
88
95
  }
89
- if (flagBool(args, 'json')) {
96
+ if (wantJson) {
90
97
  process.stdout.write(asJson(selection) + '\n');
91
98
  return 0;
92
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pipelines.command.d.ts","sourceRoot":"","sources":["../../src/commands/pipelines.command.ts"],"names":[],"mappings":"AAUA,OAAO,EAOL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,oBAAoB,EAAE,eA2BlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAsDrC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eA+DlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAoCpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eA6ClC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAiElC,CAAC"}
1
+ {"version":3,"file":"pipelines.command.d.ts","sourceRoot":"","sources":["../../src/commands/pipelines.command.ts"],"names":[],"mappings":"AAeA,OAAO,EAOL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,oBAAoB,EAAE,eA2BlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAuDrC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eA+DlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAoCpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eA6ClC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAiElC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { inspectSharkcraft, buildProjectOverview, renderOverviewText } from '@shrkcrft/inspector';
1
+ import { inspectSharkcraft, buildProjectOverview, renderOverviewText, contextTuningBoostFor, } from '@shrkcrft/inspector';
2
2
  import { buildContext } from '@shrkcrft/context';
3
3
  import { findNextStep, formatPipelineCompact, formatPipelineFull, interpolatePipeline, renderPipelineScript, } from '@shrkcrft/pipelines';
4
4
  import { flagBool, flagNumber, flagString, flagList, flagVars, resolveCwd, } from "../command-registry.js";
@@ -81,6 +81,7 @@ export const pipelinesContextCommand = {
81
81
  scope,
82
82
  maxTokens,
83
83
  projectOverview: renderOverviewText(overview),
84
+ boostFor: contextTuningBoostFor(inspection, task),
84
85
  });
85
86
  if (flagBool(args, 'json')) {
86
87
  process.stdout.write(asJson({
@@ -1 +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,eAsEhC,CAAC"}
1
+ {"version":3,"file":"plan-context.command.d.ts","sourceRoot":"","sources":["../../src/commands/plan-context.command.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAyEhC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { planContext } from '@shrkcrft/context-planner';
2
- import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
2
+ import { flagBool, flagPositiveInt, flagString, resolveCwd, } from "../command-registry.js";
3
3
  import { asJson, header, kv } from "../output/format-output.js";
4
4
  /**
5
5
  * `shrk plan-context` — produce a deterministic, token-budgeted context
@@ -21,8 +21,11 @@ export const planContextCommand = {
21
21
  process.stderr.write(this.usage + '\n');
22
22
  return 2;
23
23
  }
24
- const budget = Number(flagString(args, 'budget') ?? '8000');
25
- const maxFiles = Number(flagString(args, 'max-files') ?? '30');
24
+ // NaN-safe: a fat-fingered `--budget abc` would otherwise become NaN and
25
+ // print "NaN tokens" while selecting 0 files at exit 0. Fall back to the
26
+ // documented defaults instead.
27
+ const budget = flagPositiveInt(args, 'budget', 8000);
28
+ const maxFiles = flagPositiveInt(args, 'max-files', 30);
26
29
  const hintedFiles = collectMulti(args, 'hint-file');
27
30
  const hintedPackages = collectMulti(args, 'hint-package');
28
31
  const pack = planContext({
@@ -6,7 +6,7 @@ import { asJson } from "../output/format-output.js";
6
6
  export const planSimulateCommand = {
7
7
  name: 'simulate',
8
8
  description: 'Simulate a saved generation plan (v1 or v2): virtual final content, classified operations, boundary/policy/impact/test gates, apply readiness. Read-only.',
9
- usage: 'shrk plan simulate <plan.json> [--format text|markdown|html|json] [--output <file>] [--strict] [--include-boundaries] [--include-impact] [--include-tests] [--include-policies] [--include-ownership] [--include-memory] [--diff] [--max-diff-lines N]',
9
+ usage: 'shrk plan simulate <plan.json> [--format text|markdown|html|json] [--output <file>] [--strict] [--no-boundaries] [--no-impact] [--no-tests] [--no-policies] [--no-ownership] [--include-memory] [--diff] [--max-diff-lines N]',
10
10
  async run(args) {
11
11
  const planPath = args.positional[0];
12
12
  if (!planPath) {
@@ -0,0 +1,3 @@
1
+ import { type ICommandHandler } from '../command-registry.js';
2
+ export declare const policyLintCommand: ICommandHandler;
3
+ //# sourceMappingURL=policy-lint.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-lint.command.d.ts","sourceRoot":"","sources":["../../src/commands/policy-lint.command.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAKhC,eAAO,MAAM,iBAAiB,EAAE,eAkJ/B,CAAC"}