@shrkcrft/cli 0.1.0-alpha.15 → 0.1.0-alpha.17

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 (37) hide show
  1. package/dist/command-registry.d.ts +18 -0
  2. package/dist/command-registry.d.ts.map +1 -1
  3. package/dist/command-registry.js +84 -0
  4. package/dist/commands/apply.command.d.ts.map +1 -1
  5. package/dist/commands/apply.command.js +10 -2
  6. package/dist/commands/cache-align.command.d.ts +12 -0
  7. package/dist/commands/cache-align.command.d.ts.map +1 -0
  8. package/dist/commands/cache-align.command.js +78 -0
  9. package/dist/commands/command-catalog.d.ts.map +1 -1
  10. package/dist/commands/command-catalog.js +44 -0
  11. package/dist/commands/compress.command.d.ts +15 -0
  12. package/dist/commands/compress.command.d.ts.map +1 -0
  13. package/dist/commands/compress.command.js +126 -0
  14. package/dist/commands/deps-audit.command.js +4 -0
  15. package/dist/commands/dev.command.d.ts.map +1 -1
  16. package/dist/commands/dev.command.js +5 -1
  17. package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
  18. package/dist/dashboard/dashboard-api-server.js +65 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3 -0
  22. package/dist/main.d.ts.map +1 -1
  23. package/dist/main.js +24 -2
  24. package/dist/output/ccr-store-config.d.ts +18 -0
  25. package/dist/output/ccr-store-config.d.ts.map +1 -0
  26. package/dist/output/ccr-store-config.js +22 -0
  27. package/dist/output/format-output.d.ts.map +1 -1
  28. package/dist/output/format-output.js +6 -1
  29. package/dist/output/output-compression.d.ts +15 -0
  30. package/dist/output/output-compression.d.ts.map +1 -0
  31. package/dist/output/output-compression.js +60 -0
  32. package/dist/output/resolve-compress-type.d.ts +22 -0
  33. package/dist/output/resolve-compress-type.d.ts.map +1 -0
  34. package/dist/output/resolve-compress-type.js +21 -0
  35. package/dist/validation/run-validation-loop.d.ts.map +1 -1
  36. package/dist/validation/run-validation-loop.js +5 -1
  37. package/package.json +33 -32
@@ -111,6 +111,24 @@ export declare function extractGlobalCwd(argv: readonly string[]): {
111
111
  cwd?: string;
112
112
  rest: string[];
113
113
  };
