knitbrain 0.1.0

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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -0
  3. package/dist/ccr/store.d.ts +57 -0
  4. package/dist/ccr/store.js +195 -0
  5. package/dist/ccr/store.js.map +1 -0
  6. package/dist/dashboard.d.ts +23 -0
  7. package/dist/dashboard.js +125 -0
  8. package/dist/dashboard.js.map +1 -0
  9. package/dist/engine/agents.d.ts +36 -0
  10. package/dist/engine/agents.js +88 -0
  11. package/dist/engine/agents.js.map +1 -0
  12. package/dist/engine/calibration.d.ts +29 -0
  13. package/dist/engine/calibration.js +72 -0
  14. package/dist/engine/calibration.js.map +1 -0
  15. package/dist/engine/feedback.d.ts +30 -0
  16. package/dist/engine/feedback.js +82 -0
  17. package/dist/engine/feedback.js.map +1 -0
  18. package/dist/engine/knowledge.d.ts +22 -0
  19. package/dist/engine/knowledge.js +154 -0
  20. package/dist/engine/knowledge.js.map +1 -0
  21. package/dist/engine/memory.d.ts +35 -0
  22. package/dist/engine/memory.js +93 -0
  23. package/dist/engine/memory.js.map +1 -0
  24. package/dist/engine/meter.d.ts +40 -0
  25. package/dist/engine/meter.js +61 -0
  26. package/dist/engine/meter.js.map +1 -0
  27. package/dist/engine/skills.d.ts +33 -0
  28. package/dist/engine/skills.js +97 -0
  29. package/dist/engine/skills.js.map +1 -0
  30. package/dist/engine/teams.d.ts +28 -0
  31. package/dist/engine/teams.js +58 -0
  32. package/dist/engine/teams.js.map +1 -0
  33. package/dist/engine/workflow.d.ts +18 -0
  34. package/dist/engine/workflow.js +40 -0
  35. package/dist/engine/workflow.js.map +1 -0
  36. package/dist/hooks/index.d.ts +2 -0
  37. package/dist/hooks/index.js +47 -0
  38. package/dist/hooks/index.js.map +1 -0
  39. package/dist/hooks/pretooluse.d.ts +23 -0
  40. package/dist/hooks/pretooluse.js +38 -0
  41. package/dist/hooks/pretooluse.js.map +1 -0
  42. package/dist/hub/client.d.ts +26 -0
  43. package/dist/hub/client.js +64 -0
  44. package/dist/hub/client.js.map +1 -0
  45. package/dist/hub/server.d.ts +23 -0
  46. package/dist/hub/server.js +85 -0
  47. package/dist/hub/server.js.map +1 -0
  48. package/dist/index.d.ts +2 -0
  49. package/dist/index.js +82 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/mcp/tools.d.ts +40 -0
  52. package/dist/mcp/tools.js +461 -0
  53. package/dist/mcp/tools.js.map +1 -0
  54. package/dist/measure.d.ts +27 -0
  55. package/dist/measure.js +25 -0
  56. package/dist/measure.js.map +1 -0
  57. package/dist/optimizer/ast.d.ts +19 -0
  58. package/dist/optimizer/ast.js +189 -0
  59. package/dist/optimizer/ast.js.map +1 -0
  60. package/dist/optimizer/code.d.ts +10 -0
  61. package/dist/optimizer/code.js +231 -0
  62. package/dist/optimizer/code.js.map +1 -0
  63. package/dist/optimizer/json.d.ts +9 -0
  64. package/dist/optimizer/json.js +68 -0
  65. package/dist/optimizer/json.js.map +1 -0
  66. package/dist/optimizer/router.d.ts +39 -0
  67. package/dist/optimizer/router.js +137 -0
  68. package/dist/optimizer/router.js.map +1 -0
  69. package/dist/optimizer/text.d.ts +21 -0
  70. package/dist/optimizer/text.js +88 -0
  71. package/dist/optimizer/text.js.map +1 -0
  72. package/dist/optimizer/types.d.ts +13 -0
  73. package/dist/optimizer/types.js +2 -0
  74. package/dist/optimizer/types.js.map +1 -0
  75. package/dist/paths.d.ts +20 -0
  76. package/dist/paths.js +44 -0
  77. package/dist/paths.js.map +1 -0
  78. package/dist/platforms.d.ts +51 -0
  79. package/dist/platforms.js +157 -0
  80. package/dist/platforms.js.map +1 -0
  81. package/dist/profile.d.ts +3 -0
  82. package/dist/profile.js +169 -0
  83. package/dist/profile.js.map +1 -0
  84. package/dist/proxy/cache-aligner.d.ts +9 -0
  85. package/dist/proxy/cache-aligner.js +15 -0
  86. package/dist/proxy/cache-aligner.js.map +1 -0
  87. package/dist/proxy/index.d.ts +2 -0
  88. package/dist/proxy/index.js +37 -0
  89. package/dist/proxy/index.js.map +1 -0
  90. package/dist/proxy/optimize-request.d.ts +51 -0
  91. package/dist/proxy/optimize-request.js +111 -0
  92. package/dist/proxy/optimize-request.js.map +1 -0
  93. package/dist/proxy/server.d.ts +31 -0
  94. package/dist/proxy/server.js +104 -0
  95. package/dist/proxy/server.js.map +1 -0
  96. package/dist/server.d.ts +19 -0
  97. package/dist/server.js +54 -0
  98. package/dist/server.js.map +1 -0
  99. package/dist/setup.d.ts +28 -0
  100. package/dist/setup.js +96 -0
  101. package/dist/setup.js.map +1 -0
  102. package/dist/tokenizer.d.ts +23 -0
  103. package/dist/tokenizer.js +25 -0
  104. package/dist/tokenizer.js.map +1 -0
  105. package/dist/version.d.ts +3 -0
  106. package/dist/version.js +4 -0
  107. package/dist/version.js.map +1 -0
  108. package/package.json +66 -0
