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

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.
@@ -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',
@@ -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;AAgBhC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,eAkE7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,eA0B3B,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ import { compressContent, EContentType, FileCcrStore, } from '@shrkcrft/compress';
4
+ import { flagBool, flagNumber, flagString, resolveCwd, } from "../command-registry.js";
5
+ import { asJson } from "../output/format-output.js";
6
+ const CONTENT_TYPES = new Set(Object.values(EContentType));
7
+ function ccrDir(cwd) {
8
+ return nodePath.join(cwd, '.sharkcraft', 'ccr');
9
+ }
10
+ function readInput(args) {
11
+ const positional = args.positional[0];
12
+ const useStdin = flagBool(args, 'stdin') || positional === undefined || positional === '-';
13
+ if (useStdin)
14
+ return readFileSync(0, 'utf8');
15
+ return readFileSync(positional, 'utf8');
16
+ }
17
+ /**
18
+ * `shrk compress` — deterministically compress a blob (file or stdin) before
19
+ * it re-enters an agent prompt. Same information, fewer tokens. Lossy passes
20
+ * cache the original under `.sharkcraft/ccr/` so `shrk expand <key>` can get
21
+ * it back. The compressed text goes to stdout (pipeable); the savings summary
22
+ * goes to stderr unless `--json` is set.
23
+ */
24
+ export const compressCommand = {
25
+ name: 'compress',
26
+ description: 'Compress a blob (file or stdin) deterministically to cut tokens — JSON→table, logs/search/diffs→signal. Reversible via `shrk expand`.',
27
+ usage: 'shrk [--cwd <dir>] compress [<file>|-] [--stdin] [--type <content-type>] [--query <text>] [--max <n>] [--no-cache] [--json]',
28
+ run(args) {
29
+ const cwd = resolveCwd(args);
30
+ let content;
31
+ try {
32
+ content = readInput(args);
33
+ }
34
+ catch (e) {
35
+ process.stderr.write(`compress: cannot read input — ${e.message}\n`);
36
+ return 1;
37
+ }
38
+ if (content.length === 0) {
39
+ process.stderr.write('compress: empty input.\n');
40
+ return 1;
41
+ }
42
+ const opts = {};
43
+ if (!flagBool(args, 'no-cache'))
44
+ opts.store = new FileCcrStore(ccrDir(cwd));
45
+ const query = flagString(args, 'query');
46
+ if (query)
47
+ opts.query = query;
48
+ const max = flagNumber(args, 'max');
49
+ if (max !== undefined && max > 0)
50
+ opts.maxItems = Math.floor(max);
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
+ if (flagBool(args, 'json')) {
63
+ process.stdout.write(asJson({
64
+ contentType: result.contentType,
65
+ strategy: result.strategy,
66
+ lossy: result.lossy,
67
+ tokensBefore: result.savings.before,
68
+ tokensAfter: result.savings.after,
69
+ tokensSaved: result.savings.saved,
70
+ savedRatio: result.savings.ratio,
71
+ ccrKey: result.ccrKey ?? null,
72
+ note: result.note,
73
+ compressed: result.compressed,
74
+ }) + '\n');
75
+ return 0;
76
+ }
77
+ process.stdout.write(result.compressed + '\n');
78
+ const cached = result.ccrKey ? ` · original cached as ${result.ccrKey} (shrk expand ${result.ccrKey})` : '';
79
+ process.stderr.write(`${result.strategy}: ${result.savings.before} → ${result.savings.after} tokens (−${pct}%)${cached}\n`);
80
+ return 0;
81
+ },
82
+ };
83
+ /**
84
+ * `shrk expand` — the retrieve half of CCR. Print the full original that
85
+ * `shrk compress` cached for a `<<ccr:KEY>>` key.
86
+ */
87
+ export const expandCommand = {
88
+ name: 'expand',
89
+ description: 'Retrieve the full original a `shrk compress` run cached, by its `<<ccr:KEY>>` key.',
90
+ usage: 'shrk [--cwd <dir>] expand <key> [--json]',
91
+ run(args) {
92
+ const cwd = resolveCwd(args);
93
+ const key = (args.positional[0] ?? '').trim();
94
+ if (key.length === 0) {
95
+ process.stderr.write('expand: a CCR key is required (e.g. `shrk expand a1b2c3d4e5f60718`).\n');
96
+ return 1;
97
+ }
98
+ const store = new FileCcrStore(ccrDir(cwd));
99
+ const entry = store.get(key);
100
+ if (!entry) {
101
+ process.stderr.write(`expand: no cached original for key "${key}" under ${ccrDir(cwd)}.\n`);
102
+ return 1;
103
+ }
104
+ if (flagBool(args, 'json')) {
105
+ process.stdout.write(asJson({ key: entry.key, bytes: entry.bytes, content: entry.content }) + '\n');
106
+ return 0;
107
+ }
108
+ process.stdout.write(entry.content + '\n');
109
+ return 0;
110
+ },
111
+ };
@@ -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,EAIhB,MAAM,uBAAuB,CAAC;AAsX/B,wBAAgB,aAAa,IAAI,eAAe,CA2X/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BrE;AAkGD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CA4CxE"}
package/dist/main.js CHANGED
@@ -34,6 +34,8 @@ import { gateCommand } from "./commands/gate.command.js";
34
34
  import { migrateCommand } from "./commands/migrate.command.js";