114
+ /** A request to compress a command's stdout, parsed from the global flags. */
115
+ export interface IGlobalCompressDirective {
116
+ /** Force a content type for the compressor (else auto-detect). */
117
+ type?: string;
118
+ /** Query text that biases which lines/matches the compressor keeps. */
119
+ query?: string;
120
+ }
121
+ /**
122
+ * Extracts the global output-compression flags from anywhere in argv:
123
+ * `--compress` / `--ccr` (synonyms; turn it on) plus optional
124
+ * `--compress-type <t>` and `--compress-query <q>`. Returns the directive (when
125
+ * any was present) and the remaining argv with those flags removed — so the
126
+ * underlying command can be re-run cleanly without them (and never recurses).
127
+ */
128
+ export declare function extractGlobalCompress(argv: readonly string[]): {
129
+ directive?: IGlobalCompressDirective;
130
+ rest: string[];
131
+ };
114
132
  /**
115
133
  * Returns the absolute cwd for the current command:
116
134
  * 1. Command-level --cwd flag (if passed after the command)
@@ -1 +1 @@
1
- {"version":3,"file":"command-registry.d.ts","sourceRoot":"","sources":["../src/command-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-registry.d.ts","sourceRoot":"","sources":["../src/command-registry.ts"],"names":[],"mappings":"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"}
@@ -256,6 +256,13 @@ export function extractGlobalCwd(argv) {
256
256
  let cwd;
257
257
  for (let i = 0; i < argv.length; i += 1) {
258
258
  const t = argv[i];
259
+ // Honor the POSIX `--` end-of-options separator (as parseArgs does):
260
+ // everything after it is a literal positional, so a `--cwd` there must not
261
+ // be intercepted. Preserve `--` and the remainder verbatim.
262
+ if (t === '--') {
263
+ rest.push(...argv.slice(i));
264
+ break;
265
+ }
259
266
  if (t === '--cwd') {
260
267
  const next = argv[i + 1];
261
268
  if (next !== undefined && !next.startsWith('-')) {
@@ -277,6 +284,83 @@ export function extractGlobalCwd(argv) {
277
284
  cwd = nodePath.resolve(process.cwd(), cwd);
278
285
  return cwd === undefined ? { rest } : { cwd, rest };
279
286
  }
287
+ /**
288
+ * Extracts the global output-compression flags from anywhere in argv:
289
+ * `--compress` / `--ccr` (synonyms; turn it on) plus optional
290
+ * `--compress-type <t>` and `--compress-query <q>`. Returns the directive (when
291
+ * any was present) and the remaining argv with those flags removed — so the
292
+ * underlying command can be re-run cleanly without them (and never recurses).
293
+ */
294
+ export function extractGlobalCompress(argv) {
295
+ const rest = [];
296
+ let active = false;
297
+ let type;
298
+ let query;
299
+ const valued = (token, flag, set, i) => {
300
+ if (token === flag) {
301
+ const next = argv[i + 1];
302
+ if (next !== undefined && !next.startsWith('-')) {
303
+ set(next);
304
+ return true; // caller skips next
305
+ }
306
+ return false;
307
+ }
308
+ return false;
309
+ };
310
+ for (let i = 0; i < argv.length; i += 1) {
311
+ const t = argv[i];
312
+ // Honor the POSIX `--` end-of-options separator exactly as parseArgs does:
313
+ // everything after it is a literal positional, so a compress-flag-shaped
314
+ // token there must NOT be intercepted (and the next token must not be
315
+ // swallowed as a value). Preserve `--` and the remainder verbatim for the
316
+ // child to re-parse.
317
+ if (t === '--') {
318
+ rest.push(...argv.slice(i));
319
+ break;
320
+ }
321
+ if (t === '--compress' || t === '--ccr') {
322
+ active = true;
323
+ continue;
324
+ }
325
+ if (t.startsWith('--compress-type=')) {
326
+ type = t.slice('--compress-type='.length);
327
+ active = true;
328
+ continue;
329
+ }
330
+ if (t.startsWith('--compress-query=')) {
331
+ query = t.slice('--compress-query='.length);
332
+ active = true;
333
+ continue;
334
+ }
335
+ if (t === '--compress-type') {
336
+ if (valued(t, '--compress-type', (v) => (type = v), i)) {
337
+ active = true;
338
+ i += 1;
339
+ continue;
340
+ }
341
+ active = true;
342
+ continue;
343
+ }
344
+ if (t === '--compress-query') {
345
+ if (valued(t, '--compress-query', (v) => (query = v), i)) {
346
+ active = true;
347
+ i += 1;
348
+ continue;
349
+ }
350
+ active = true;
351
+ continue;
352
+ }
353
+ rest.push(t);
354
+ }
355
+ if (!active)
356
+ return { rest };
357
+ const directive = {};
358
+ if (type !== undefined)
359
+ directive.type = type;
360
+ if (query !== undefined)
361
+ directive.query = query;
362
+ return { directive, rest };
363
+ }
280
364
  /**
281
365
  * Returns the absolute cwd for the current command:
282
366
  * 1. Command-level --cwd flag (if passed after the command)
@@ -1 +1 @@
1
- {"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../src/commands/apply.command.ts"],"names":[],"mappings":"AAqDA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAyLhC,eAAO,MAAM,YAAY,EAAE,eAyrB1B,CAAC"}
1
+ {"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../src/commands/apply.command.ts"],"names":[],"mappings":"AAqDA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAyLhC,eAAO,MAAM,YAAY,EAAE,eAisB1B,CAAC"}
@@ -179,7 +179,7 @@ async function runApplyBatchFromCli(args, batchPath) {
179
179
  export const applyCommand = {
180
180
  name: 'apply',
181
181
  description: 'Apply a previously-saved generation plan (sharkcraft.plan/v1 JSON). The CLI is the only write path; MCP never writes. Plans that live under .sharkcraft/sessions/<id>/plans/ automatically update the session metadata (signature + divergence + applied + validation).',
182
- usage: 'shrk [--cwd <dir>] apply <plan.json> [--session <id>] [--force] [--allow-divergent] [--verify-signature] [--require-signature] [--dry-run] [--validate] [--report] [--json] [--trace] [--explain-dispatch] | shrk apply --asset-preview <draft.ts> --target <file> [--write] [--allow-unknown-target] [--reason <text>] | shrk apply --batch <plan.json> [--allow-divergent] [--dry-run] [--json]',
182
+ usage: 'shrk [--cwd <dir>] apply <plan.json> [--session <id>] [--force] [--allow-divergent] [--verify-signature] [--require-signature] [--no-verify-signature] [--dry-run] [--validate] [--report] [--json] [--trace] [--explain-dispatch] | shrk apply --asset-preview <draft.ts> --target <file> [--write] [--allow-unknown-target] [--reason <text>] | shrk apply --batch <plan.json> [--allow-divergent] [--dry-run] [--json]',
183
183
  async run(args) {
184
184
  // Asset-preview flow: paste-with-review for authoring drafts.
185
185
  // Distinct from the plan-based apply path: takes a TS draft and a
@@ -222,7 +222,15 @@ export const applyCommand = {
222
222
  const explainOnly = flagBool(args, 'explain-dispatch');
223
223
  let signatureStatus = DevSessionSignatureStatus.NotChecked;
224
224
  let signatureMessage;
225
- if (verifySig) {
225
+ // A plan that CARRIES a signature self-enforces verification: the signature
226
+ // is the producer's tamper-evidence declaration, so a signed plan must not
227
+ // apply unverified just because the caller forgot --verify-signature
228
+ // (contract: "Apply requires --verify-signature for signed plans"). A
229
+ // tampered/invalid signature then refuses below. `--no-verify-signature` is
230
+ // the explicit escape hatch for sign-here / apply-there-without-the-secret.
231
+ const isSigned = Boolean(saved.signature);
232
+ const skipSig = flagBool(args, 'no-verify-signature') && !verifySig;
233
+ if (verifySig || (isSigned && !skipSig)) {
226
234
  const result = verifyPlan(saved);
227
235
  if (result.ok === true) {
228
236
  signatureStatus = DevSessionSignatureStatus.Verified;
@@ -0,0 +1,12 @@
1
+ import { type ICommandHandler } from '../command-registry.js';
2
+ /**
3
+ * `shrk align` — replace volatile tokens (UUIDs/JWTs/timestamps/hashes) with
4
+ * stable placeholders so a provider KV-cache prefix stays steady across turns.
5
+ * Aligned text → stdout; the reversible map is written to `--map <path>` (or
6
+ * `.sharkcraft/cache-align/align.json`). Pass an existing `--map` to carry
7
+ * ordinals forward. `shrk unalign` restores.
8
+ */
9
+ export declare const alignCommand: ICommandHandler;
10
+ /** `shrk unalign` — the restore half: turn placeholders back into originals. */
11
+ export declare const unalignCommand: ICommandHandler;
12
+ //# sourceMappingURL=cache-align.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-align.command.d.ts","sourceRoot":"","sources":["../../src/commands/cache-align.command.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkBhC;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,eA4B1B,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,cAAc,EAAE,eAuB5B,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ import { alignVolatileTokens, restoreVolatileTokens, } from '@shrkcrft/compress';
4
+ import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
5
+ import { asJson } from "../output/format-output.js";
6
+ function readInput(args) {
7
+ const positional = args.positional[0];
8
+ const useStdin = flagBool(args, 'stdin') || positional === undefined || positional === '-';
9
+ return useStdin ? readFileSync(0, 'utf8') : readFileSync(positional, 'utf8');
10
+ }
11
+ function loadMap(path) {
12
+ if (!path || !existsSync(path))
13
+ return undefined;
14
+ const parsed = JSON.parse(readFileSync(path, 'utf8'));
15
+ if (typeof parsed === 'object' && parsed !== null && Array.isArray(parsed.bindings)) {
16
+ return parsed;
17
+ }
18
+ return undefined;
19
+ }
20
+ /**
21
+ * `shrk align` — replace volatile tokens (UUIDs/JWTs/timestamps/hashes) with
22
+ * stable placeholders so a provider KV-cache prefix stays steady across turns.
23
+ * Aligned text → stdout; the reversible map is written to `--map <path>` (or
24
+ * `.sharkcraft/cache-align/align.json`). Pass an existing `--map` to carry
25
+ * ordinals forward. `shrk unalign` restores.
26
+ */
27
+ export const alignCommand = {
28
+ name: 'align',
29
+ description: 'Replace volatile tokens with stable placeholders for KV-cache prefix stability; reversible via `shrk unalign`.',
30
+ usage: 'shrk [--cwd <dir>] align [<file>|-] [--stdin] [--map <path>] [--json]',
31
+ run(args) {
32
+ const cwd = resolveCwd(args);
33
+ let content;
34
+ try {
35
+ content = readInput(args);
36
+ }
37
+ catch (e) {
38
+ process.stderr.write(`align: cannot read input — ${e.message}\n`);
39
+ return 1;
40
+ }
41
+ const mapPath = flagString(args, 'map') ?? nodePath.join(cwd, '.sharkcraft', 'cache-align', 'align.json');
42
+ const result = alignVolatileTokens(content, loadMap(mapPath));
43
+ mkdirSync(nodePath.dirname(mapPath), { recursive: true });
44
+ writeFileSync(mapPath, JSON.stringify(result.map, null, 2), 'utf8');
45
+ if (flagBool(args, 'json')) {
46
+ process.stdout.write(asJson({ aligned: result.aligned, map: result.map, replaced: result.replaced }) + '\n');
47
+ return 0;
48
+ }
49
+ process.stdout.write(result.aligned + '\n');
50
+ process.stderr.write(`aligned: ${result.replaced} token(s) replaced · map → ${mapPath}\n`);
51
+ return 0;
52
+ },
53
+ };
54
+ /** `shrk unalign` — the restore half: turn placeholders back into originals. */
55
+ export const unalignCommand = {
56
+ name: 'unalign',
57
+ description: 'Restore the original volatile tokens in aligned text using its `--map`.',
58
+ usage: 'shrk [--cwd <dir>] unalign [<file>|-] [--stdin] --map <path>',
59
+ run(args) {
60
+ const cwd = resolveCwd(args);
61
+ const mapPath = flagString(args, 'map') ?? nodePath.join(cwd, '.sharkcraft', 'cache-align', 'align.json');
62
+ const map = loadMap(mapPath);
63
+ if (!map) {
64
+ process.stderr.write(`unalign: no alignment map at "${mapPath}" (pass --map <path>).\n`);
65
+ return 1;
66
+ }
67
+ let content;
68
+ try {
69
+ content = readInput(args);
70
+ }
71
+ catch (e) {
72
+ process.stderr.write(`unalign: cannot read input — ${e.message}\n`);
73
+ return 1;
74
+ }
75
+ process.stdout.write(restoreVolatileTokens(content, map) + '\n');
76
+ return 0;
77
+ },
78
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/command-catalog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/command-catalog.ts"],"names":[],"mappings":"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"}
@@ -1495,6 +1495,48 @@ export const COMMAND_CATALOG = Object.freeze([
1495
1495
  intendedAudience: [CommandAudience.Human, CommandAudience.Ci],
1496
1496
  taskRole: CommandTaskRole.Inspect,
1497
1497
  }),
1498
+ entry({
1499
+ command: 'compress',
1500
+ description: 'Deterministically compress a blob (file or stdin) to cut tokens — JSON→table, logs/search/diffs→signal. Reversible via `shrk expand`.',
1501
+ category: 'core',
1502
+ safetyLevel: SafetyLevel.WritesSessionOnly,
1503
+ writesFiles: true,
1504
+ mcpAvailable: true,
1505
+ surface: CommandSurface.Common,
1506
+ intendedAudience: [CommandAudience.Agent, CommandAudience.Human],
1507
+ taskRole: CommandTaskRole.Context,
1508
+ }),
1509
+ entry({
1510
+ command: 'expand',
1511
+ description: 'Retrieve the full original a `shrk compress` run cached, by its `<<ccr:KEY>>` key.',
1512
+ category: 'core',
1513
+ safetyLevel: SafetyLevel.ReadOnly,
1514
+ mcpAvailable: true,
1515
+ surface: CommandSurface.Common,
1516
+ intendedAudience: [CommandAudience.Agent, CommandAudience.Human],
1517
+ taskRole: CommandTaskRole.Context,
1518
+ }),
1519
+ entry({
1520
+ command: 'align',
1521
+ description: 'Replace volatile tokens (UUIDs/JWTs/timestamps/hashes) with stable placeholders for KV-cache prefix stability; reversible via `shrk unalign`.',
1522
+ category: 'core',
1523
+ safetyLevel: SafetyLevel.WritesSessionOnly,
1524
+ writesFiles: true,
1525
+ mcpAvailable: true,
1526
+ surface: CommandSurface.Advanced,
1527
+ intendedAudience: [CommandAudience.Agent, CommandAudience.Human],
1528
+ taskRole: CommandTaskRole.Context,
1529
+ }),
1530
+ entry({
1531
+ command: 'unalign',
1532
+ description: 'Restore the original volatile tokens in aligned text using its `--map`.',
1533
+ category: 'core',
1534
+ safetyLevel: SafetyLevel.ReadOnly,
1535
+ mcpAvailable: true,
1536
+ surface: CommandSurface.Advanced,
1537
+ intendedAudience: [CommandAudience.Agent, CommandAudience.Human],
1538
+ taskRole: CommandTaskRole.Context,
1539
+ }),
1498
1540
  // ── Backend feature expansion ─────────────────────────────────────────
1499
1541
  entry({
1500
1542
  command: 'bundle create',
@@ -3360,6 +3402,8 @@ const PRIMARY_VERBS_ALLOWLIST = new Set([
3360
3402
  'impact',
3361
3403
  'graph',
3362
3404
  'code-intel',
3405
+ 'compress',
3406
+ 'expand',
3363
3407
  // Generate code safely
3364
3408
  'gen',
3365
3409
  'apply',
@@ -0,0 +1,15 @@
1
+ import { type ICommandHandler } from '../command-registry.js';
2
+ /**
3
+ * `shrk compress` — deterministically compress a blob (file or stdin) before
4
+ * it re-enters an agent prompt. Same information, fewer tokens. Lossy passes
5
+ * cache the original under `.sharkcraft/ccr/` so `shrk expand <key>` can get
6
+ * it back. The compressed text goes to stdout (pipeable); the savings summary
7
+ * goes to stderr unless `--json` is set.
8
+ */
9
+ export declare const compressCommand: ICommandHandler;
10
+ /**
11
+ * `shrk expand` — the retrieve half of CCR. Print the full original that
12
+ * `shrk compress` cached for a `<<ccr:KEY>>` key.
13
+ */
14
+ export declare const expandCommand: ICommandHandler;
15
+ //# sourceMappingURL=compress.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compress.command.d.ts","sourceRoot":"","sources":["../../src/commands/compress.command.ts"],"names":[],"mappings":"AAQA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAahC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,eA+E7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,eA4B3B,CAAC"}
@@ -0,0 +1,126 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { Buffer } from 'node:buffer';
3
+ import { compressContent, ECompressionStrategy, EContentType, } from '@shrkcrft/compress';
4
+ import { flagBool, flagNumber, flagString, resolveCwd, } from "../command-registry.js";
5
+ import { asJson } from "../output/format-output.js";
6
+ import { ccrDir, openCcrStore } from "../output/ccr-store-config.js";
7
+ const CONTENT_TYPES = new Set(Object.values(EContentType));
8
+ function readInput(args) {
9
+ const positional = args.positional[0];
10
+ const useStdin = flagBool(args, 'stdin') || positional === undefined || positional === '-';
11
+ if (useStdin)
12
+ return readFileSync(0, 'utf8');
13
+ return readFileSync(positional, 'utf8');
14
+ }
15
+ /**
16
+ * `shrk compress` — deterministically compress a blob (file or stdin) before
17
+ * it re-enters an agent prompt. Same information, fewer tokens. Lossy passes
18
+ * cache the original under `.sharkcraft/ccr/` so `shrk expand <key>` can get
19
+ * it back. The compressed text goes to stdout (pipeable); the savings summary
20
+ * goes to stderr unless `--json` is set.
21
+ */
22
+ export const compressCommand = {
23
+ name: 'compress',
24
+ description: 'Compress a blob (file or stdin) deterministically to cut tokens — JSON→table, logs/search/diffs→signal. Reversible via `shrk expand`.',
25
+ usage: 'shrk [--cwd <dir>] compress [<file>|-] [--stdin] [--type <content-type>] [--query <text>] [--max <n>] [--lossless] [--no-cache] [--json]',
26
+ run(args) {
27
+ const cwd = resolveCwd(args);
28
+ let content;
29
+ try {
30
+ content = readInput(args);
31
+ }
32
+ catch (e) {
33
+ process.stderr.write(`compress: cannot read input — ${e.message}\n`);
34
+ return 1;
35
+ }
36
+ if (content.length === 0) {
37
+ process.stderr.write('compress: empty input.\n');
38
+ return 1;
39
+ }
40
+ const opts = {};
41
+ if (!flagBool(args, 'no-cache'))
42
+ opts.store = openCcrStore(cwd);
43
+ const query = flagString(args, 'query');
44
+ if (query)
45
+ opts.query = query;
46
+ const max = flagNumber(args, 'max');
47
+ if (max !== undefined && max > 0)
48
+ opts.maxItems = Math.floor(max);
49
+ if (flagBool(args, 'lossless'))
50
+ opts.lossless = true;
51
+ const type = flagString(args, 'type');
52
+ if (type && CONTENT_TYPES.has(type))
53
+ opts.contentType = type;
54
+ const result = compressContent(content, opts);
55
+ const pct = Math.round(result.savings.ratio * 100);
56
+ // A lossy result with no cached original (i.e. --no-cache) can't be undone
57
+ // by `shrk expand`. Warn so the dropped detail isn't lost silently.
58
+ if (result.lossy && !result.ccrKey) {
59
+ process.stderr.write('warning: compressed lossily but the original was NOT cached (--no-cache) — ' +
60
+ 'detail is unrecoverable; omit --no-cache to keep it retrievable via `shrk expand`.\n');
61
+ }
62
+ const queryApplied = query !== undefined && query.length > 0;
63
+ if (flagBool(args, 'json')) {
64
+ // tokens are a deterministic ESTIMATE (chars/divisor heuristic), not a
65
+ // real BPE count — flagged so callers don't treat savedRatio as exact.
66
+ const base = {
67
+ contentType: result.contentType,
68
+ strategy: result.strategy,
69
+ lossy: result.lossy,
70
+ tokensBefore: result.savings.before,
71
+ tokensAfter: result.savings.after,
72
+ tokensSaved: result.savings.saved,
73
+ savedRatio: result.savings.ratio,
74
+ tokensAreEstimated: true,
75
+ queryApplied,
76
+ ccrKey: result.ccrKey ?? null,
77
+ note: result.note,
78
+ };
79
+ // Net-loss guard: on a passthrough/no-win blob the engine returns the
80
+ // VERBATIM original as `compressed`. Echoing it back inside the JSON
81
+ // envelope (plus scaffold) costs more tokens than the input. Signal
82
+ // passthrough and omit the duplicated content — the caller still has it.
83
+ const noWin = result.strategy === ECompressionStrategy.Passthrough || result.savings.saved <= 0;
84
+ const payload = noWin
85
+ ? { ...base, passthrough: true, inputBytes: Buffer.byteLength(content, 'utf8') }
86
+ : { ...base, compressed: result.compressed };
87
+ process.stdout.write(asJson(payload) + '\n');
88
+ return 0;
89
+ }
90
+ process.stdout.write(result.compressed + '\n');
91
+ const cached = result.ccrKey ? ` · original cached as ${result.ccrKey} (shrk expand ${result.ccrKey})` : '';
92
+ process.stderr.write(`${result.strategy}: ~${result.savings.before} → ~${result.savings.after} tokens (−${pct}%, est.)${cached}\n`);
93
+ return 0;
94
+ },
95
+ };
96
+ /**
97
+ * `shrk expand` — the retrieve half of CCR. Print the full original that
98
+ * `shrk compress` cached for a `<<ccr:KEY>>` key.
99
+ */
100
+ export const expandCommand = {
101
+ name: 'expand',
102
+ description: 'Retrieve the full original a `shrk compress` run cached, by its `<<ccr:KEY>>` key.',
103
+ usage: 'shrk [--cwd <dir>] expand <key> [--json]',
104
+ run(args) {
105
+ const cwd = resolveCwd(args);
106
+ const key = (args.positional[0] ?? '').trim();
107
+ if (key.length === 0) {
108
+ process.stderr.write('expand: a CCR key is required (e.g. `shrk expand a1b2c3d4e5f60718`).\n');
109
+ return 1;
110
+ }
111
+ const store = openCcrStore(cwd);
112
+ const entry = store.get(key);
113
+ if (!entry) {
114
+ process.stderr.write(`expand: no cached original for key "${key}" under ${ccrDir(cwd)}.\n`);
115
+ return 1;
116
+ }
117
+ if (flagBool(args, 'json')) {
118
+ process.stdout.write(asJson({ key: entry.key, bytes: entry.bytes, content: entry.content }) + '\n');
119
+ return 0;
120
+ }
121
+ // Write the cached original VERBATIM — appending a newline broke byte-for-byte
122
+ // round-trip (`compress … ; expand` must reproduce the input exactly).
123
+ process.stdout.write(entry.content);
124
+ return 0;
125
+ },
126
+ };
@@ -256,6 +256,10 @@ function rootOfSpecifier(spec) {
256
256
  function isBuiltinModule(spec) {
257
257
  if (spec.startsWith('node:'))
258
258
  return true;
259
+ // Bun runtime builtins (`bun:test`, `bun:sqlite`, `bun:ffi`, …) are provided by
260
+ // the runtime, never an npm dependency — so they are not "missing".
261
+ if (spec.startsWith('bun:'))
262
+ return true;
259
263
  // Common bare-name builtins.
260
264
  return new Set([
261
265
  'fs', 'path', 'os', 'crypto', 'http', 'https', 'url', 'util', 'stream',
@@ -1 +1 @@
1
- {"version":3,"file":"dev.command.d.ts","sourceRoot":"","sources":["../../src/commands/dev.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA67ChC,eAAO,MAAM,UAAU,EAAE,eAkExB,CAAC"}
1
+ {"version":3,"file":"dev.command.d.ts","sourceRoot":"","sources":["../../src/commands/dev.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAi8ChC,eAAO,MAAM,UAAU,EAAE,eAkExB,CAAC"}
@@ -672,7 +672,11 @@ async function validateSession(args) {
672
672
  const allVerifications = flagBool(args, 'all-verifications');
673
673
  const allowPackCommands = flagBool(args, 'allow-pack-commands');
674
674
  const wantStrict = flagBool(args, 'strict');
675
- const wantReport = flagBool(args, 'report') !== false; // default: write report
675
+ // flagBool is two-valued (absent → false), so `flagBool(...) !== false` is
676
+ // false when the flag is absent — the opposite of the intended default. Read
677
+ // the raw value: write the report by default, opt out only via --report=false.
678
+ const reportFlag = args.flags.get('report');
679
+ const wantReport = reportFlag !== false && reportFlag !== 'false';
676
680
  const wantJson = flagBool(args, 'json');
677
681
  const startedAt = new Date().toISOString();
678
682
  const reportFileName = `validate-${startedAt.replace(/[:.]/g, '-')}.json`;
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-api-server.d.ts","sourceRoot":"","sources":["../../src/dashboard/dashboard-api-server.ts"],"names":[],"mappings":"AAiEA,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AA2BD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAqC1F;AAqlBD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"dashboard-api-server.d.ts","sourceRoot":"","sources":["../../src/dashboard/dashboard-api-server.ts"],"names":[],"mappings":"AAuIA,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AA2BD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAqC1F;AA0lBD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC"}
@@ -16,10 +16,70 @@ import * as fs from 'node:fs';
16
16
  import { existsSync, readFileSync, statSync } from 'node:fs';
17
17
  import * as nodePath from 'node:path';
18
18
  import { buildDashboardAdoption, buildDashboardArchitecture, buildDashboardBoundaries, buildDashboardCapabilities, buildDashboardCommands, buildDashboardCoverage, buildDashboardDoctor, buildDashboardDrift, buildDashboardGraph, buildDashboardGraphNode, buildDashboardGraphPath, buildDashboardHealth, buildDashboardKnowledgeList, buildDashboardKnowledgeEntry, buildDashboardKnowledgeGraph, buildDashboardKnowledgeSimilar, buildDashboardMcpSummary, buildDashboardOnboarding, buildDashboardOverview, buildDashboardPacks, buildDashboardPipelines, buildDashboardPresets, buildDashboardQuality, buildDashboardReports, buildDashboardReview, buildDashboardSafety, buildDashboardScaffolds, buildDashboardSchemas, buildDashboardSessionDetail, buildDashboardSessions, buildDashboardStats, inspectSharkcraft, renderDevSessionHtml, scanDevSession, } from '@shrkcrft/inspector';
19
+ import { EContentType, compactArrayToColumnar, estimateTokens } from '@shrkcrft/compress';
19
20
  import { COMMAND_CATALOG } from "../commands/command-catalog.js";
20
21
  import { buildDashboardCodeIntelligence, buildDashboardMigrations, buildDashboardQualityGates, buildDashboardRoutes, } from "./code-intelligence-data.js";
21
22
  import { buildKnowledgeAsk } from "./knowledge-ask.js";
22
23
  const SCHEMA_ID = 'sharkcraft.dashboard-api/v1';
24
+ /**
25
+ * Compute the deterministic compression layer's per-surface token savings for
26
+ * the dashboard. Measured on the live workspace (no timestamps → stable).
27
+ *
28
+ * `realTokens`, when supplied, is an exact BPE tokenizer (cl100k_base); the
29
+ * panel then reports exact counts and flags `tokensAreEstimated: false`. With
30
+ * no tokenizer (the default in a published install, where the dev-only
31
+ * `gpt-tokenizer` is absent) it falls back to the engine's estimator — whose
32
+ * *percentages* are sound but whose *absolutes* are rough — and flags
33
+ * `tokensAreEstimated: true` so the UI never presents an estimate as exact.
34
+ */
35
+ function buildDashboardCompression(inspection, realTokens) {
36
+ const graph = buildDashboardKnowledgeGraph(inspection);
37
+ // Both encodings are JSON, so when estimating, score them with the JSON
38
+ // divisor — the same ratio the engine uses — for the closest absolute counts.
39
+ const count = (text) => realTokens ? realTokens(text) : estimateTokens(text, EContentType.Json);
40
+ const surfaces = [];
41
+ const add = (surface, strategy, beforeText, afterText) => {
42
+ const before = count(beforeText);
43
+ // Net-loss guard: columnar/legend overhead can exceed the raw encoding on
44
+ // tiny arrays. The engine ships whichever is smaller, so report what the
45
+ // agent actually pays — never a negative saving.
46
+ const after = Math.min(count(afterText), before);
47
+ surfaces.push({ surface, strategy, before, after, savedPct: before > 0 ? Math.round((1 - after / before) * 100) : 0 });
48
+ };
49
+ const nodes = [...graph.nodes];
50
+ const edges = [...graph.edges];
51
+ add('knowledge graph', 'columnar table', JSON.stringify({ nodes, edges }), JSON.stringify({ nodes: compactArrayToColumnar(nodes) ?? nodes, edges: compactArrayToColumnar(edges) ?? edges }));
52
+ add('knowledge nodes', 'columnar table', JSON.stringify(nodes), JSON.stringify(compactArrayToColumnar(nodes) ?? nodes));
53
+ const totalsBefore = surfaces.reduce((s, x) => s + x.before, 0);
54
+ const totalsAfter = surfaces.reduce((s, x) => s + x.after, 0);
55
+ return {
56
+ surfaces,
57
+ totals: {
58
+ before: totalsBefore,
59
+ after: totalsAfter,
60
+ savedPct: totalsBefore > 0 ? Math.round((1 - totalsAfter / totalsBefore) * 100) : 0,
61
+ },
62
+ tokensAreEstimated: !realTokens,
63
+ };
64
+ }
65
+ /**
66
+ * Best-effort load of the optional dev tokenizer for exact dashboard counts.
67
+ * Guarded dynamic import: `gpt-tokenizer` is not a runtime dependency of the
68
+ * CLI, so this resolves to `undefined` in any install that did not ship it, and
69
+ * the dashboard transparently falls back to the estimator.
70
+ */
71
+ async function loadDashboardTokenizer() {
72
+ try {
73
+ const mod = (await import('gpt-tokenizer'));
74
+ if (typeof mod.encode !== 'function')
75
+ return undefined;
76
+ const encode = mod.encode;
77
+ return (text) => (text ? encode(text).length : 0);
78
+ }
79
+ catch {
80
+ return undefined;
81
+ }
82
+ }
23
83
  export async function startDashboardApiServer(opts) {
24
84
  const host = opts.host ?? '127.0.0.1';
25
85
  const port = opts.port ?? 0;
@@ -328,6 +388,7 @@ async function handle(req, res, ctx) {
328
388
  path.startsWith('/api/knowledge') ||
329
389
  path.startsWith('/api/onboarding') ||
330
390
  path.startsWith('/api/review') ||
391
+ path.startsWith('/api/compression') ||
331
392
  path.startsWith('/api/scaffolds');
332
393
  const inspection = needsInspection
333
394
  ? await inspectSharkcraft({ cwd: projectRoot })
@@ -347,6 +408,10 @@ async function handle(req, res, ctx) {
347
408
  if (path === '/api/packs') {
348
409
  return respond(res, buildEnvelope(projectRoot, buildDashboardPacks(inspection)));
349
410
  }
411
+ if (path === '/api/compression') {
412
+ const realTokens = await loadDashboardTokenizer();
413
+ return respond(res, buildEnvelope(projectRoot, buildDashboardCompression(inspection, realTokens)));
414
+ }
350
415
  if (path === '/api/presets') {
351
416
  return respond(res, buildEnvelope(projectRoot, buildDashboardPresets(inspection)));
352
417
  }
package/dist/index.d.ts CHANGED
@@ -17,6 +17,9 @@ export { packsListCommand, packsGetCommand, packsInspectCommand, packsDoctorComm
17
17
  export { pipelinesListCommand, pipelinesGetCommand, pipelinesContextCommand, pipelinesPlanCommand, pipelinesScriptCommand, pipelinesNextCommand, } from './commands/pipelines.command.js';
18
18
  export { schemasListCommand, schemasGetCommand, schemasWriteCommand, } from './commands/schemas.command.js';
19
19
  export { versionCommand } from './commands/version.command.js';
20
+ export { compressCommand, expandCommand } from './commands/compress.command.js';
21
+ export { alignCommand, unalignCommand } from './commands/cache-align.command.js';
20
22
  export { makeHelpCommand } from './commands/help.command.js';
21
23
  export { buildRegistry, runCli } from './main.js';
24
+ export { buildWatchPlan, maybeRunInWatchMode, runWatchLoop, } from './output/watch-loop.js';
22
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -17,5 +17,8 @@ export { packsListCommand, packsGetCommand, packsInspectCommand, packsDoctorComm
17
17
  export { pipelinesListCommand, pipelinesGetCommand, pipelinesContextCommand, pipelinesPlanCommand, pipelinesScriptCommand, pipelinesNextCommand, } from "./commands/pipelines.command.js";
18
18
  export { schemasListCommand, schemasGetCommand, schemasWriteCommand, } from "./commands/schemas.command.js";
19
19
  export { versionCommand } from "./commands/version.command.js";
20
+ export { compressCommand, expandCommand } from "./commands/compress.command.js";
21
+ export { alignCommand, unalignCommand } from "./commands/cache-align.command.js";
20
22
  export { makeHelpCommand } from "./commands/help.command.js";
21
23
  export { buildRegistry, runCli } from "./main.js";
24
+ export { buildWatchPlan, maybeRunInWatchMode, runWatchLoop, } from "./output/watch-loop.js";
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAuX/B,wBAAgB,aAAa,IAAI,eAAe,CA2X/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BrE;AAoHD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CA4CxE"}
package/dist/main.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { loadDotenv } from "./env/load-dotenv.js";
3
- import { CommandRegistry, extractGlobalCwd, parseArgs, } from "./command-registry.js";
3
+ import { CommandRegistry, extractGlobalCompress, extractGlobalCwd, parseArgs, } from "./command-registry.js";
4
+ import { runCommandWithCompression } from "./output/output-compression.js";
4
5
  import { initCommand } from "./commands/init.command.js";
5
6
  import { inspectCommand } from "./commands/inspect.command.js";
6
7
  import { doctorAcknowledgeCommand, doctorAcknowledgementsCommand, doctorCommand, doctorSuppressCommand, doctorSuppressionsCommand, } from "./commands/doctor.command.js";
@@ -34,6 +35,8 @@ import { gateCommand } from "./commands/gate.command.js";
34
35
  import { migrateCommand } from "./commands/migrate.command.js";
35
36
  import { coverageCommand } from "./commands/coverage.command.js";
36
37
  import { statsCommand } from "./commands/stats.command.js";
38
+ import { compressCommand, expandCommand } from "./commands/compress.command.js";
39
+ import { alignCommand, unalignCommand } from "./commands/cache-align.command.js";
37
40
  import { reviewCommand } from "./commands/review.command.js";
38
41
  import { onboardCommand } from "./commands/onboard.command.js";
39
42
  import { contradictionsCommand, generatedCommand, ingestCommand, } from "./commands/ingest.command.js";
@@ -196,6 +199,10 @@ export function buildRegistry() {
196
199
  registry.register(migrateCommand);
197
200
  registry.register(coverageCommand);
198
201
  registry.register(statsCommand);
202
+ registry.register(compressCommand);
203
+ registry.register(expandCommand);
204
+ registry.register(alignCommand);
205
+ registry.register(unalignCommand);
199
206
  registry.register(reviewCommand);
200
207
  registry.register(onboardCommand);
201
208
  registry.register(ingestCommand);
@@ -539,8 +546,23 @@ async function isUsageEnabled(cwd) {
539
546
  async function runCliInner(argv) {
540
547
  const registry = buildRegistry();
541
548
  // Pre-parse the global --cwd so it can appear anywhere (incl. before the command).
542
- const { cwd: globalCwd, rest: cleanArgv } = extractGlobalCwd(argv);
549
+ const { cwd: globalCwd, rest: cwdCleanArgv } = extractGlobalCwd(argv);
550
+ // Pre-parse the global --compress / --ccr output-compression flags.
551
+ const { directive: compressDirective, rest: cleanArgv } = extractGlobalCompress(cwdCleanArgv);
543
552
  const [first] = cleanArgv;
553
+ // `--compress` / `--ccr` on a real command: re-run it and compress its stdout.
554
+ // (Meta verbs like --help/--version and bare invocations are left untouched.)
555
+ if (compressDirective &&
556
+ first &&
557
+ first !== '--help' &&
558
+ first !== '-h' &&
559
+ first !== '--full-help' &&
560
+ first !== '--version' &&
561
+ first !== '-v' &&
562
+ first !== '--about') {
563
+ const childArgv = globalCwd ? ['--cwd', globalCwd, ...cleanArgv] : [...cleanArgv];
564
+ return runCommandWithCompression(childArgv, compressDirective, globalCwd ?? process.cwd());
565
+ }
544
566
  // bare invocation lands on the curated tiered view.
545
567
  if (!first) {
546
568
  const landing = await renderNoArgsLanding(globalCwd ?? process.cwd());
@@ -0,0 +1,18 @@
1
+ import { TtlFileCcrStore } from '@shrkcrft/compress';
2
+ /**
3
+ * Upper bound on cached CCR originals under `.sharkcraft/ccr/`. The store evicts
4
+ * the oldest entries past this on every `put`, so the compress cache stays
5
+ * bounded instead of growing without limit (the old `FileCcrStore` had no cap).
6
+ * Count-based (not time-based) so a previously-cached key never silently
7
+ * expires out from under a `shrk expand` until it is genuinely the oldest and
8
+ * the cap is exceeded.
9
+ */
10
+ export declare const CCR_MAX_ENTRIES = 1000;
11
+ /** Absolute path to the per-workspace CCR cache directory. */
12
+ export declare function ccrDir(cwd: string): string;
13
+ /**
14
+ * Open the bounded, cross-process CCR store the CLI write/read paths share.
15
+ * `ttlMs: 0` means no time expiry; `maxEntries` is the only bound.
16
+ */
17
+ export declare function openCcrStore(cwd: string): TtlFileCcrStore;
18
+ //# sourceMappingURL=ccr-store-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ccr-store-config.d.ts","sourceRoot":"","sources":["../../src/output/ccr-store-config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,8DAA8D;AAC9D,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAEzD"}
@@ -0,0 +1,22 @@
1
+ import * as nodePath from 'node:path';
2
+ import { TtlFileCcrStore } from '@shrkcrft/compress';
3
+ /**
4
+ * Upper bound on cached CCR originals under `.sharkcraft/ccr/`. The store evicts
5
+ * the oldest entries past this on every `put`, so the compress cache stays
6
+ * bounded instead of growing without limit (the old `FileCcrStore` had no cap).
7
+ * Count-based (not time-based) so a previously-cached key never silently
8
+ * expires out from under a `shrk expand` until it is genuinely the oldest and
9
+ * the cap is exceeded.
10
+ */
11
+ export const CCR_MAX_ENTRIES = 1000;
12
+ /** Absolute path to the per-workspace CCR cache directory. */
13
+ export function ccrDir(cwd) {
14
+ return nodePath.join(cwd, '.sharkcraft', 'ccr');
15
+ }
16
+ /**
17
+ * Open the bounded, cross-process CCR store the CLI write/read paths share.
18
+ * `ttlMs: 0` means no time expiry; `maxEntries` is the only bound.
19
+ */
20
+ export function openCcrStore(cwd) {
21
+ return new TtlFileCcrStore(ccrDir(cwd), { maxEntries: CCR_MAX_ENTRIES });
22
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"format-output.d.ts","sourceRoot":"","sources":["../../src/output/format-output.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAG3F;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7C;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,CAWlE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
1
+ {"version":3,"file":"format-output.d.ts","sourceRoot":"","sources":["../../src/output/format-output.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAG3F;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAO7C;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,CAWlE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
@@ -9,7 +9,12 @@ export function kv(key, value) {
9
9
  return ` ${key.padEnd(18)} ${v}`;
10
10
  }
11
11
  export function asJson(value) {
12
- return JSON.stringify(value, null, 2);
12
+ // Minified by default: `--json` output is for machine / agent consumption, so
13
+ // we emit the smallest valid JSON (mirrors the MCP wire's default). The shape
14
+ // is unchanged — only whitespace is removed — so `JSON.parse` consumers are
15
+ // unaffected. Set SHRK_JSON_PRETTY=1 for human-readable 2-space indentation.
16
+ const pretty = process.env.SHRK_JSON_PRETTY === '1' || process.env.SHRK_JSON_PRETTY === 'true';
17
+ return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);
13
18
  }
14
19
  export function table(rows) {
15
20
  if (rows.length === 0)
@@ -0,0 +1,15 @@
1
+ import type { IGlobalCompressDirective } from '../command-registry.js';
2
+ /**
3
+ * Implements the global `--compress` / `--ccr` flag: run a `shrk` command in a
4
+ * child process, capture its stdout, and emit a deterministically-compressed
5
+ * version (with the original cached for `shrk expand`). The command's own
6
+ * stderr is forwarded verbatim and its exit code is preserved.
7
+ *
8
+ * A SUBPROCESS (not in-process `process.stdout` capture) on purpose: some
9
+ * commands call `process.exit`, which would discard a buffered in-process
10
+ * capture mid-write; re-running the command isolates that and still yields the
11
+ * full output + real exit status. `childArgv` has already had the compress
12
+ * flags stripped, so the child never recurses.
13
+ */
14
+ export declare function runCommandWithCompression(childArgv: readonly string[], directive: IGlobalCompressDirective, cwd: string): number;
15
+ //# sourceMappingURL=output-compression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-compression.d.ts","sourceRoot":"","sources":["../../src/output/output-compression.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAQvE;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,SAAS,EAAE,wBAAwB,EACnC,GAAG,EAAE,MAAM,GACV,MAAM,CAgDR"}
@@ -0,0 +1,60 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { compressContent } from '@shrkcrft/compress';
3
+ import { openCcrStore } from "./ccr-store-config.js";
4
+ import { resolveCompressType } from "./resolve-compress-type.js";
5
+ // Command output can be large (a full knowledge dump, a wide graph). Allow up to
6
+ // 64 MiB of captured stdout before spawnSync gives up.
7
+ const MAX_BUFFER = 64 * 1024 * 1024;
8
+ /**
9
+ * Implements the global `--compress` / `--ccr` flag: run a `shrk` command in a
10
+ * child process, capture its stdout, and emit a deterministically-compressed
11
+ * version (with the original cached for `shrk expand`). The command's own
12
+ * stderr is forwarded verbatim and its exit code is preserved.
13
+ *
14
+ * A SUBPROCESS (not in-process `process.stdout` capture) on purpose: some
15
+ * commands call `process.exit`, which would discard a buffered in-process
16
+ * capture mid-write; re-running the command isolates that and still yields the
17
+ * full output + real exit status. `childArgv` has already had the compress
18
+ * flags stripped, so the child never recurses.
19
+ */
20
+ export function runCommandWithCompression(childArgv, directive, cwd) {
21
+ const runtime = process.argv[0];
22
+ const entry = process.argv[1];
23
+ if (!runtime || !entry) {
24
+ process.stderr.write('--compress: cannot determine the shrk entry point to re-run; emitting uncompressed.\n');
25
+ return 1;
26
+ }
27
+ // Resolve an explicit --compress-type up front so a typo is reported loudly
28
+ // (not silently auto-detected), even if the command ends up printing nothing.
29
+ const resolvedType = resolveCompressType(directive.type);
30
+ if (resolvedType.warning)
31
+ process.stderr.write(`${resolvedType.warning}\n`);
32
+ const res = spawnSync(runtime, [entry, ...childArgv], {
33
+ encoding: 'utf8',
34
+ maxBuffer: MAX_BUFFER,
35
+ env: process.env,
36
+ });
37
+ if (res.error) {
38
+ process.stderr.write(`--compress: failed to run the command (${res.error.message}); emitting nothing.\n`);
39
+ return 1;
40
+ }
41
+ // Forward the command's own stderr (warnings, summaries, errors) untouched.
42
+ if (res.stderr)
43
+ process.stderr.write(res.stderr);
44
+ const captured = res.stdout ?? '';
45
+ const code = res.status ?? (res.signal ? 1 : 0);
46
+ // Nothing on stdout (or the command failed) → don't fabricate output.
47
+ if (captured.length === 0)
48
+ return code;
49
+ const opts = { store: openCcrStore(cwd) };
50
+ if (directive.query)
51
+ opts.query = directive.query;
52
+ if (resolvedType.type)
53
+ opts.contentType = resolvedType.type;
54
+ const result = compressContent(captured, opts);
55
+ process.stdout.write(result.compressed.endsWith('\n') ? result.compressed : `${result.compressed}\n`);
56
+ const pct = Math.round(result.savings.ratio * 100);
57
+ const cached = result.ccrKey ? ` · original cached (shrk expand ${result.ccrKey})` : '';
58
+ process.stderr.write(`[--compress] ${result.strategy}: ~${result.savings.before} → ~${result.savings.after} tokens (−${pct}%, est.)${cached}\n`);
59
+ return code;
60
+ }
@@ -0,0 +1,22 @@
1
+ import { EContentType } from '@shrkcrft/compress';
2
+ /** Outcome of resolving a raw `--compress-type` string. */
3
+ export interface IResolvedCompressType {
4
+ /** The forced content type — set only when the raw value named a valid one. */
5
+ type?: EContentType;
6
+ /**
7
+ * A user-facing warning, set when the raw value was non-empty but
8
+ * unrecognized. The caller surfaces it (on stderr) so an explicit-but-typo'd
9
+ * `--compress-type` is reported rather than silently dropped.
10
+ */
11
+ warning?: string;
12
+ }
13
+ /**
14
+ * Resolve a raw `--compress-type` flag value into a forced {@link EContentType}.
15
+ *
16
+ * An unrecognized, non-empty value is NOT silently ignored (the old behavior):
17
+ * it yields a `warning` listing the valid types, so the caller can tell the
18
+ * user their explicit choice was dropped before falling back to auto-detection.
19
+ * A missing or empty value is a no-op (auto-detect, no warning).
20
+ */
21
+ export declare function resolveCompressType(raw: string | undefined): IResolvedCompressType;
22
+ //# sourceMappingURL=resolve-compress-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-compress-type.d.ts","sourceRoot":"","sources":["../../src/output/resolve-compress-type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKlD,2DAA2D;AAC3D,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,qBAAqB,CAOlF"}
@@ -0,0 +1,21 @@
1
+ import { EContentType } from '@shrkcrft/compress';
2
+ /** The valid `--compress-type` values: the EContentType wire strings. */
3
+ const VALID_TYPES = new Set(Object.values(EContentType));
4
+ /**
5
+ * Resolve a raw `--compress-type` flag value into a forced {@link EContentType}.
6
+ *
7
+ * An unrecognized, non-empty value is NOT silently ignored (the old behavior):
8
+ * it yields a `warning` listing the valid types, so the caller can tell the
9
+ * user their explicit choice was dropped before falling back to auto-detection.
10
+ * A missing or empty value is a no-op (auto-detect, no warning).
11
+ */
12
+ export function resolveCompressType(raw) {
13
+ if (raw === undefined || raw === '')
14
+ return {};
15
+ if (VALID_TYPES.has(raw))
16
+ return { type: raw };
17
+ const valid = [...VALID_TYPES].sort().join(', ');
18
+ return {
19
+ warning: `--compress: unknown --compress-type "${raw}"; auto-detecting instead. Valid types: ${valid}.`,
20
+ };
21
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"run-validation-loop.d.ts","sourceRoot":"","sources":["../../src/validation/run-validation-loop.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2EAA2E;IAC3E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6EAA6E;IAC7E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,wBAAwB,EAAE,CAAC;IACxC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAqGnC"}
1
+ {"version":3,"file":"run-validation-loop.d.ts","sourceRoot":"","sources":["../../src/validation/run-validation-loop.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2EAA2E;IAC3E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6EAA6E;IAC7E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,wBAAwB,EAAE,CAAC;IACxC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAyGnC"}
@@ -25,7 +25,11 @@ export async function runValidationLoop(options) {
25
25
  const ver = cfg?.verificationCommands ?? [];
26
26
  const wantIds = new Set(options.verificationIds);
27
27
  for (const v of ver) {
28
- const shouldRun = options.allVerifications || wantIds.has(v.id);
28
+ // `--all-verifications` auto-runs commands, so it must respect the
29
+ // explicit `trusted: false` opt-out (a command the project marked
30
+ // untrusted must not be executed en masse). An explicit `--verification
31
+ // <id>` still runs it — naming it by id IS the opt-in.
32
+ const shouldRun = (options.allVerifications && v.trusted !== false) || wantIds.has(v.id);
29
33
  if (!shouldRun)
30
34
  continue;
31
35
  commands.push({ id: v.id, command: v.command, trusted: v.trusted !== false });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shrkcrft/cli",
3
- "version": "0.1.0-alpha.15",
3
+ "version": "0.1.0-alpha.17",
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,38 @@
47
47
  "typecheck": "tsc --noEmit -p tsconfig.json"
48
48
  },
49
49
  "dependencies": {
50
- "@shrkcrft/core": "^0.1.0-alpha.15",
51
- "@shrkcrft/config": "^0.1.0-alpha.15",
52
- "@shrkcrft/workspace": "^0.1.0-alpha.15",
53
- "@shrkcrft/knowledge": "^0.1.0-alpha.15",
54
- "@shrkcrft/context": "^0.1.0-alpha.15",
55
- "@shrkcrft/rules": "^0.1.0-alpha.15",
56
- "@shrkcrft/paths": "^0.1.0-alpha.15",
57
- "@shrkcrft/templates": "^0.1.0-alpha.15",
58
- "@shrkcrft/plugin-api": "^0.1.0-alpha.15",
59
- "@shrkcrft/dashboard": "^0.1.0-alpha.15",
60
- "@shrkcrft/dashboard-api": "^0.1.0-alpha.15",
61
- "@shrkcrft/pipelines": "^0.1.0-alpha.15",
62
- "@shrkcrft/presets": "^0.1.0-alpha.15",
63
- "@shrkcrft/boundaries": "^0.1.0-alpha.15",
64
- "@shrkcrft/graph": "^0.1.0-alpha.15",
65
- "@shrkcrft/rule-graph": "^0.1.0-alpha.15",
66
- "@shrkcrft/structural-search": "^0.1.0-alpha.15",
67
- "@shrkcrft/impact-engine": "^0.1.0-alpha.15",
68
- "@shrkcrft/context-planner": "^0.1.0-alpha.15",
69
- "@shrkcrft/architecture-guard": "^0.1.0-alpha.15",
70
- "@shrkcrft/framework-scanners": "^0.1.0-alpha.15",
71
- "@shrkcrft/api-surface-diff": "^0.1.0-alpha.15",
72
- "@shrkcrft/quality-gates": "^0.1.0-alpha.15",
73
- "@shrkcrft/migrate": "^0.1.0-alpha.15",
74
- "@shrkcrft/generator": "^0.1.0-alpha.15",
75
- "@shrkcrft/importer": "^0.1.0-alpha.15",
76
- "@shrkcrft/inspector": "^0.1.0-alpha.15",
77
- "@shrkcrft/ai": "^0.1.0-alpha.15",
78
- "@shrkcrft/embeddings": "^0.1.0-alpha.15",
79
- "@shrkcrft/shared": "^0.1.0-alpha.15",
80
- "@shrkcrft/mcp-server": "^0.1.0-alpha.15",
50
+ "@shrkcrft/core": "^0.1.0-alpha.17",
51
+ "@shrkcrft/compress": "^0.1.0-alpha.17",
52
+ "@shrkcrft/config": "^0.1.0-alpha.17",
53
+ "@shrkcrft/workspace": "^0.1.0-alpha.17",
54
+ "@shrkcrft/knowledge": "^0.1.0-alpha.17",
55
+ "@shrkcrft/context": "^0.1.0-alpha.17",
56
+ "@shrkcrft/rules": "^0.1.0-alpha.17",
57
+ "@shrkcrft/paths": "^0.1.0-alpha.17",
58
+ "@shrkcrft/templates": "^0.1.0-alpha.17",
59
+ "@shrkcrft/plugin-api": "^0.1.0-alpha.17",
60
+ "@shrkcrft/dashboard": "^0.1.0-alpha.17",
61
+ "@shrkcrft/dashboard-api": "^0.1.0-alpha.17",
62
+ "@shrkcrft/pipelines": "^0.1.0-alpha.17",
63
+ "@shrkcrft/presets": "^0.1.0-alpha.17",
64
+ "@shrkcrft/boundaries": "^0.1.0-alpha.17",
65
+ "@shrkcrft/graph": "^0.1.0-alpha.17",
66
+ "@shrkcrft/rule-graph": "^0.1.0-alpha.17",
67
+ "@shrkcrft/structural-search": "^0.1.0-alpha.17",
68
+ "@shrkcrft/impact-engine": "^0.1.0-alpha.17",
69
+ "@shrkcrft/context-planner": "^0.1.0-alpha.17",
70
+ "@shrkcrft/architecture-guard": "^0.1.0-alpha.17",
71
+ "@shrkcrft/framework-scanners": "^0.1.0-alpha.17",
72
+ "@shrkcrft/api-surface-diff": "^0.1.0-alpha.17",
73
+ "@shrkcrft/quality-gates": "^0.1.0-alpha.17",
74
+ "@shrkcrft/migrate": "^0.1.0-alpha.17",
75
+ "@shrkcrft/generator": "^0.1.0-alpha.17",
76
+ "@shrkcrft/importer": "^0.1.0-alpha.17",
77
+ "@shrkcrft/inspector": "^0.1.0-alpha.17",
78
+ "@shrkcrft/ai": "^0.1.0-alpha.17",
79
+ "@shrkcrft/embeddings": "^0.1.0-alpha.17",
80
+ "@shrkcrft/shared": "^0.1.0-alpha.17",
81
+ "@shrkcrft/mcp-server": "^0.1.0-alpha.17",
81
82
  "@huggingface/transformers": "^3.7.5"
82
83
  },
83
84
  "publishConfig": {