@codragraph/cli 2.1.0 → 2.1.4
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.
- package/README.md +62 -21
- package/dist/_shared/cgdb/schema-constants.d.ts +2 -2
- package/dist/_shared/cgdb/schema-constants.d.ts.map +1 -1
- package/dist/_shared/cgdb/schema-constants.js +3 -0
- package/dist/_shared/cgdb/schema-constants.js.map +1 -1
- package/dist/_shared/feature-clusters.d.ts +99 -0
- package/dist/_shared/feature-clusters.d.ts.map +1 -0
- package/dist/_shared/feature-clusters.js +2 -0
- package/dist/_shared/feature-clusters.js.map +1 -0
- package/dist/_shared/graph/types.d.ts +16 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/pipeline.d.ts +1 -1
- package/dist/_shared/pipeline.d.ts.map +1 -1
- package/dist/cli/ai-context.js +4 -0
- package/dist/cli/analyze.js +46 -26
- package/dist/cli/index.js +39 -1
- package/dist/cli/serve.d.ts +1 -0
- package/dist/cli/serve.js +3 -1
- package/dist/cli/setup.js +42 -21
- package/dist/cli/status.d.ts +13 -0
- package/dist/cli/status.js +99 -0
- package/dist/cli/tool.d.ts +25 -0
- package/dist/cli/tool.js +74 -0
- package/dist/config/ignore-service.js +2 -0
- package/dist/config/supported-languages.d.ts +3 -3
- package/dist/config/supported-languages.js +3 -3
- package/dist/core/cgdb/cgdb-adapter.js +19 -3
- package/dist/core/cgdb/csv-generator.js +33 -2
- package/dist/core/cgdb/schema.d.ts +2 -1
- package/dist/core/cgdb/schema.js +55 -0
- package/dist/core/embeddings/embedder.js +4 -2
- package/dist/core/graphstore/cgdb-row-source.js +3 -2
- package/dist/core/graphstore/index.d.ts +1 -1
- package/dist/core/graphstore/index.js +1 -1
- package/dist/core/group/bridge-db.js +42 -10
- package/dist/core/group/service.d.ts +16 -0
- package/dist/core/group/service.js +360 -0
- package/dist/core/ingestion/emit-references.d.ts +1 -1
- package/dist/core/ingestion/emit-references.js +1 -1
- package/dist/core/ingestion/feature-cluster-processor.d.ts +62 -0
- package/dist/core/ingestion/feature-cluster-processor.js +626 -0
- package/dist/core/ingestion/finalize-orchestrator.js +1 -1
- package/dist/core/ingestion/model/registration-table.js +1 -0
- package/dist/core/ingestion/model/resolve.d.ts +2 -2
- package/dist/core/ingestion/model/resolve.js +3 -3
- package/dist/core/ingestion/model/semantic-model.d.ts +1 -1
- package/dist/core/ingestion/model/semantic-model.js +1 -1
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -1
- package/dist/core/ingestion/model/symbol-table.js +1 -1
- package/dist/core/ingestion/pipeline-phases/feature-clusters.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/feature-clusters.js +88 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/index.js +1 -0
- package/dist/core/ingestion/pipeline.d.ts +4 -0
- package/dist/core/ingestion/pipeline.js +9 -5
- package/dist/core/run-analyze.d.ts +21 -0
- package/dist/core/run-analyze.js +213 -6
- package/dist/core/search/hybrid-search.js +11 -3
- package/dist/mcp/core/embedder.js +5 -2
- package/dist/mcp/local/local-backend.d.ts +12 -0
- package/dist/mcp/local/local-backend.js +381 -3
- package/dist/mcp/resources.js +139 -0
- package/dist/mcp/tools.js +174 -2
- package/dist/server/api.d.ts +14 -2
- package/dist/server/api.js +206 -7
- package/dist/server/mcp-http.d.ts +22 -0
- package/dist/server/mcp-http.js +21 -2
- package/dist/server/web-dashboard.d.ts +28 -0
- package/dist/server/web-dashboard.js +61 -0
- package/dist/storage/repo-manager.d.ts +6 -1
- package/dist/storage/repo-manager.js +5 -1
- package/dist/types/pipeline.d.ts +2 -0
- package/dist/web/assets/agent-D5lb0zXz.js +1089 -0
- package/dist/web/assets/architectureDiagram-EMZXCZ2Q-CZtc99v_.js +36 -0
- package/dist/web/assets/blockDiagram-IGV67L2C-BtoUp-6Y.js +132 -0
- package/dist/web/assets/c4Diagram-DFAF54RM-C4Hl3J2U.js +10 -0
- package/dist/web/assets/chunk-3GS5O3IE-DkUjU0WD.js +231 -0
- package/dist/web/assets/chunk-3YCYZ6SJ-CQkVgT_z.js +1 -0
- package/dist/web/assets/chunk-7RZVMHOQ-BitYcNVR.js +338 -0
- package/dist/web/assets/chunk-AEOMTBSW-BgTIXPsY.js +1 -0
- package/dist/web/assets/chunk-H3VCZNTA-Cx5XV_aC.js +13 -0
- package/dist/web/assets/chunk-HN6EAY2L-BBnyTNdB.js +1 -0
- package/dist/web/assets/chunk-KSICW3F5-BYzvDLNI.js +15 -0
- package/dist/web/assets/chunk-O5ABG6QK-dHwHzA6n.js +1 -0
- package/dist/web/assets/chunk-PK6DOVAG-CvsEnugt.js +206 -0
- package/dist/web/assets/chunk-RWUO3TPN-BgRTY0_k.js +1 -0
- package/dist/web/assets/chunk-TBF5ZNIQ-DL5stGM1.js +1 -0
- package/dist/web/assets/chunk-TU3PZOEN-RLyvLcv-.js +1 -0
- package/dist/web/assets/classDiagram-PPOCWD7C-DTr8QIOf.js +1 -0
- package/dist/web/assets/classDiagram-v2-23LJLIIU-DTr8QIOf.js +1 -0
- package/dist/web/assets/context-builder-22jU3V56.js +16 -0
- package/dist/web/assets/cose-bilkent-PNC4W37J-DVhePRYg.js +1 -0
- package/dist/web/assets/dagre-E77IOHMT-Dzx0A6ZU.js +4 -0
- package/dist/web/assets/diagram-H7BISOXX-CC9pRew1.js +43 -0
- package/dist/web/assets/diagram-JC5VWROH-Bau_i9tf.js +24 -0
- package/dist/web/assets/diagram-LXUTUG65-D9_FM2Gt.js +10 -0
- package/dist/web/assets/diagram-WEHSV5V5-BMlayouL.js +24 -0
- package/dist/web/assets/erDiagram-GCSMX5X6-C3dhDFA8.js +85 -0
- package/dist/web/assets/flowDiagram-OTCZ4VVT-CWSFWmhr.js +162 -0
- package/dist/web/assets/ganttDiagram-MUNLMDZQ-D3a67Yol.js +292 -0
- package/dist/web/assets/gitGraphDiagram-3HKGZ4G3-7jmry-vM.js +106 -0
- package/dist/web/assets/index-BgeqpYgd.js +1415 -0
- package/dist/web/assets/index-CT0GtFLZ.css +1 -0
- package/dist/web/assets/infoDiagram-MN7RKWGX-G7lhP0Ib.js +2 -0
- package/dist/web/assets/ishikawaDiagram-YMYX4NHK-DUoJvNP2.js +70 -0
- package/dist/web/assets/journeyDiagram-SO5T7YLQ-RMFPNNqz.js +139 -0
- package/dist/web/assets/kanban-definition-LJHFXRCJ-BzpDs1K9.js +89 -0
- package/dist/web/assets/katex-GD7MH7QM-DBQvrix-.js +261 -0
- package/dist/web/assets/mindmap-definition-2EUWGEK5-Bk0O4roa.js +96 -0
- package/dist/web/assets/pieDiagram-3IATQBI2-DKU7kpgS.js +30 -0
- package/dist/web/assets/quadrantDiagram-E256RVCF-BY0TGWCS.js +7 -0
- package/dist/web/assets/requirementDiagram-M5DCFWZL-DLHOVTSv.js +84 -0
- package/dist/web/assets/sankeyDiagram-L3NBLAOT-DVMj5rX2.js +10 -0
- package/dist/web/assets/sequenceDiagram-ZOUHS735-CJC73bV-.js +157 -0
- package/dist/web/assets/stateDiagram-MLPALWAM-BCFyESls.js +1 -0
- package/dist/web/assets/stateDiagram-v2-B5LQ5ZB2-DahzzIca.js +1 -0
- package/dist/web/assets/timeline-definition-5SPVSISX-TRSDRgPw.js +120 -0
- package/dist/web/assets/vennDiagram-IE5QUKF5-DNy7HRBM.js +34 -0
- package/dist/web/assets/wardley-RL74JXVD-BCRCBASE-B-eZEzf9.js +161 -0
- package/dist/web/assets/wardleyDiagram-XU3VSMPF-BP-r1xzR.js +20 -0
- package/dist/web/assets/xychartDiagram-ZHJ5623Y-Dr9r7a35.js +7 -0
- package/dist/web/codragraph-logo-512.png +0 -0
- package/dist/web/codragraph-logo.png +0 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/index.html +36 -0
- package/hooks/claude/codragraph-hook.cjs +24 -9
- package/hooks/claude/pre-tool-use.sh +6 -1
- package/package.json +15 -4
- package/scripts/build.js +75 -16
- package/scripts/patch-tree-sitter-swift.cjs +0 -1
- package/skills/codragraph-cli.md +17 -1
- package/skills/codragraph-guide.md +6 -2
- package/skills/codragraph-onboarding.md +2 -2
- package/vendor/leiden/index.cjs +272 -285
- package/vendor/leiden/utils.cjs +264 -274
- package/dist/_shared/lbug/schema-constants.d.ts +0 -16
- package/dist/_shared/lbug/schema-constants.d.ts.map +0 -1
- package/dist/_shared/lbug/schema-constants.js +0 -67
- package/dist/_shared/lbug/schema-constants.js.map +0 -1
- package/dist/core/graphstore/lbug-row-source.d.ts +0 -19
- package/dist/core/graphstore/lbug-row-source.js +0 -141
- package/dist/core/lbug/content-read.d.ts +0 -46
- package/dist/core/lbug/content-read.js +0 -64
- package/dist/core/lbug/csv-generator.d.ts +0 -29
- package/dist/core/lbug/csv-generator.js +0 -492
- package/dist/core/lbug/lbug-adapter.d.ts +0 -176
- package/dist/core/lbug/lbug-adapter.js +0 -1320
- package/dist/core/lbug/pool-adapter.d.ts +0 -93
- package/dist/core/lbug/pool-adapter.js +0 -550
- package/dist/core/lbug/schema.d.ts +0 -62
- package/dist/core/lbug/schema.js +0 -502
- package/dist/mcp/core/lbug-adapter.d.ts +0 -5
- package/dist/mcp/core/lbug-adapter.js +0 -5
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LadybugDB schema constants — single source of truth.
|
|
3
|
-
*
|
|
4
|
-
* NODE_TABLES and REL_TYPES define what the knowledge graph can contain.
|
|
5
|
-
* Both CLI and web must agree on these for data compatibility.
|
|
6
|
-
*
|
|
7
|
-
* Full DDL schemas remain in each package's own schema.ts because
|
|
8
|
-
* the CLI uses native LadybugDB and the web uses WASM.
|
|
9
|
-
*/
|
|
10
|
-
export const NODE_TABLES = [
|
|
11
|
-
'File',
|
|
12
|
-
'Folder',
|
|
13
|
-
'Function',
|
|
14
|
-
'Class',
|
|
15
|
-
'Interface',
|
|
16
|
-
'Method',
|
|
17
|
-
'CodeElement',
|
|
18
|
-
'Community',
|
|
19
|
-
'Process',
|
|
20
|
-
'Section',
|
|
21
|
-
'Struct',
|
|
22
|
-
'Enum',
|
|
23
|
-
'Macro',
|
|
24
|
-
'Typedef',
|
|
25
|
-
'Union',
|
|
26
|
-
'Namespace',
|
|
27
|
-
'Trait',
|
|
28
|
-
'Impl',
|
|
29
|
-
'TypeAlias',
|
|
30
|
-
'Const',
|
|
31
|
-
'Static',
|
|
32
|
-
'Variable',
|
|
33
|
-
'Property',
|
|
34
|
-
'Record',
|
|
35
|
-
'Delegate',
|
|
36
|
-
'Annotation',
|
|
37
|
-
'Constructor',
|
|
38
|
-
'Template',
|
|
39
|
-
'Module',
|
|
40
|
-
'Route',
|
|
41
|
-
'Tool',
|
|
42
|
-
];
|
|
43
|
-
export const REL_TABLE_NAME = 'CodeRelation';
|
|
44
|
-
export const REL_TYPES = [
|
|
45
|
-
'CONTAINS',
|
|
46
|
-
'DEFINES',
|
|
47
|
-
'IMPORTS',
|
|
48
|
-
'CALLS',
|
|
49
|
-
'EXTENDS',
|
|
50
|
-
'IMPLEMENTS',
|
|
51
|
-
'HAS_METHOD',
|
|
52
|
-
'HAS_PROPERTY',
|
|
53
|
-
'ACCESSES',
|
|
54
|
-
'METHOD_OVERRIDES',
|
|
55
|
-
'OVERRIDES', // Legacy compat alias — kept until all stored indexes are migrated
|
|
56
|
-
'METHOD_IMPLEMENTS',
|
|
57
|
-
'MEMBER_OF',
|
|
58
|
-
'STEP_IN_PROCESS',
|
|
59
|
-
'HANDLES_ROUTE',
|
|
60
|
-
'FETCHES',
|
|
61
|
-
'HANDLES_TOOL',
|
|
62
|
-
'ENTRY_POINT_OF',
|
|
63
|
-
'WRAPS',
|
|
64
|
-
'QUERIES',
|
|
65
|
-
];
|
|
66
|
-
export const EMBEDDING_TABLE_NAME = 'CodeEmbedding';
|
|
67
|
-
//# sourceMappingURL=schema-constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema-constants.js","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM;IACN,QAAQ;IACR,UAAU;IACV,OAAO;IACP,WAAW;IACX,QAAQ;IACR,aAAa;IACb,WAAW;IACX,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;IACN,OAAO;IACP,SAAS;IACT,OAAO;IACP,WAAW;IACX,OAAO;IACP,MAAM;IACN,WAAW;IACX,OAAO;IACP,QAAQ;IACR,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,aAAa;IACb,UAAU;IACV,QAAQ;IACR,OAAO;IACP,MAAM;CACE,CAAC;AAIX,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,UAAU;IACV,SAAS;IACT,SAAS;IACT,OAAO;IACP,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,UAAU;IACV,kBAAkB;IAClB,WAAW,EAAE,mEAAmE;IAChF,mBAAmB;IACnB,WAAW;IACX,iBAAiB;IACjB,eAAe;IACf,SAAS;IACT,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,SAAS;CACD,CAAC;AAIX,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adapter exposing a live LadybugDB instance as a `@codragraph/graphstore`
|
|
3
|
-
* `RowSource`. Used by the analyze pipeline (Phase 4) to snapshot the
|
|
4
|
-
* loaded graph into the content-addressed store.
|
|
5
|
-
*
|
|
6
|
-
* Best-effort by design: any table that errors at query time is skipped
|
|
7
|
-
* (with the failure surfaced through the optional `onSkip` callback) so
|
|
8
|
-
* the surrounding analyze flow never breaks because the versioning hook
|
|
9
|
-
* misbehaves.
|
|
10
|
-
*/
|
|
11
|
-
import type { RowSource } from '@codragraph/graphstore';
|
|
12
|
-
import { type NodeTableName } from '../../_shared/index.js';
|
|
13
|
-
export interface LbugRowSourceOptions {
|
|
14
|
-
/** Filter the node tables enumerated by `listNodeTables` — defaults to every NODE_TABLE. */
|
|
15
|
-
readonly nodeTables?: readonly NodeTableName[];
|
|
16
|
-
/** Called with `(table, error)` when a table query fails — defaults to a no-op. */
|
|
17
|
-
readonly onSkip?: (tableName: string, error: unknown) => void;
|
|
18
|
-
}
|
|
19
|
-
export declare const createLbugRowSource: (opts?: LbugRowSourceOptions) => RowSource;
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adapter exposing a live LadybugDB instance as a `@codragraph/graphstore`
|
|
3
|
-
* `RowSource`. Used by the analyze pipeline (Phase 4) to snapshot the
|
|
4
|
-
* loaded graph into the content-addressed store.
|
|
5
|
-
*
|
|
6
|
-
* Best-effort by design: any table that errors at query time is skipped
|
|
7
|
-
* (with the failure surfaced through the optional `onSkip` callback) so
|
|
8
|
-
* the surrounding analyze flow never breaks because the versioning hook
|
|
9
|
-
* misbehaves.
|
|
10
|
-
*/
|
|
11
|
-
import { NODE_TABLES, REL_TABLE_NAME } from '../../_shared/index.js';
|
|
12
|
-
import { executeQuery } from '../lbug/lbug-adapter.js';
|
|
13
|
-
export const createLbugRowSource = (opts = {}) => {
|
|
14
|
-
const onSkip = opts.onSkip ?? (() => { });
|
|
15
|
-
const tables = opts.nodeTables ?? NODE_TABLES;
|
|
16
|
-
const listNodeTables = async () => {
|
|
17
|
-
return [...tables];
|
|
18
|
-
};
|
|
19
|
-
const streamNodeTable = async function* (tableName) {
|
|
20
|
-
let rows;
|
|
21
|
-
try {
|
|
22
|
-
// `MATCH (n:T) RETURN n` returns one row per node. The node value
|
|
23
|
-
// is reachable as either `row.n` (named-column form) or `row[0]`
|
|
24
|
-
// (positional form) depending on the LadybugDB result-shape mode;
|
|
25
|
-
// we accept both, mirroring the resilient pattern used by
|
|
26
|
-
// `core/search/bm25-index.ts` for FTS results. Tables that do not
|
|
27
|
-
// exist on disk for a given repo throw here — we treat that as
|
|
28
|
-
// "no rows" via the onSkip callback rather than a hard failure.
|
|
29
|
-
rows = await executeQuery(`MATCH (n:${tableName}) RETURN n`);
|
|
30
|
-
}
|
|
31
|
-
catch (err) {
|
|
32
|
-
onSkip(tableName, err);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
let yielded = 0;
|
|
36
|
-
for (const raw of rows) {
|
|
37
|
-
const node = unwrapNode(raw);
|
|
38
|
-
if (!node)
|
|
39
|
-
continue;
|
|
40
|
-
yield normalizeNodeRow(node);
|
|
41
|
-
yielded++;
|
|
42
|
-
}
|
|
43
|
-
// If the query reported rows but none unwrapped, surface that as a
|
|
44
|
-
// skip so the analyze log makes the silent-empty failure mode
|
|
45
|
-
// visible instead of producing a 0-row snapshot for the table.
|
|
46
|
-
if (rows.length > 0 && yielded === 0) {
|
|
47
|
-
onSkip(tableName, new Error(`lbug-row-source: query returned ${rows.length} row(s) for "${tableName}" but none had an unwrappable node — ` +
|
|
48
|
-
`result shape changed? expected row.n or row[0] to be the node`));
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const streamEdges = async function* () {
|
|
52
|
-
let rows;
|
|
53
|
-
try {
|
|
54
|
-
// Project `from`/`to`/`type` as scalar columns and the full rel as
|
|
55
|
-
// `rel`. Scalars give us a deterministic edge id even if the rel
|
|
56
|
-
// payload's shape changes; `rel` carries any extra properties for
|
|
57
|
-
// hashing.
|
|
58
|
-
rows = await executeQuery(`MATCH (a)-[r:${REL_TABLE_NAME}]->(b) RETURN a.id AS \`from\`, b.id AS \`to\`, r.type AS type, r AS rel`);
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
onSkip(REL_TABLE_NAME, err);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
let yielded = 0;
|
|
65
|
-
for (const raw of rows) {
|
|
66
|
-
const r = raw;
|
|
67
|
-
const from = pickField(r, 'from', 0);
|
|
68
|
-
const to = pickField(r, 'to', 1);
|
|
69
|
-
const type = pickField(r, 'type', 2);
|
|
70
|
-
const rel = pickField(r, 'rel', 3);
|
|
71
|
-
if (typeof from !== 'string' || typeof to !== 'string')
|
|
72
|
-
continue;
|
|
73
|
-
yield normalizeEdgeRow({ from, to, type, rel: isPlainObject(rel) ? rel : null });
|
|
74
|
-
yielded++;
|
|
75
|
-
}
|
|
76
|
-
if (rows.length > 0 && yielded === 0) {
|
|
77
|
-
onSkip(REL_TABLE_NAME, new Error(`lbug-row-source: edges query returned ${rows.length} row(s) but none had a string from/to — ` +
|
|
78
|
-
`result shape changed?`));
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
return { listNodeTables, streamNodeTable, streamEdges };
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* Pull the node out of an executeQuery result row, accepting either the
|
|
85
|
-
* named-column form (`row.n`) or the positional form (`row[0]`). Returns
|
|
86
|
-
* null when the row is missing or the node value isn't an object — the
|
|
87
|
-
* caller treats that as "skip and surface".
|
|
88
|
-
*/
|
|
89
|
-
const unwrapNode = (raw) => {
|
|
90
|
-
if (!raw || typeof raw !== 'object')
|
|
91
|
-
return null;
|
|
92
|
-
const r = raw;
|
|
93
|
-
const candidate = r['n'] ?? r[0];
|
|
94
|
-
return isPlainObject(candidate) ? candidate : null;
|
|
95
|
-
};
|
|
96
|
-
/** Read a field from an executeQuery row, falling back to the positional index. */
|
|
97
|
-
const pickField = (row, named, positional) => {
|
|
98
|
-
if (!row)
|
|
99
|
-
return undefined;
|
|
100
|
-
return row[named] ?? row[positional];
|
|
101
|
-
};
|
|
102
|
-
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
103
|
-
/**
|
|
104
|
-
* Sanitize a node row for canonical hashing:
|
|
105
|
-
* - Drop LadybugDB-specific internal fields (`_id`, `_label`) that are
|
|
106
|
-
* not content-bearing — including them would make the hash sensitive
|
|
107
|
-
* to internal storage offsets and break dedup across snapshots.
|
|
108
|
-
* - Sort keys deterministically (canonical JSON in the serializer
|
|
109
|
-
* already does this, but doing it once here keeps the row payload
|
|
110
|
-
* stable when we ever swap engines).
|
|
111
|
-
*/
|
|
112
|
-
const normalizeNodeRow = (node) => {
|
|
113
|
-
const out = {};
|
|
114
|
-
for (const key of Object.keys(node).sort()) {
|
|
115
|
-
if (key === '_id' || key === '_label')
|
|
116
|
-
continue;
|
|
117
|
-
out[key] = node[key];
|
|
118
|
-
}
|
|
119
|
-
return out;
|
|
120
|
-
};
|
|
121
|
-
const normalizeEdgeRow = (r) => {
|
|
122
|
-
const props = {};
|
|
123
|
-
if (r.rel && typeof r.rel === 'object') {
|
|
124
|
-
for (const key of Object.keys(r.rel).sort()) {
|
|
125
|
-
// Skip the synthetic from/to/type that show up under `rel` too —
|
|
126
|
-
// we already project them as top-level columns and don't want
|
|
127
|
-
// duplication in the canonical row.
|
|
128
|
-
if (key === 'from' || key === 'to' || key === 'type')
|
|
129
|
-
continue;
|
|
130
|
-
if (key.startsWith('_'))
|
|
131
|
-
continue;
|
|
132
|
-
props[key] = r.rel[key];
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return {
|
|
136
|
-
from: String(r.from),
|
|
137
|
-
to: String(r.to),
|
|
138
|
-
type: typeof r.type === 'string' ? r.type : String(r.type ?? ''),
|
|
139
|
-
...props,
|
|
140
|
-
};
|
|
141
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read-side decoder for `content` columns in lbug node rows.
|
|
3
|
-
*
|
|
4
|
-
* RFC 0001 Phase 2 introduces an optional `contentEncoding` column on
|
|
5
|
-
* every node table that has `content`. Default is `'none'` (passthrough)
|
|
6
|
-
* so existing reads keep working unchanged. When a writer opts into
|
|
7
|
-
* `--compress brotli|zstd`, the column carries the encoding tag and the
|
|
8
|
-
* `content` column carries base64-encoded compressed bytes — readers
|
|
9
|
-
* MUST run those bytes back through `decodeContent` before handing them
|
|
10
|
-
* to a consumer (MCP tool result, HTTP API response, embedding model,
|
|
11
|
-
* LLM input).
|
|
12
|
-
*
|
|
13
|
-
* Centralizing the decode in one helper has two benefits:
|
|
14
|
-
* 1. Shim sites are 2-line changes: add `, n.contentEncoding AS
|
|
15
|
-
* contentEncoding` to the Cypher RETURN, and pipe the row through
|
|
16
|
-
* `decodeContentField` (or `decodeContentRow`) at the boundary.
|
|
17
|
-
* 2. Anyone hunting for "where does the read path decode compressed
|
|
18
|
-
* bytes" greps for `decodeContentField` and gets every site in one
|
|
19
|
-
* shot — no per-table feature detection scattered across files.
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* Decode a single (content, contentEncoding) pair from a Cypher row.
|
|
23
|
-
*
|
|
24
|
-
* Returns the input content unchanged when:
|
|
25
|
-
* - the encoding is missing / empty / `'none'` (the common case for
|
|
26
|
-
* 1.6.x – 1.7.x indexes, plus any 1.8+ index written without
|
|
27
|
-
* `--compress`);
|
|
28
|
-
* - content is null/undefined (caller decides whether that's an error);
|
|
29
|
-
* - content is not a string (pre-Phase-2 indexes never wrote non-string
|
|
30
|
-
* content, but defensive: don't crash a read path on a malformed row).
|
|
31
|
-
*
|
|
32
|
-
* Throws (via `decodeContent`) only when the row claims an encoding this
|
|
33
|
-
* CLI build can't decode — that's a forward-compat error and the right
|
|
34
|
-
* behavior is to fail loudly rather than return wrong content.
|
|
35
|
-
*/
|
|
36
|
-
export declare function decodeContentField(content: unknown, encoding: unknown): string | undefined;
|
|
37
|
-
/**
|
|
38
|
-
* Apply `decodeContentField` to a row that carries `content` and
|
|
39
|
-
* `contentEncoding` keys (or their numeric column-index aliases).
|
|
40
|
-
*
|
|
41
|
-
* The numeric-fallback shape (`r[N]`) mirrors LadybugDB's row format —
|
|
42
|
-
* driver versions vary on whether named keys are populated, so existing
|
|
43
|
-
* read sites do `r.content ?? r[N]`. This helper accepts the same
|
|
44
|
-
* pattern. Returns a NEW object (does not mutate input).
|
|
45
|
-
*/
|
|
46
|
-
export declare function decodeContentRow<T extends Record<string, unknown>>(row: T, contentKey?: keyof T, encodingKey?: keyof T): T;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read-side decoder for `content` columns in lbug node rows.
|
|
3
|
-
*
|
|
4
|
-
* RFC 0001 Phase 2 introduces an optional `contentEncoding` column on
|
|
5
|
-
* every node table that has `content`. Default is `'none'` (passthrough)
|
|
6
|
-
* so existing reads keep working unchanged. When a writer opts into
|
|
7
|
-
* `--compress brotli|zstd`, the column carries the encoding tag and the
|
|
8
|
-
* `content` column carries base64-encoded compressed bytes — readers
|
|
9
|
-
* MUST run those bytes back through `decodeContent` before handing them
|
|
10
|
-
* to a consumer (MCP tool result, HTTP API response, embedding model,
|
|
11
|
-
* LLM input).
|
|
12
|
-
*
|
|
13
|
-
* Centralizing the decode in one helper has two benefits:
|
|
14
|
-
* 1. Shim sites are 2-line changes: add `, n.contentEncoding AS
|
|
15
|
-
* contentEncoding` to the Cypher RETURN, and pipe the row through
|
|
16
|
-
* `decodeContentField` (or `decodeContentRow`) at the boundary.
|
|
17
|
-
* 2. Anyone hunting for "where does the read path decode compressed
|
|
18
|
-
* bytes" greps for `decodeContentField` and gets every site in one
|
|
19
|
-
* shot — no per-table feature detection scattered across files.
|
|
20
|
-
*/
|
|
21
|
-
import { decodeContent } from '@codragraph/graphstore';
|
|
22
|
-
/**
|
|
23
|
-
* Decode a single (content, contentEncoding) pair from a Cypher row.
|
|
24
|
-
*
|
|
25
|
-
* Returns the input content unchanged when:
|
|
26
|
-
* - the encoding is missing / empty / `'none'` (the common case for
|
|
27
|
-
* 1.6.x – 1.7.x indexes, plus any 1.8+ index written without
|
|
28
|
-
* `--compress`);
|
|
29
|
-
* - content is null/undefined (caller decides whether that's an error);
|
|
30
|
-
* - content is not a string (pre-Phase-2 indexes never wrote non-string
|
|
31
|
-
* content, but defensive: don't crash a read path on a malformed row).
|
|
32
|
-
*
|
|
33
|
-
* Throws (via `decodeContent`) only when the row claims an encoding this
|
|
34
|
-
* CLI build can't decode — that's a forward-compat error and the right
|
|
35
|
-
* behavior is to fail loudly rather than return wrong content.
|
|
36
|
-
*/
|
|
37
|
-
export function decodeContentField(content, encoding) {
|
|
38
|
-
if (content === undefined || content === null)
|
|
39
|
-
return undefined;
|
|
40
|
-
if (typeof content !== 'string')
|
|
41
|
-
return content;
|
|
42
|
-
if (typeof encoding !== 'string' || encoding === '' || encoding === 'none') {
|
|
43
|
-
return content;
|
|
44
|
-
}
|
|
45
|
-
return decodeContent(content, encoding);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Apply `decodeContentField` to a row that carries `content` and
|
|
49
|
-
* `contentEncoding` keys (or their numeric column-index aliases).
|
|
50
|
-
*
|
|
51
|
-
* The numeric-fallback shape (`r[N]`) mirrors LadybugDB's row format —
|
|
52
|
-
* driver versions vary on whether named keys are populated, so existing
|
|
53
|
-
* read sites do `r.content ?? r[N]`. This helper accepts the same
|
|
54
|
-
* pattern. Returns a NEW object (does not mutate input).
|
|
55
|
-
*/
|
|
56
|
-
export function decodeContentRow(row, contentKey = 'content', encodingKey = 'contentEncoding') {
|
|
57
|
-
const content = row[contentKey];
|
|
58
|
-
if (content === undefined || content === null)
|
|
59
|
-
return row;
|
|
60
|
-
const encoding = row[encodingKey];
|
|
61
|
-
if (typeof encoding !== 'string' || encoding === '' || encoding === 'none')
|
|
62
|
-
return row;
|
|
63
|
-
return { ...row, [contentKey]: decodeContentField(content, encoding) };
|
|
64
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CSV Generator for LadybugDB Hybrid Schema
|
|
3
|
-
*
|
|
4
|
-
* Streams CSV rows directly to disk files in a single pass over graph nodes.
|
|
5
|
-
* File contents are lazy-read from disk per-node to avoid holding the entire
|
|
6
|
-
* repo in RAM. Rows are buffered (FLUSH_EVERY) before writing to minimize
|
|
7
|
-
* per-row Promise overhead.
|
|
8
|
-
*
|
|
9
|
-
* RFC 4180 Compliant:
|
|
10
|
-
* - Fields containing commas, double quotes, or newlines are enclosed in double quotes
|
|
11
|
-
* - Double quotes within fields are escaped by doubling them ("")
|
|
12
|
-
* - All fields are consistently quoted for safety with code content
|
|
13
|
-
*/
|
|
14
|
-
import { KnowledgeGraph } from '../graph/types.js';
|
|
15
|
-
import { NodeTableName } from './schema.js';
|
|
16
|
-
import { type ContentEncoding } from '@codragraph/graphstore';
|
|
17
|
-
export declare const sanitizeUTF8: (str: string) => string;
|
|
18
|
-
export declare const escapeCSVField: (value: string | number | undefined | null) => string;
|
|
19
|
-
export declare const escapeCSVNumber: (value: number | undefined | null, defaultValue?: number) => string;
|
|
20
|
-
export declare const isBinaryContent: (content: string) => boolean;
|
|
21
|
-
export interface StreamedCSVResult {
|
|
22
|
-
nodeFiles: Map<NodeTableName, {
|
|
23
|
-
csvPath: string;
|
|
24
|
-
rows: number;
|
|
25
|
-
}>;
|
|
26
|
-
relCsvPath: string;
|
|
27
|
-
relRows: number;
|
|
28
|
-
}
|
|
29
|
-
export declare const streamAllCSVsToDisk: (graph: KnowledgeGraph, repoPath: string, csvDir: string, compress?: ContentEncoding) => Promise<StreamedCSVResult>;
|