@@ -0,0 +1,189 @@
1
+ import { createRequire } from "node:module";
2
+ import { dirname, join } from "node:path";
3
+ /** Don't elide bodies smaller than this many source characters (matches scanner). */
4
+ const MIN_BODY_CHARS = 40;
5
+ let state = "idle";
6
+ const parsers = new Map();
7
+ /** Whether the WASM parsers are loaded and usable right now (sync check). */
8
+ export function astReady() {
9
+ return state === "ready";
10
+ }
11
+ /** Test seam: reset to cold state (parsers are kept — re-init is cheap). */
12
+ export function resetAstForTest() {
13
+ if (state === "failed")
14
+ state = "idle";
15
+ }
16
+ let loading = null;
17
+ /**
18
+ * Kick off (or await) WASM parser initialization. Idempotent; safe to call
19
+ * fire-and-forget from sync code. On any failure the state is "failed" and
20
+ * the scanner fallback serves all code forever — never throws.
21
+ */
22
+ export function ensureAst() {
23
+ if (state === "ready" || state === "failed")
24
+ return Promise.resolve();
25
+ if (loading)
26
+ return loading;
27
+ state = "loading";
28
+ loading = (async () => {
29
+ try {
30
+ const require = createRequire(import.meta.url);
31
+ const pkgMain = require.resolve("@vscode/tree-sitter-wasm");
32
+ const wasmDir = dirname(pkgMain);
33
+ const ts = require("@vscode/tree-sitter-wasm");
34
+ await ts.Parser.init();
35
+ for (const lang of ["typescript", "tsx", "python"]) {
36
+ const language = await ts.Language.load(join(wasmDir, `tree-sitter-${lang}.wasm`));
37
+ const parser = new ts.Parser();
38
+ parser.setLanguage(language);
39
+ parsers.set(lang, parser);
40
+ }
41
+ state = "ready";
42
+ }
43
+ catch {
44
+ state = "failed"; // degrade to the scanner, permanently and silently
45
+ }
46
+ })();
47
+ return loading;
48
+ }
49
+ /** Looks like Python (indentation language the brace scanner can't handle). */
50
+ function looksPython(text) {
51
+ return /^\s*(def \w+.*:|async def \w+.*:|class \w+(\(.*\))?:|from \S+ import )/m.test(text);
52
+ }
53
+ /** Function-like node types whose `body` field is elidable, per grammar. */
54
+ const BODY_OWNERS = new Set([
55
+ // TS / TSX / JS
56
+ "function_declaration",
57
+ "function_expression",
58
+ "generator_function",
59
+ "generator_function_declaration",
60
+ "method_definition",
61
+ "arrow_function",
62
+ // Python
63
+ "function_definition",
64
+ ]);
65
+ /** Comments / docstrings shorter than this stay inline. */
66
+ const MIN_COMMENT_CHARS = 120;
67
+ /**
68
+ * Walk the tree collecting elidable ranges — function/method bodies, long
69
+ * comment blocks, and module docstrings — skipping subtrees already elided.
70
+ */
71
+ function collectElisions(root, src, isPython) {
72
+ const out = [];
73
+ const lineCount = (start, end) => src.slice(start, end).split("\n").length;
74
+ const commentMarker = (start, end) => {
75
+ const n = lineCount(start, end);
76
+ return isPython || src.slice(start, start + 1) === "#"
77
+ ? `# …${n}-line comment`
78
+ : `/* …${n}-line comment */`;
79
+ };
80
+ const visit = (node) => {
81
+ if (BODY_OWNERS.has(node.type)) {
82
+ const body = node.childForFieldName("body");
83
+ if (body !== null) {
84
+ const brace = body.type === "statement_block";
85
+ const isBlock = brace || body.type === "block";
86
+ if (isBlock) {
87
+ const start = brace ? body.startIndex + 1 : body.startIndex;
88
+ const end = brace ? body.endIndex - 1 : body.endIndex;
89
+ if (end - start >= MIN_BODY_CHARS) {
90
+ const n = lineCount(start, end);
91
+ out.push({ start, end, replacement: brace ? ` …${n} lines ` : `…${n} lines` });
92
+ return; // don't descend into an elided body
93
+ }
94
+ }
95
+ }
96
+ }
97
+ // Module docstrings: low-signal in a skeleton, recoverable from CCR.
98
+ const isDocstring = isPython && node.type === "expression_statement" && node.namedChild(0)?.type === "string";
99
+ if (isDocstring && node.endIndex - node.startIndex >= MIN_COMMENT_CHARS) {
100
+ out.push({
101
+ start: node.startIndex,
102
+ end: node.endIndex,
103
+ replacement: commentMarker(node.startIndex, node.endIndex),
104
+ });
105
+ return;
106
+ }
107
+ // Children: merge ADJACENT comment runs (consecutive `//` lines are
108
+ // separate nodes individually under the threshold; together they're a
109
+ // block worth eliding). Single long doc comments are a run of one.
110
+ let i = 0;
111
+ while (i < node.namedChildCount) {
112
+ const child = node.namedChild(i);
113
+ if (child.type === "comment") {
114
+ let j = i;
115
+ let end = child.endIndex;
116
+ while (j + 1 < node.namedChildCount) {
117
+ const next = node.namedChild(j + 1);
118
+ if (next.type !== "comment")
119
+ break;
120
+ if (/\S/.test(src.slice(end, next.startIndex)))
121
+ break; // gap has code
122
+ j += 1;
123
+ end = next.endIndex;
124
+ }
125
+ if (end - child.startIndex >= MIN_COMMENT_CHARS) {
126
+ out.push({ start: child.startIndex, end, replacement: commentMarker(child.startIndex, end) });
127
+ }
128
+ i = j + 1;
129
+ continue;
130
+ }
131
+ visit(child);
132
+ i += 1;
133
+ }
134
+ };
135
+ visit(root);
136
+ return out;
137
+ }
138
+ /**
139
+ * Compress source code via tree-sitter: keep imports, signatures, types,
140
+ * decorators, class headers; elide function/method bodies. Returns null when
141
+ * the parsers aren't loaded or no grammar fits — caller falls back to the
142
+ * scanner. Lossless: pristine original in CCR.
143
+ */
144
+ export function compressCodeAst(original, ccr) {
145
+ if (state !== "ready") {
146
+ void ensureAst(); // warm up for the next call
147
+ return null;
148
+ }
149
+ // Real transcript blocks are messy (snippets, prose-wrapped pastes), so a
150
+ // parse-error gate rejects nearly everything. Elision only ever touches
151
+ // well-formed function nodes — error recovery just yields fewer matches —
152
+ // so instead: parse with every grammar and keep whichever elides the most.
153
+ const candidates = looksPython(original)
154
+ ? ["python", "typescript", "tsx"]
155
+ : ["typescript", "tsx", "python"];
156
+ let elisions = [];
157
+ let elidedChars = 0;
158
+ let isPython = false;
159
+ for (const langName of candidates) {
160
+ const parser = parsers.get(langName);
161
+ if (!parser)
162
+ continue;
163
+ const tree = parser.parse(original);
164
+ if (tree === null)
165
+ continue;
166
+ const found = collectElisions(tree.rootNode, original, langName === "python");
167
+ const chars = found.reduce((s, e) => s + (e.end - e.start), 0);
168
+ if (chars > elidedChars) {
169
+ elisions = found;
170
+ elidedChars = chars;
171
+ isPython = langName === "python";
172
+ }
173
+ }
174
+ if (elisions.length === 0)
175
+ return null; // nothing to elide — let the scanner try
176
+ const parts = [];
177
+ let cursor = 0;
178
+ for (const e of elisions) {
179
+ parts.push(original.slice(cursor, e.start));
180
+ parts.push(e.replacement);
181
+ cursor = e.end;
182
+ }
183
+ parts.push(original.slice(cursor));
184
+ const handle = ccr.put(original);
185
+ const marker = isPython ? `# ⟨ccr:${handle}⟩` : `// ⟨ccr:${handle}⟩`;
186
+ const skeleton = `${parts.join("")}\n${marker}`;
187
+ return { skeleton, handle, contentType: "code" };
188
+ }
189
+ //# sourceMappingURL=ast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/optimizer/ast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CCRStore } from "../ccr/store.js";
2
+ import type { CompressResult } from "./types.js";
3
+ /** Cheap structural test: looks like source code (braces + a code keyword), or an indentation language (Python). */
4
+ export declare function isCode(text: string): boolean;
5
+ /**
6
+ * Compress source code: keep imports, signatures, types, decorators, class
7
+ * headers; elide function/method bodies to `{ …N lines }`. The pristine
8
+ * original is stored in CCR and recoverable byte-for-byte.
9
+ */
10
+ export declare function compressCode(original: string, ccr: CCRStore): CompressResult;
@@ -0,0 +1,231 @@
1
+ /** Control keywords whose `(...) {` is a control block, NOT a function body. */
2
+ const CONTROL_KEYWORDS = new Set([
3
+ "if",
4
+ "for",
5
+ "while",
6
+ "switch",
7
+ "catch",
8
+ "with",
9
+ ]);
10
+ /** Don't elide bodies smaller than this many source characters. */
11
+ const MIN_BODY_CHARS = 40;
12
+ /** Cheap structural test: looks like source code (braces + a code keyword), or an indentation language (Python). */
13
+ export function isCode(text) {
14
+ if (/[{};]/.test(text) &&
15
+ /\b(function|const|let|var|class|import|export|def|fn|public|private|interface|type)\b/.test(text)) {
16
+ return true;
17
+ }
18
+ return /^(def \w+.*:|class \w+(\(.*\))?:|from \S+ import |import \S+$|async def \w+)/m.test(text);
19
+ }
20
+ /**
21
+ * Replace the *contents* of strings, template literals, and comments with
22
+ * spaces (preserving length and newlines) so brace/paren matching never trips
23
+ * on punctuation inside them. Returns a same-length masked copy.
24
+ */
25
+ function maskStringsAndComments(src) {
26
+ const out = src.split("");
27
+ const n = src.length;
28
+ let i = 0;
29
+ let mode = "code";
30
+ const blank = (idx) => {
31
+ if (src[idx] !== "\n")
32
+ out[idx] = " ";
33
+ };
34
+ while (i < n) {
35
+ const c = src[i];
36
+ const c2 = i + 1 < n ? src[i + 1] : "";
37
+ if (mode === "code") {
38
+ if (c === "/" && c2 === "/") {
39
+ mode = "line";
40
+ i += 2;
41
+ }
42
+ else if (c === "/" && c2 === "*") {
43
+ out[i] = " ";
44
+ out[i + 1] = " ";
45
+ mode = "block";
46
+ i += 2;
47
+ }
48
+ else if (c === "'") {
49
+ mode = "sq";
50
+ i += 1;
51
+ }
52
+ else if (c === '"') {
53
+ mode = "dq";
54
+ i += 1;
55
+ }
56
+ else if (c === "`") {
57
+ mode = "tpl";
58
+ i += 1;
59
+ }
60
+ else {
61
+ i += 1;
62
+ }
63
+ continue;
64
+ }
65
+ if (mode === "line") {
66
+ if (c === "\n")
67
+ mode = "code";
68
+ else
69
+ blank(i);
70
+ i += 1;
71
+ continue;
72
+ }
73
+ if (mode === "block") {
74
+ if (c === "*" && c2 === "/") {
75
+ out[i] = " ";
76
+ out[i + 1] = " ";
77
+ mode = "code";
78
+ i += 2;
79
+ }
80
+ else {
81
+ blank(i);
82
+ i += 1;
83
+ }
84
+ continue;
85
+ }
86
+ // string / template
87
+ const quote = mode === "sq" ? "'" : mode === "dq" ? '"' : "`";
88
+ if (c === "\\") {
89
+ blank(i);
90
+ if (i + 1 < n)
91
+ blank(i + 1);
92
+ i += 2;
93
+ continue;
94
+ }
95
+ if (c === quote) {
96
+ mode = "code";
97
+ i += 1;
98
+ continue;
99
+ }
100
+ blank(i);
101
+ i += 1;
102
+ }
103
+ return out.join("");
104
+ }
105
+ /** Last non-whitespace index at or before `from` in `s`, else -1. */
106
+ function prevNonWs(s, from) {
107
+ let i = from;
108
+ while (i >= 0 && /\s/.test(s[i]))
109
+ i -= 1;
110
+ return i;
111
+ }
112
+ /** Match the `(` that pairs with the `)` at `closeParen` (masked input). */
113
+ function matchOpenParen(masked, closeParen) {
114
+ let depth = 0;
115
+ for (let i = closeParen; i >= 0; i -= 1) {
116
+ const c = masked[i];
117
+ if (c === ")")
118
+ depth += 1;
119
+ else if (c === "(") {
120
+ depth -= 1;
121
+ if (depth === 0)
122
+ return i;
123
+ }
124
+ }
125
+ return -1;
126
+ }
127
+ /** The identifier token ending just before index `before` (skipping ws). */
128
+ function tokenBefore(masked, before) {
129
+ const end = prevNonWs(masked, before - 1);
130
+ if (end < 0)
131
+ return "";
132
+ let start = end;
133
+ while (start >= 0 && /[A-Za-z0-9_$]/.test(masked[start]))
134
+ start -= 1;
135
+ return masked.slice(start + 1, end + 1);
136
+ }
137
+ /** Characters allowed in a return-type annotation between `)` and `{`. */
138
+ const RETURN_TYPE_CHARS = /[A-Za-z0-9_$<>,.[\]|:?&]/;
139
+ /**
140
+ * Is the `{` at `brace` (masked) the start of a function/method body?
141
+ *
142
+ * Handles: arrow bodies (`=> {`), bare `(...) {`, and TS return-typed
143
+ * signatures (`(...): Promise<string> {`) by skipping the return-type
144
+ * expression back to its `)`. Control blocks (`if/for/while (...) {`) and
145
+ * object/class bodies are deliberately NOT treated as function bodies.
146
+ */
147
+ function isFunctionBody(masked, brace) {
148
+ const p = prevNonWs(masked, brace - 1);
149
+ if (p < 0)
150
+ return false;
151
+ // Arrow function: `=> {`
152
+ if (masked[p] === ">" && p >= 1 && masked[p - 1] === "=")
153
+ return true;
154
+ // Skip a possible return-type expression backwards to find the `)`.
155
+ let j = p;
156
+ while (j >= 0 && RETURN_TYPE_CHARS.test(masked[j])) {
157
+ j = prevNonWs(masked, j - 1);
158
+ }
159
+ if (j < 0 || masked[j] !== ")")
160
+ return false;
161
+ const open = matchOpenParen(masked, j);
162
+ if (open < 0)
163
+ return false;
164
+ const tok = tokenBefore(masked, open);
165
+ if (tok === "")
166
+ return true; // anonymous `function (...) {`
167
+ return !CONTROL_KEYWORDS.has(tok);
168
+ }
169
+ /** Match the `}` that pairs with the `{` at `open` (masked input). */
170
+ function matchCloseBrace(masked, open) {
171
+ let depth = 0;
172
+ for (let i = open; i < masked.length; i += 1) {
173
+ const c = masked[i];
174
+ if (c === "{")
175
+ depth += 1;
176
+ else if (c === "}") {
177
+ depth -= 1;
178
+ if (depth === 0)
179
+ return i;
180
+ }
181
+ }
182
+ return -1;
183
+ }
184
+ /**
185
+ * Compress source code: keep imports, signatures, types, decorators, class
186
+ * headers; elide function/method bodies to `{ …N lines }`. The pristine
187
+ * original is stored in CCR and recoverable byte-for-byte.
188
+ */
189
+ export function compressCode(original, ccr) {
190
+ const masked = maskStringsAndComments(original);
191
+ // Find non-nested function-body brace ranges, left to right.
192
+ const ranges = [];
193
+ let scanFrom = 0;
194
+ for (let i = 0; i < masked.length; i += 1) {
195
+ if (i < scanFrom)
196
+ continue;
197
+ if (masked[i] !== "{")
198
+ continue;
199
+ if (!isFunctionBody(masked, i))
200
+ continue;
201
+ const close = matchCloseBrace(masked, i);
202
+ if (close < 0)
203
+ continue;
204
+ ranges.push({ open: i, close });
205
+ scanFrom = close + 1; // skip anything nested inside this body
206
+ }
207
+ let skeleton;
208
+ if (ranges.length === 0) {
209
+ skeleton = original;
210
+ }
211
+ else {
212
+ const parts = [];
213
+ let cursor = 0;
214
+ for (const { open, close } of ranges) {
215
+ const inner = original.slice(open + 1, close);
216
+ if (inner.length < MIN_BODY_CHARS)
217
+ continue; // keep tiny bodies inline
218
+ parts.push(original.slice(cursor, open + 1));
219
+ const lines = inner.split("\n").length;
220
+ parts.push(` …${lines} lines `);
221
+ cursor = close;
222
+ }
223
+ parts.push(original.slice(cursor));
224
+ skeleton = parts.join("");
225
+ }
226
+ const handle = ccr.put(original);
227
+ // Handle emitted once (token-cheap) — bodies reference the same original.
228
+ skeleton = `${skeleton}\n// ⟨ccr:${handle}⟩`;
229
+ return { skeleton, handle, contentType: "code" };
230
+ }
231
+ //# sourceMappingURL=code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/optimizer/code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { CCRStore } from "../ccr/store.js";
2
+ import type { CompressResult } from "./types.js";
3
+ /** Structural test: does this text parse as a JSON object/array? */
4
+ export declare function isJson(text: string): boolean;
5
+ /**
6
+ * Compress a JSON payload: store the pristine original in CCR, return a
7
+ * structure-preserving skeleton tagged with the recovery handle.
8
+ */
9
+ export declare function compressJson(original: string, ccr: CCRStore): CompressResult;
@@ -0,0 +1,68 @@
1
+ /** Strings longer than this are elided to a placeholder. */
2
+ const MAX_STRING = 64;
3
+ /** Arrays longer than this keep a sample + a count, rest deferred to CCR. */
4
+ const MAX_ARRAY = 6;
5
+ /** How many leading items to keep as a sample for long arrays. */
6
+ const ARRAY_SAMPLE = 1;
7
+ /** Objects (maps) with more entries than this keep a sample of keys + a count. */
8
+ const MAX_OBJECT_KEYS = 24;
9
+ /** How many leading entries to keep as a sample for large objects. */
10
+ const OBJECT_SAMPLE = 6;
11
+ /** Structural test: does this text parse as a JSON object/array? */
12
+ export function isJson(text) {
13
+ const t = text.trim();
14
+ if (!t.startsWith("{") && !t.startsWith("["))
15
+ return false;
16
+ try {
17
+ JSON.parse(t);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ /**
25
+ * Produce a structure-preserving skeleton: keep keys/structure/short scalars
26
+ * (the navigation), elide long strings and long arrays (the payload). The full
27
+ * original is recoverable from CCR — this view is intentionally lossy.
28
+ */
29
+ function skeletonize(value) {
30
+ if (typeof value === "string") {
31
+ return value.length > MAX_STRING ? `⟨str:${value.length}c⟩` : value;
32
+ }
33
+ if (Array.isArray(value)) {
34
+ if (value.length > MAX_ARRAY) {
35
+ const sample = value.slice(0, ARRAY_SAMPLE).map(skeletonize);
36
+ return [...sample, `⟨…${value.length - ARRAY_SAMPLE} more items⟩`];
37
+ }
38
+ return value.map(skeletonize);
39
+ }
40
+ if (value !== null && typeof value === "object") {
41
+ const entries = Object.entries(value);
42
+ const out = {};
43
+ if (entries.length > MAX_OBJECT_KEYS) {
44
+ // Large map (e.g. a dependency tree): keep the shape via a key sample.
45
+ for (const [k, v] of entries.slice(0, OBJECT_SAMPLE))
46
+ out[k] = skeletonize(v);
47
+ out[`⟨…${entries.length - OBJECT_SAMPLE} more keys⟩`] = null;
48
+ return out;
49
+ }
50
+ for (const [k, v] of entries)
51
+ out[k] = skeletonize(v);
52
+ return out;
53
+ }
54
+ // number | boolean | null — kept verbatim (short, structural)
55
+ return value;
56
+ }
57
+ /**
58
+ * Compress a JSON payload: store the pristine original in CCR, return a
59
+ * structure-preserving skeleton tagged with the recovery handle.
60
+ */
61
+ export function compressJson(original, ccr) {
62
+ const parsed = JSON.parse(original);
63
+ const skel = skeletonize(parsed);
64
+ const handle = ccr.put(original);
65
+ const skeleton = `${JSON.stringify(skel)} ⟨ccr:${handle}⟩`;
66
+ return { skeleton, handle, contentType: "json" };
67
+ }
68
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/optimizer/json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { CCRStore } from "../ccr/store.js";
2
+ import type { ContentType } from "./types.js";
3
+ /** Result of routing + compressing a payload, with measurement + a safety flag. */
4
+ export interface RouteResult {
5
+ /** The payload to hand the agent: a skeleton if compressed, else the original. */
6
+ readonly skeleton: string;
7
+ /** CCR handle for recovery, or "" when passed through uncompressed. */
8
+ readonly handle: string;
9
+ /** Detected content type. */
10
+ readonly contentType: ContentType;
11
+ /** False = passed through unchanged (compression wasn't worth it). */
12
+ readonly compressed: boolean;
13
+ readonly originalTokens: number;
14
+ readonly skeletonTokens: number;
15
+ readonly savedPct: number;
16
+ }
17
+ /** Deterministic content-type detection (no ML). JSON is strict; code is heuristic. */
18
+ export declare function detect(text: string): ContentType;
19
+ /**
20
+ * Detect host-Read line numbering (the dominant in-session tool-result shape;
21
+ * the prefixes defeat code parsing if left in). Returns the stripped content
22
+ * when ≥60% of lines carry the prefix, else null.
23
+ */
24
+ export declare function stripLineNumbers(text: string): string | null;
25
+ /**
26
+ * The unified optimizer entry point: detect → route → compress → measure, and
27
+ * pass the original through unchanged unless compression saves meaningfully.
28
+ * Lossless either way (original is recoverable from CCR when compressed).
29
+ */
30
+ export interface CompressOptions {
31
+ /**
32
+ * Whether short-prose sentence anchoring may apply. Callers with a TOIN
33
+ * feedback store pass `!feedback.shouldSkip("prose")` so over-retrieval
34
+ * backs the lever off; defaults to true for gate-less contexts (lossless
35
+ * either way).
36
+ */
37
+ allowProse?: boolean;
38
+ }
39
+ export declare function compress(text: string, ccr: CCRStore, options?: CompressOptions): RouteResult;