35
35
  import { coverageCommand } from "./commands/coverage.command.js";
36
36
  import { statsCommand } from "./commands/stats.command.js";
37
+ import { compressCommand, expandCommand } from "./commands/compress.command.js";
38
+ import { alignCommand, unalignCommand } from "./commands/cache-align.command.js";
37
39
  import { reviewCommand } from "./commands/review.command.js";
38
40
  import { onboardCommand } from "./commands/onboard.command.js";
39
41
  import { contradictionsCommand, generatedCommand, ingestCommand, } from "./commands/ingest.command.js";
@@ -196,6 +198,10 @@ export function buildRegistry() {
196
198
  registry.register(migrateCommand);
197
199
  registry.register(coverageCommand);
198
200
  registry.register(statsCommand);
201
+ registry.register(compressCommand);
202
+ registry.register(expandCommand);
203
+ registry.register(alignCommand);
204
+ registry.register(unalignCommand);
199
205
  registry.register(reviewCommand);
200
206
  registry.register(onboardCommand);
201
207
  registry.register(ingestCommand);
@@ -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)
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.16",
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.16",
51
+ "@shrkcrft/compress": "^0.1.0-alpha.16",
52
+ "@shrkcrft/config": "^0.1.0-alpha.16",
53
+ "@shrkcrft/workspace": "^0.1.0-alpha.16",
54
+ "@shrkcrft/knowledge": "^0.1.0-alpha.16",
55
+ "@shrkcrft/context": "^0.1.0-alpha.16",
56
+ "@shrkcrft/rules": "^0.1.0-alpha.16",
57
+ "@shrkcrft/paths": "^0.1.0-alpha.16",
58
+ "@shrkcrft/templates": "^0.1.0-alpha.16",
59
+ "@shrkcrft/plugin-api": "^0.1.0-alpha.16",
60
+ "@shrkcrft/dashboard": "^0.1.0-alpha.16",
61
+ "@shrkcrft/dashboard-api": "^0.1.0-alpha.16",
62
+ "@shrkcrft/pipelines": "^0.1.0-alpha.16",
63
+ "@shrkcrft/presets": "^0.1.0-alpha.16",
64
+ "@shrkcrft/boundaries": "^0.1.0-alpha.16",
65
+ "@shrkcrft/graph": "^0.1.0-alpha.16",
66
+ "@shrkcrft/rule-graph": "^0.1.0-alpha.16",
67
+ "@shrkcrft/structural-search": "^0.1.0-alpha.16",
68
+ "@shrkcrft/impact-engine": "^0.1.0-alpha.16",
69
+ "@shrkcrft/context-planner": "^0.1.0-alpha.16",
70
+ "@shrkcrft/architecture-guard": "^0.1.0-alpha.16",
71
+ "@shrkcrft/framework-scanners": "^0.1.0-alpha.16",
72
+ "@shrkcrft/api-surface-diff": "^0.1.0-alpha.16",
73
+ "@shrkcrft/quality-gates": "^0.1.0-alpha.16",
74
+ "@shrkcrft/migrate": "^0.1.0-alpha.16",
75
+ "@shrkcrft/generator": "^0.1.0-alpha.16",
76
+ "@shrkcrft/importer": "^0.1.0-alpha.16",
77
+ "@shrkcrft/inspector": "^0.1.0-alpha.16",
78
+ "@shrkcrft/ai": "^0.1.0-alpha.16",
79
+ "@shrkcrft/embeddings": "^0.1.0-alpha.16",
80
+ "@shrkcrft/shared": "^0.1.0-alpha.16",
81
+ "@shrkcrft/mcp-server": "^0.1.0-alpha.16",
81
82
  "@huggingface/transformers": "^3.7.5"
82
83
  },
83
84
  "publishConfig": {