@blackwell-systems/gcf 2.1.1 → 2.2.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 (59) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/index.cjs +204 -12
  3. package/dist/cli.js +0 -0
  4. package/dist/decode_generic.js +95 -11
  5. package/dist/decode_generic.js.map +1 -1
  6. package/dist/generic.js +162 -5
  7. package/dist/generic.js.map +1 -1
  8. package/dist/scalar.d.ts.map +1 -1
  9. package/dist/scalar.js +3 -0
  10. package/dist/scalar.js.map +1 -1
  11. package/package.json +2 -2
  12. package/src/decode_generic.ts +100 -12
  13. package/src/generic.ts +157 -5
  14. package/src/scalar.ts +2 -0
  15. package/dist/cjs/browser.d.ts +0 -9
  16. package/dist/cjs/browser.js +0 -25
  17. package/dist/cjs/browser.js.map +0 -1
  18. package/dist/cjs/cli.d.ts +0 -5
  19. package/dist/cjs/cli.js +0 -136
  20. package/dist/cjs/cli.js.map +0 -1
  21. package/dist/cjs/constants.d.ts +0 -8
  22. package/dist/cjs/constants.js +0 -46
  23. package/dist/cjs/constants.js.map +0 -1
  24. package/dist/cjs/decode.d.ts +0 -5
  25. package/dist/cjs/decode.js +0 -197
  26. package/dist/cjs/decode.js.map +0 -1
  27. package/dist/cjs/decode_generic.d.ts +0 -4
  28. package/dist/cjs/decode_generic.js +0 -678
  29. package/dist/cjs/decode_generic.js.map +0 -1
  30. package/dist/cjs/delta.d.ts +0 -15
  31. package/dist/cjs/delta.js +0 -73
  32. package/dist/cjs/delta.js.map +0 -1
  33. package/dist/cjs/encode.d.ts +0 -5
  34. package/dist/cjs/encode.js +0 -89
  35. package/dist/cjs/encode.js.map +0 -1
  36. package/dist/cjs/generic.d.ts +0 -1
  37. package/dist/cjs/generic.js +0 -332
  38. package/dist/cjs/generic.js.map +0 -1
  39. package/dist/cjs/index.d.ts +0 -11
  40. package/dist/cjs/index.js +0 -32
  41. package/dist/cjs/index.js.map +0 -1
  42. package/dist/cjs/packroot.d.ts +0 -13
  43. package/dist/cjs/packroot.js +0 -50
  44. package/dist/cjs/packroot.js.map +0 -1
  45. package/dist/cjs/scalar.d.ts +0 -26
  46. package/dist/cjs/scalar.js +0 -339
  47. package/dist/cjs/scalar.js.map +0 -1
  48. package/dist/cjs/session.d.ts +0 -30
  49. package/dist/cjs/session.js +0 -140
  50. package/dist/cjs/session.js.map +0 -1
  51. package/dist/cjs/stream.d.ts +0 -66
  52. package/dist/cjs/stream.js +0 -127
  53. package/dist/cjs/stream.js.map +0 -1
  54. package/dist/cjs/stream_generic.d.ts +0 -37
  55. package/dist/cjs/stream_generic.js +0 -87
  56. package/dist/cjs/stream_generic.js.map +0 -1
  57. package/dist/cjs/types.d.ts +0 -75
  58. package/dist/cjs/types.js +0 -3
  59. package/dist/cjs/types.js.map +0 -1
package/src/generic.ts CHANGED
@@ -141,21 +141,149 @@ function sharedArraySchema(arr: unknown[], fieldName: string): string[] | null {
141
141
  return canonicalFields;
142
142
  }
143
143
 
144
+ // ── Nested object flattening (v3.2) ──────────────────────────────────────
145
+
146
+ interface FlatLeaf {
147
+ path: string; // ">" separated path (e.g. "customer>name")
148
+ keys: string[]; // key chain to traverse from row object
149
+ }
150
+
151
+ function analyzeFlattenable(arr: unknown[], fieldName: string, parentPath: string): FlatLeaf[] | null {
152
+ let canonicalShape: Record<string, 'scalar' | 'nested'> | null = null;
153
+
154
+ for (const item of arr) {
155
+ const obj = item as Record<string, unknown>;
156
+ if (!(fieldName in obj) || obj[fieldName] === null || obj[fieldName] === undefined) continue;
157
+ const v = obj[fieldName];
158
+ if (typeof v !== 'object' || Array.isArray(v)) return null;
159
+
160
+ const keys = Object.keys(v as Record<string, unknown>);
161
+
162
+ if (!canonicalShape) {
163
+ canonicalShape = {};
164
+ for (const k of keys) {
165
+ if (k.includes('>')) return null;
166
+ const val = (v as Record<string, unknown>)[k];
167
+ if (val !== null && val !== undefined && typeof val === 'object' && !Array.isArray(val)) {
168
+ canonicalShape[k] = 'nested';
169
+ } else if (Array.isArray(val)) {
170
+ return null;
171
+ } else {
172
+ canonicalShape[k] = 'scalar';
173
+ }
174
+ }
175
+ } else {
176
+ if (keys.length !== Object.keys(canonicalShape).length) return null;
177
+ for (const k of keys) {
178
+ if (!(k in canonicalShape)) return null;
179
+ const val = (v as Record<string, unknown>)[k];
180
+ const expected = canonicalShape[k];
181
+ if (expected === 'scalar') {
182
+ if (val !== null && val !== undefined && typeof val === 'object') return null;
183
+ } else if (expected === 'nested') {
184
+ if (val !== null && val !== undefined) {
185
+ if (typeof val !== 'object' || Array.isArray(val)) return null;
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ if (!canonicalShape) return null;
193
+
194
+ const currentPath = parentPath ? parentPath + '>' + fieldName : fieldName;
195
+ const parentKeys = parentPath ? [...parentPath.split('>'), fieldName] : [fieldName];
196
+
197
+ const leaves: FlatLeaf[] = [];
198
+ for (const k of Object.keys(canonicalShape)) {
199
+ if (canonicalShape[k] === 'scalar') {
200
+ leaves.push({ path: currentPath + '>' + k, keys: [...parentKeys, k] });
201
+ } else {
202
+ const subArr = arr.map(item => {
203
+ const obj = item as Record<string, unknown>;
204
+ if (!(fieldName in obj) || obj[fieldName] === null || obj[fieldName] === undefined) return {};
205
+ return obj[fieldName];
206
+ });
207
+ const subLeaves = analyzeFlattenable(subArr as unknown[], k, currentPath);
208
+ if (!subLeaves || subLeaves.length === 0) return null;
209
+ leaves.push(...subLeaves);
210
+ }
211
+ }
212
+
213
+ // Guard: reject if any row has non-null object with all-null leaves.
214
+ if (leaves.length > 0) {
215
+ for (const item of arr) {
216
+ const obj = item as Record<string, unknown>;
217
+ if (!(fieldName in obj) || obj[fieldName] === null || obj[fieldName] === undefined) continue;
218
+ const allNull = leaves.every(leaf => {
219
+ const val = resolveKeyChain(item, leaf.keys);
220
+ return val.exists && val.value === null;
221
+ });
222
+ if (allNull) return null;
223
+ }
224
+ }
225
+
226
+ return leaves;
227
+ }
228
+
229
+ function resolveKeyChain(item: unknown, keys: string[]): { value: unknown; exists: boolean } {
230
+ if (keys.length === 0) return { value: undefined, exists: false };
231
+ const obj = item as Record<string, unknown>;
232
+ if (typeof obj !== 'object' || obj === null) return { value: undefined, exists: false };
233
+ if (!(keys[0] in obj)) return { value: undefined, exists: false };
234
+ let current: unknown = obj[keys[0]];
235
+ if (current === null || current === undefined) return { value: current, exists: true };
236
+ for (let i = 1; i < keys.length; i++) {
237
+ if (typeof current !== 'object' || current === null) return { value: undefined, exists: false };
238
+ const c = current as Record<string, unknown>;
239
+ if (!(keys[i] in c)) return { value: undefined, exists: false };
240
+ current = c[keys[i]];
241
+ }
242
+ return { value: current, exists: true };
243
+ }
244
+
245
+ // ── End flattening helpers ───────────────────────────────────────────────
246
+
144
247
  function encodeTabular(headerPrefix: string, arr: unknown[], fields: string[], depth: number): string {
145
248
  const prefix = indent(depth);
146
249
 
147
- // Pre-compute inline schemas and shared array schemas.
250
+ // Phase 0: Analyze fields for flattening.
251
+ const flattenMap = new Map<string, FlatLeaf[]>();
252
+ for (const f of fields) {
253
+ const leaves = analyzeFlattenable(arr, f, '');
254
+ if (leaves && leaves.length > 0) {
255
+ flattenMap.set(f, leaves);
256
+ }
257
+ }
258
+
259
+ // Build expanded column list.
260
+ type ColType = 'flat' | 'original';
261
+ interface FlatColumn { headerName: string; colType: ColType; field: string; keys: string[]; }
262
+ const columns: FlatColumn[] = [];
263
+ for (const f of fields) {
264
+ const leaves = flattenMap.get(f);
265
+ if (leaves) {
266
+ for (const leaf of leaves) {
267
+ columns.push({ headerName: formatKey(leaf.path), colType: 'flat', field: f, keys: leaf.keys });
268
+ }
269
+ } else {
270
+ columns.push({ headerName: formatKey(f), colType: 'original', field: f, keys: [] });
271
+ }
272
+ }
273
+
274
+ // Pre-compute inline schemas and shared array schemas (skip flattened fields).
148
275
  const inlineSchemas = new Map<string, string[]>();
149
276
  const sharedArrSchemas = new Map<string, string[]>();
150
277
  for (const f of fields) {
278
+ if (flattenMap.has(f)) continue;
151
279
  const ifs = inlineSchemaFields(arr, f);
152
280
  if (ifs) inlineSchemas.set(f, ifs);
153
281
  const sas = sharedArraySchema(arr, f);
154
282
  if (sas) sharedArrSchemas.set(f, sas);
155
283
  }
156
284
 
157
- const fmtFields = fields.map(f => formatKey(f));
158
- let out = `${headerPrefix}[${arr.length}]{${fmtFields.join(',')}}\n`;
285
+ const headerFields = columns.map(c => c.headerName);
286
+ let out = `${headerPrefix}[${arr.length}]{${headerFields.join(',')}}\n`;
159
287
 
160
288
  for (let i = 0; i < arr.length; i++) {
161
289
  const obj = arr[i] as Record<string, unknown>;
@@ -163,14 +291,38 @@ function encodeTabular(headerPrefix: string, arr: unknown[], fields: string[], d
163
291
  const attachments: { name: string; value: unknown; inline: boolean; inlineFields?: string[] }[] = [];
164
292
  let rowHasAttachment = false;
165
293
 
166
- for (const f of fields) {
294
+ for (const col of columns) {
295
+ if (col.colType === 'flat') {
296
+ // Resolve value via key chain.
297
+ if (!(col.keys[0] in obj)) {
298
+ cells.push('~');
299
+ } else {
300
+ // Check if top-level field is null.
301
+ const topVal = obj[col.keys[0]];
302
+ if (topVal === null || topVal === undefined) {
303
+ cells.push(topVal === null ? '-' : '~');
304
+ } else {
305
+ const resolved = resolveKeyChain(obj, col.keys);
306
+ if (!resolved.exists) {
307
+ cells.push('~');
308
+ } else if (resolved.value === null || resolved.value === undefined) {
309
+ cells.push('-');
310
+ } else {
311
+ cells.push(formatScalar(resolved.value, 0x7c));
312
+ }
313
+ }
314
+ }
315
+ continue;
316
+ }
317
+
318
+ // Original (non-flattened) field.
319
+ const f = col.field;
167
320
  if (!(f in obj)) { cells.push('~'); continue; }
168
321
  const v = obj[f];
169
322
  if (v === null || v === undefined) { cells.push('-'); continue; }
170
323
  if (typeof v === 'object') {
171
324
  const ifs = inlineSchemas.get(f);
172
325
  if (ifs && !Array.isArray(v)) {
173
- // Inline schema: first row declares, subsequent use bare ^.
174
326
  if (i === 0) {
175
327
  const fmtIF = ifs.map(k => formatKey(k));
176
328
  cells.push(`^{${fmtIF.join(',')}}`);
package/src/scalar.ts CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  const JSON_NUMBER_RE = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
7
7
  const NUMERIC_LIKE_RE = /^[+-]\.?\d|^\.\d|^0\d/;
8
+ const INLINE_ARRAY_RE = /\[[^\]]*\]\s*:/;
8
9
 
9
10
  /** Check if a string value must be quoted per Section 2.4. */
10
11
  export function needsQuote(s: string): boolean {
@@ -14,6 +15,7 @@ export function needsQuote(s: string): boolean {
14
15
  if (NUMERIC_LIKE_RE.test(s)) return true;
15
16
  if (s[0] === ' ' || s[s.length - 1] === ' ') return true;
16
17
  if (s[0] === '#' || s[0] === '@' || s[0] === '.') return true;
18
+ if (INLINE_ARRAY_RE.test(s)) return true;
17
19
  for (let i = 0; i < s.length; i++) {
18
20
  const c = s.charCodeAt(i);
19
21
  if (c === 0x22 || c === 0x5c || c < 0x20 || c === 0x0a || c === 0x0d ||
@@ -1,9 +0,0 @@
1
- export type { Symbol, Edge, Payload, DeltaPayload, Components } from './types.js';
2
- export { KIND_ABBREV, KIND_EXPAND } from './constants.js';
3
- export { encode } from './encode.js';
4
- export { decode } from './decode.js';
5
- export { encodeGeneric } from './generic.js';
6
- export { decodeGeneric } from './decode_generic.js';
7
- export { formatScalar, formatKey, parseScalar, needsQuote, quoteString } from './scalar.js';
8
- export { StreamEncoder, type StreamWriter, type StreamOptions } from './stream.js';
9
- export { GenericStreamEncoder } from './stream_generic.js';
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GenericStreamEncoder = exports.StreamEncoder = exports.quoteString = exports.needsQuote = exports.parseScalar = exports.formatKey = exports.formatScalar = exports.decodeGeneric = exports.encodeGeneric = exports.decode = exports.encode = exports.KIND_EXPAND = exports.KIND_ABBREV = void 0;
4
- var constants_js_1 = require("./constants.js");
5
- Object.defineProperty(exports, "KIND_ABBREV", { enumerable: true, get: function () { return constants_js_1.KIND_ABBREV; } });
6
- Object.defineProperty(exports, "KIND_EXPAND", { enumerable: true, get: function () { return constants_js_1.KIND_EXPAND; } });
7
- var encode_js_1 = require("./encode.js");
8
- Object.defineProperty(exports, "encode", { enumerable: true, get: function () { return encode_js_1.encode; } });
9
- var decode_js_1 = require("./decode.js");
10
- Object.defineProperty(exports, "decode", { enumerable: true, get: function () { return decode_js_1.decode; } });
11
- var generic_js_1 = require("./generic.js");
12
- Object.defineProperty(exports, "encodeGeneric", { enumerable: true, get: function () { return generic_js_1.encodeGeneric; } });
13
- var decode_generic_js_1 = require("./decode_generic.js");
14
- Object.defineProperty(exports, "decodeGeneric", { enumerable: true, get: function () { return decode_generic_js_1.decodeGeneric; } });
15
- var scalar_js_1 = require("./scalar.js");
16
- Object.defineProperty(exports, "formatScalar", { enumerable: true, get: function () { return scalar_js_1.formatScalar; } });
17
- Object.defineProperty(exports, "formatKey", { enumerable: true, get: function () { return scalar_js_1.formatKey; } });
18
- Object.defineProperty(exports, "parseScalar", { enumerable: true, get: function () { return scalar_js_1.parseScalar; } });
19
- Object.defineProperty(exports, "needsQuote", { enumerable: true, get: function () { return scalar_js_1.needsQuote; } });
20
- Object.defineProperty(exports, "quoteString", { enumerable: true, get: function () { return scalar_js_1.quoteString; } });
21
- var stream_js_1 = require("./stream.js");
22
- Object.defineProperty(exports, "StreamEncoder", { enumerable: true, get: function () { return stream_js_1.StreamEncoder; } });
23
- var stream_generic_js_1 = require("./stream_generic.js");
24
- Object.defineProperty(exports, "GenericStreamEncoder", { enumerable: true, get: function () { return stream_generic_js_1.GenericStreamEncoder; } });
25
- //# sourceMappingURL=browser.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":";;;AAEA,+CAA0D;AAAjD,2GAAA,WAAW,OAAA;AAAE,2GAAA,WAAW,OAAA;AACjC,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AACf,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AACf,2CAA6C;AAApC,2GAAA,aAAa,OAAA;AACtB,yDAAoD;AAA3C,kHAAA,aAAa,OAAA;AACtB,yCAA4F;AAAnF,yGAAA,YAAY,OAAA;AAAE,sGAAA,SAAS,OAAA;AAAE,wGAAA,WAAW,OAAA;AAAE,uGAAA,UAAU,OAAA;AAAE,wGAAA,WAAW,OAAA;AACtE,yCAAmF;AAA1E,0GAAA,aAAa,OAAA;AACtB,yDAA2D;AAAlD,yHAAA,oBAAoB,OAAA"}
package/dist/cjs/cli.d.ts DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * GCF command-line interface: encode, decode, stats.
4
- */
5
- export {};
package/dist/cjs/cli.js DELETED
@@ -1,136 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * GCF command-line interface: encode, decode, stats.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const node_fs_1 = require("node:fs");
8
- const encode_js_1 = require("./encode.js");
9
- const decode_js_1 = require("./decode.js");
10
- const generic_js_1 = require("./generic.js");
11
- const decode_generic_js_1 = require("./decode_generic.js");
12
- const USAGE = `gcf - token-optimized wire format for LLM tool responses
13
-
14
- Usage:
15
- gcf encode [file] Encode JSON graph payload to GCF (stdin if no file)
16
- gcf decode [file] Decode GCF graph text to JSON (stdin if no file)
17
- gcf encode-generic [file] Encode generic JSON to GCF (stdin if no file)
18
- gcf decode-generic [file] Decode generic GCF to JSON (stdin if no file)
19
- gcf stats [file] Compare token counts: JSON vs GCF (stdin if no file)
20
- gcf version Print version
21
-
22
- Examples:
23
- gcf encode < payload.json
24
- gcf decode < payload.gcf
25
- gcf encode-generic < data.json
26
- gcf decode-generic < data.gcf
27
- gcf stats payload.json
28
- `;
29
- function readInput(args) {
30
- if (args.length > 0 && args[0] !== '-') {
31
- return (0, node_fs_1.readFileSync)(args[0], 'utf-8');
32
- }
33
- return (0, node_fs_1.readFileSync)(0, 'utf-8');
34
- }
35
- function payloadFromJSON(data) {
36
- const obj = JSON.parse(data);
37
- return {
38
- tool: obj.tool ?? '',
39
- tokenBudget: obj.tokenBudget ?? 0,
40
- tokensUsed: obj.tokensUsed ?? 0,
41
- packRoot: obj.packRoot ?? '',
42
- symbols: (obj.symbols ?? []).map((s) => ({
43
- qualifiedName: s.qualifiedName,
44
- kind: s.kind,
45
- score: s.score,
46
- provenance: s.provenance,
47
- distance: s.distance ?? 0,
48
- })),
49
- edges: (obj.edges ?? []).map((e) => ({
50
- source: e.source,
51
- target: e.target,
52
- edgeType: e.edgeType,
53
- status: e.status ?? '',
54
- })),
55
- };
56
- }
57
- function payloadToJSON(p) {
58
- return JSON.stringify({
59
- tool: p.tool,
60
- tokensUsed: p.tokensUsed,
61
- tokenBudget: p.tokenBudget,
62
- packRoot: p.packRoot ?? '',
63
- symbols: p.symbols.map(s => ({
64
- qualifiedName: s.qualifiedName,
65
- kind: s.kind,
66
- score: s.score,
67
- provenance: s.provenance,
68
- distance: s.distance,
69
- })),
70
- edges: p.edges.map(e => ({
71
- source: e.source,
72
- target: e.target,
73
- edgeType: e.edgeType,
74
- ...(e.status ? { status: e.status } : {}),
75
- })),
76
- }, null, 2);
77
- }
78
- function doEncode(data) {
79
- const p = payloadFromJSON(data);
80
- process.stdout.write((0, encode_js_1.encode)(p));
81
- }
82
- function doDecode(data) {
83
- const p = (0, decode_js_1.decode)(data);
84
- console.log(payloadToJSON(p));
85
- }
86
- function doStats(data) {
87
- const p = payloadFromJSON(data);
88
- const gcfOutput = (0, encode_js_1.encode)(p);
89
- const jsonTokens = Math.floor(data.trim().length / 4);
90
- const gcfTokens = Math.floor(gcfOutput.trim().length / 4);
91
- const savings = jsonTokens > 0 ? 100 * (1 - gcfTokens / jsonTokens) : 0;
92
- const barWidth = 30;
93
- const jsonBar = '█'.repeat(barWidth);
94
- const gcfFilled = jsonTokens > 0 ? Math.round((gcfTokens * barWidth) / jsonTokens) : 0;
95
- const gcfBar = '█'.repeat(gcfFilled) + '░'.repeat(barWidth - gcfFilled);
96
- console.log(`Payload: ${p.symbols.length} symbols, ${p.edges.length} edges\n`);
97
- console.log(` JSON ${jsonBar} ${jsonTokens} tokens`);
98
- console.log(` GCF ${gcfBar} ${gcfTokens} tokens`);
99
- console.log(`\n Savings: ${Math.round(savings)}% fewer tokens with GCF`);
100
- }
101
- const args = process.argv.slice(2);
102
- const cmd = args[0];
103
- switch (cmd) {
104
- case 'encode':
105
- doEncode(readInput(args.slice(1)));
106
- break;
107
- case 'decode':
108
- doDecode(readInput(args.slice(1)));
109
- break;
110
- case 'encode-generic':
111
- process.stdout.write((0, generic_js_1.encodeGeneric)(JSON.parse(readInput(args.slice(1)))));
112
- break;
113
- case 'decode-generic':
114
- console.log(JSON.stringify((0, decode_generic_js_1.decodeGeneric)(readInput(args.slice(1))), null, 2));
115
- break;
116
- case 'stats':
117
- doStats(readInput(args.slice(1)));
118
- break;
119
- case 'version':
120
- console.log('gcf 0.1.0');
121
- break;
122
- case '-h':
123
- case '--help':
124
- case 'help':
125
- process.stdout.write(USAGE);
126
- break;
127
- default:
128
- if (!cmd) {
129
- process.stderr.write(USAGE);
130
- process.exit(1);
131
- }
132
- process.stderr.write(`unknown command: ${cmd}\n\n`);
133
- process.stderr.write(USAGE);
134
- process.exit(1);
135
- }
136
- //# sourceMappingURL=cli.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * KindAbbrev maps full kind names to short GCF abbreviations.
3
- */
4
- export declare const KIND_ABBREV: Record<string, string>;
5
- /**
6
- * KindExpand is the reverse of KindAbbrev: maps abbreviations back to full kind names.
7
- */
8
- export declare const KIND_EXPAND: Record<string, string>;
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.KIND_EXPAND = exports.KIND_ABBREV = void 0;
4
- /**
5
- * KindAbbrev maps full kind names to short GCF abbreviations.
6
- */
7
- exports.KIND_ABBREV = {
8
- function: 'fn',
9
- type: 'type',
10
- method: 'method',
11
- interface: 'iface',
12
- var: 'var',
13
- const: 'const',
14
- resource: 'resource',
15
- table: 'table',
16
- class: 'class',
17
- selector: 'selector',
18
- field: 'field',
19
- route_handler: 'route',
20
- external: 'ext',
21
- file: 'file',
22
- package: 'pkg',
23
- service: 'svc',
24
- };
25
- /**
26
- * KindExpand is the reverse of KindAbbrev: maps abbreviations back to full kind names.
27
- */
28
- exports.KIND_EXPAND = {
29
- fn: 'function',
30
- type: 'type',
31
- method: 'method',
32
- iface: 'interface',
33
- var: 'var',
34
- const: 'const',
35
- resource: 'resource',
36
- table: 'table',
37
- class: 'class',
38
- selector: 'selector',
39
- field: 'field',
40
- route: 'route_handler',
41
- ext: 'external',
42
- file: 'file',
43
- pkg: 'package',
44
- svc: 'service',
45
- };
46
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,WAAW,GAA2B;IACjD,QAAQ,EAAE,IAAI;IACd,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,OAAO;IAClB,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,OAAO;IACtB,QAAQ,EAAE,KAAK;IACf,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;CACf,CAAC;AAEF;;GAEG;AACU,QAAA,WAAW,GAA2B;IACjD,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,WAAW;IAClB,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,eAAe;IACtB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,SAAS;CACf,CAAC"}
@@ -1,5 +0,0 @@
1
- import type { Payload } from './types.js';
2
- /**
3
- * Decode parses GCF text back into a Payload.
4
- */
5
- export declare function decode(input: string): Payload;
@@ -1,197 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.decode = decode;
4
- const constants_js_1 = require("./constants.js");
5
- /**
6
- * Decode parses GCF text back into a Payload.
7
- */
8
- function decode(input) {
9
- const lines = input.split('\n');
10
- if (lines.length === 0) {
11
- throw new Error('gcf: empty input');
12
- }
13
- const header = lines[0];
14
- if (!header.startsWith('GCF ')) {
15
- throw new Error(`gcf: invalid header, expected 'GCF ...' got "${header}"`);
16
- }
17
- const p = {
18
- tool: '',
19
- tokenBudget: 0,
20
- tokensUsed: 0,
21
- symbols: [],
22
- edges: [],
23
- };
24
- // Parse header fields.
25
- parseHeader(header.slice(4), p);
26
- // v3.1: tool field is optional (SHOULD be present for MCP tool responses, not required).
27
- // Detect delta mode.
28
- const isDelta = header.includes(' delta=true');
29
- const validDeltaSections = new Set(['removed', 'added', 'edges_removed', 'edges_added']);
30
- // Parse body: symbols and edges.
31
- const symbols = [];
32
- const symByID = new Map();
33
- let currentDistance = 0;
34
- let inEdges = false;
35
- for (let i = 1; i < lines.length; i++) {
36
- let line = lines[i].replace(/\r$/, '');
37
- if (line === '')
38
- continue;
39
- // Skip ##! summary trailer.
40
- if (line.startsWith('##! '))
41
- continue;
42
- // Group header.
43
- if (line.startsWith('## ')) {
44
- let group = line.slice(3);
45
- // Strip bracket suffix: "edges [200]" -> "edges"
46
- const bracketIdx = group.indexOf(' [');
47
- if (bracketIdx >= 0) {
48
- group = group.slice(0, bracketIdx);
49
- }
50
- if (isDelta && !validDeltaSections.has(group)) {
51
- throw new Error(`malformed_delta: invalid delta section "${group}"`);
52
- }
53
- inEdges = group === 'edges';
54
- if (!inEdges) {
55
- switch (group) {
56
- case 'targets':
57
- currentDistance = 0;
58
- break;
59
- case 'related':
60
- currentDistance = 1;
61
- break;
62
- case 'extended':
63
- currentDistance = 2;
64
- break;
65
- default:
66
- if (group.startsWith('distance_')) {
67
- const d = parseInt(group.slice(9), 10);
68
- if (!isNaN(d)) {
69
- currentDistance = d;
70
- }
71
- }
72
- break;
73
- }
74
- }
75
- continue;
76
- }
77
- // Comment.
78
- if (line.startsWith('# ')) {
79
- continue;
80
- }
81
- if (inEdges) {
82
- const edge = parseEdgeLine(line, symByID);
83
- p.edges.push(edge);
84
- }
85
- else {
86
- const { symbol, id } = parseSymbolLine(line, currentDistance);
87
- symbols.push(symbol);
88
- symByID.set(id, symbol);
89
- }
90
- }
91
- p.symbols = symbols;
92
- return p;
93
- }
94
- function parseHeader(fields, p) {
95
- const parts = fields.split(/\s+/);
96
- for (const part of parts) {
97
- const eqIdx = part.indexOf('=');
98
- if (eqIdx < 0)
99
- continue;
100
- const key = part.slice(0, eqIdx);
101
- const value = part.slice(eqIdx + 1);
102
- switch (key) {
103
- case 'tool':
104
- p.tool = value;
105
- break;
106
- case 'budget': {
107
- const v = parseInt(value, 10);
108
- if (isNaN(v))
109
- throw new Error(`gcf: invalid budget "${value}"`);
110
- p.tokenBudget = v;
111
- break;
112
- }
113
- case 'tokens': {
114
- const v = parseInt(value, 10);
115
- if (isNaN(v))
116
- throw new Error(`gcf: invalid tokens "${value}"`);
117
- p.tokensUsed = v;
118
- break;
119
- }
120
- case 'pack_root':
121
- p.packRoot = value;
122
- break;
123
- case 'symbols':
124
- // Informational, reconstructed from parsed symbols.
125
- break;
126
- }
127
- }
128
- }
129
- function parseSymbolLine(line, distance) {
130
- if (!line.startsWith('@')) {
131
- throw new Error(`gcf: expected symbol line starting with @, got "${line}"`);
132
- }
133
- const parts = line.split(/\s+/);
134
- if (parts.length < 5) {
135
- throw new Error(`invalid_node_line: symbol line needs at least 5 fields, got ${parts.length} in "${line}"`);
136
- }
137
- const idStr = parts[0].slice(1); // strip @
138
- const id = parseInt(idStr, 10);
139
- if (isNaN(id)) {
140
- throw new Error(`invalid_symbol_id: invalid symbol id "${idStr}"`);
141
- }
142
- let kind = parts[1];
143
- if (constants_js_1.KIND_EXPAND[kind]) {
144
- kind = constants_js_1.KIND_EXPAND[kind];
145
- }
146
- const qname = parts[2];
147
- const score = parseFloat(parts[3]);
148
- if (isNaN(score)) {
149
- throw new Error(`invalid_score: invalid score "${parts[3]}"`);
150
- }
151
- const provenance = parts[4];
152
- return {
153
- symbol: {
154
- qualifiedName: qname,
155
- kind,
156
- score,
157
- provenance,
158
- distance,
159
- },
160
- id,
161
- };
162
- }
163
- function parseEdgeLine(line, symByID) {
164
- const parts = line.split(/\s+/);
165
- if (parts.length < 2) {
166
- throw new Error(`gcf: edge line needs at least 2 fields, got "${line}"`);
167
- }
168
- const ref = parts[0];
169
- const ltIdx = ref.indexOf('<');
170
- if (ltIdx < 0) {
171
- throw new Error(`invalid_edge_syntax: edge line missing '<' separator in "${ref}"`);
172
- }
173
- const targetIDStr = ref.slice(1, ltIdx); // strip leading @
174
- const sourceIDStr = ref.slice(ltIdx + 2); // strip <@
175
- const targetID = parseInt(targetIDStr, 10);
176
- if (isNaN(targetID)) {
177
- throw new Error(`gcf: invalid target id "${targetIDStr}"`);
178
- }
179
- const sourceID = parseInt(sourceIDStr, 10);
180
- if (isNaN(sourceID)) {
181
- throw new Error(`gcf: invalid source id "${sourceIDStr}"`);
182
- }
183
- const targetSym = symByID.get(targetID);
184
- const sourceSym = symByID.get(sourceID);
185
- if (!targetSym || !sourceSym) {
186
- throw new Error(`unknown_edge_reference: edge references unknown symbol id(s): target=${targetID} source=${sourceID}`);
187
- }
188
- const edgeType = parts[1];
189
- const status = parts.length >= 3 ? parts[2] : undefined;
190
- return {
191
- source: sourceSym.qualifiedName,
192
- target: targetSym.qualifiedName,
193
- edgeType,
194
- status,
195
- };
196
- }
197
- //# sourceMappingURL=decode.js.map