gitnexus 1.6.7-rc.1 → 1.6.7-rc.2
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/dist/_shared/graph/types.d.ts +18 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +10 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/core/ingestion/model/registration-table.js +3 -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-phases/registry.d.ts +56 -0
- package/dist/core/ingestion/pipeline-phases/registry.js +48 -0
- package/dist/core/ingestion/pipeline.d.ts +21 -0
- package/dist/core/ingestion/pipeline.js +28 -20
- package/dist/core/ingestion/taint/source-sink-config.d.ts +36 -0
- package/dist/core/ingestion/taint/source-sink-config.js +16 -0
- package/dist/core/ingestion/taint/source-sink-registry.d.ts +27 -0
- package/dist/core/ingestion/taint/source-sink-registry.js +35 -0
- package/dist/core/lbug/csv-generator.js +14 -0
- package/dist/core/lbug/lbug-adapter.js +12 -0
- package/dist/core/lbug/schema.d.ts +2 -1
- package/dist/core/lbug/schema.js +22 -0
- package/dist/server/api.d.ts +1 -0
- package/dist/server/api.js +17 -2
- package/package.json +1 -1
- package/scripts/spikes/s1-reaching-def-index-bench.ts +151 -0
- package/scripts/spikes/s2-postdom-prototype.ts +162 -0
- package/web/assets/{agent-EkX7webX.js → agent-CKPMqImC.js} +1 -1
- package/web/assets/{architectureDiagram-UL44E2DR-BoczH8cv.js → architectureDiagram-UL44E2DR-D1EXI0zA.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-By5HB3b-.js → chunk-LCXTWHL2-Dfmux4m1.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-BQE_DkpL.js → chunk-RG4AUYOV-CAkzcoRj.js} +1 -1
- package/web/assets/{classDiagram-KGZ6W3CR-Dj_02GUH.js → classDiagram-KGZ6W3CR-Bv93af_b.js} +1 -1
- package/web/assets/{classDiagram-v2-72OJOZXJ-D-NArMpf.js → classDiagram-v2-72OJOZXJ-CLfEqHUa.js} +1 -1
- package/web/assets/{diagram-3NCE3AQN-VXtXDO95.js → diagram-3NCE3AQN-BqAtKUpW.js} +1 -1
- package/web/assets/{diagram-GF46GFSD-B1qab2Ah.js → diagram-GF46GFSD-CaBG6n6o.js} +1 -1
- package/web/assets/{diagram-QXG6HAR7-BSCHGzzT.js → diagram-QXG6HAR7-CZ-O3rcV.js} +1 -1
- package/web/assets/{diagram-WEQXMOUZ-DHtknmNT.js → diagram-WEQXMOUZ-P4lSL4GH.js} +1 -1
- package/web/assets/{erDiagram-L5TCEMPS-Db-IYTmm.js → erDiagram-L5TCEMPS-QN2eEP1e.js} +1 -1
- package/web/assets/{flowDiagram-H6V6AXG4-BHDoyVoW.js → flowDiagram-H6V6AXG4-CXbXImlN.js} +1 -1
- package/web/assets/{index-BR0IhgbR.js → index-CG6q8eTs.js} +6 -6
- package/web/assets/{infoDiagram-3YFTVSEB-6h8wbWEe.js → infoDiagram-3YFTVSEB-DmLICZx1.js} +1 -1
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-Dx2OkPk1.js → ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-CIIEZfqV.js → kanban-definition-75IXJCU3-DgDi9oJT.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-DUAqydRq.js → mindmap-definition-2TDM6QVE-CwR5sBB-.js} +1 -1
- package/web/assets/{pieDiagram-CU6KROY3-BntYuYZa.js → pieDiagram-CU6KROY3-By8g6f6B.js} +1 -1
- package/web/assets/{requirementDiagram-JXO7QTGE-QCD6I29n.js → requirementDiagram-JXO7QTGE-7oDcJ1_J.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-DScFwLz2.js → sequenceDiagram-VS2MUI6T-FySeKCUy.js} +1 -1
- package/web/assets/{stateDiagram-7D4R322I-AkRAm6Hl.js → stateDiagram-7D4R322I-CB2nABwH.js} +1 -1
- package/web/assets/{stateDiagram-v2-36443NZ5-BCK1vigR.js → stateDiagram-v2-36443NZ5-COBGd2RL.js} +1 -1
- package/web/assets/{timeline-definition-O6YCAMPW-BvpIVXjX.js → timeline-definition-O6YCAMPW-Ds2CnVZK.js} +1 -1
- package/web/assets/{vennDiagram-MWXL3ELB-BYGWk6dK.js → vennDiagram-MWXL3ELB-DUIEwXWp.js} +1 -1
- package/web/assets/{wardleyDiagram-CUQ6CDDI-Dk1z7H2T.js → wardleyDiagram-CUQ6CDDI-DEiFPQih.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-2N6NCSWN.js → xychartDiagram-N2JHSOCM-BUbayhST.js} +1 -1
- package/web/index.html +1 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Do NOT add Node.js-specific or browser-specific imports here.
|
|
6
6
|
*/
|
|
7
7
|
import { SupportedLanguages } from '../languages.js';
|
|
8
|
-
export type NodeLabel = 'Project' | 'Package' | 'Module' | 'Folder' | 'File' | 'Class' | 'Function' | 'Method' | 'Variable' | 'Interface' | 'Enum' | 'Decorator' | 'Import' | 'Type' | 'CodeElement' | 'Community' | 'Process' | 'Struct' | 'Macro' | 'Typedef' | 'Union' | 'Namespace' | 'Trait' | 'Impl' | 'TypeAlias' | 'Const' | 'Static' | 'Property' | 'Record' | 'Delegate' | 'Annotation' | 'Constructor' | 'Template' | 'Section' | 'Route' | 'Tool';
|
|
8
|
+
export type NodeLabel = 'Project' | 'Package' | 'Module' | 'Folder' | 'File' | 'Class' | 'Function' | 'Method' | 'Variable' | 'Interface' | 'Enum' | 'Decorator' | 'Import' | 'Type' | 'CodeElement' | 'Community' | 'Process' | 'Struct' | 'Macro' | 'Typedef' | 'Union' | 'Namespace' | 'Trait' | 'Impl' | 'TypeAlias' | 'Const' | 'Static' | 'Property' | 'Record' | 'Delegate' | 'Annotation' | 'Constructor' | 'Template' | 'Section' | 'Route' | 'Tool' | 'BasicBlock';
|
|
9
9
|
export type NodeProperties = {
|
|
10
10
|
name: string;
|
|
11
11
|
filePath: string;
|
|
@@ -45,6 +45,7 @@ export type NodeProperties = {
|
|
|
45
45
|
responseKeys?: string[];
|
|
46
46
|
errorKeys?: string[];
|
|
47
47
|
middleware?: string[];
|
|
48
|
+
text?: string;
|
|
48
49
|
[key: string]: unknown;
|
|
49
50
|
};
|
|
50
51
|
export type RelationshipType = 'CONTAINS' | 'CALLS' | 'INHERITS' | 'METHOD_OVERRIDES' | 'METHOD_IMPLEMENTS' | 'IMPORTS' | 'USES' | 'DEFINES' | 'DECORATES' | 'IMPLEMENTS' | 'EXTENDS' | 'HAS_METHOD' | 'HAS_PROPERTY' | 'ACCESSES' | 'MEMBER_OF' | 'STEP_IN_PROCESS' | 'HANDLES_ROUTE' | 'FETCHES' | 'HANDLES_TOOL' | 'ENTRY_POINT_OF' | 'WRAPS' | 'QUERIES'
|
|
@@ -63,7 +64,22 @@ export type RelationshipType = 'CONTAINS' | 'CALLS' | 'INHERITS' | 'METHOD_OVERR
|
|
|
63
64
|
* `reason` encodes the event name: `vue-emit: <eventName>`.
|
|
64
65
|
* Complements `BINDS_EVENT_HANDLER`; a Cypher query joining on the
|
|
65
66
|
* component File node reveals all (emitter, handler) pairs. */
|
|
66
|
-
| 'EMITS_EVENT'
|
|
67
|
+
| 'EMITS_EVENT'
|
|
68
|
+
/** Control-flow edge between two BasicBlock nodes (intra-procedural CFG). */
|
|
69
|
+
| 'CFG'
|
|
70
|
+
/** Data-dependence edge: a definition of `variable` reaches a use of it.
|
|
71
|
+
* The `variable` name is stored in the relation's existing `reason` column
|
|
72
|
+
* (M0/S1 verdict: LadybugDB has no secondary index on relationship
|
|
73
|
+
* properties, so a dedicated indexed column would not speed the
|
|
74
|
+
* variable-filtered path query). */
|
|
75
|
+
| 'REACHING_DEF'
|
|
76
|
+
/** A tainted value flows from source toward sink. */
|
|
77
|
+
| 'TAINTED'
|
|
78
|
+
/** A sanitizer clears taint along a flow. */
|
|
79
|
+
| 'SANITIZES'
|
|
80
|
+
/** Materialized source→sink taint path. Working name — final name/representation
|
|
81
|
+
* is confirmed when M3/M4 emits it; no persisted edge exists before then. */
|
|
82
|
+
| 'TAINT_PATH';
|
|
67
83
|
export interface GraphNode {
|
|
68
84
|
id: string;
|
|
69
85
|
label: NodeLabel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/graph/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,QAAQ,GACR,UAAU,GACV,WAAW,GACX,MAAM,GACN,WAAW,GACX,QAAQ,GACR,MAAM,GACN,aAAa,GACb,WAAW,GACX,SAAS,GAET,QAAQ,GACR,OAAO,GACP,SAAS,GACT,OAAO,GACP,WAAW,GACX,OAAO,GACP,MAAM,GACN,WAAW,GACX,OAAO,GACP,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,aAAa,GACb,UAAU,GACV,SAAS,GACT,OAAO,GACP,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/graph/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* Full DDL schemas remain in each package's own schema.ts because
|
|
8
8
|
* the CLI uses native LadybugDB and the web uses WASM.
|
|
9
9
|
*/
|
|
10
|
-
export declare const NODE_TABLES: readonly ["File", "Folder", "Function", "Class", "Interface", "Method", "CodeElement", "Community", "Process", "Section", "Struct", "Enum", "Macro", "Typedef", "Union", "Namespace", "Trait", "Impl", "TypeAlias", "Const", "Static", "Variable", "Property", "Record", "Delegate", "Annotation", "Constructor", "Template", "Module", "Route", "Tool"];
|
|
10
|
+
export declare const NODE_TABLES: readonly ["File", "Folder", "Function", "Class", "Interface", "Method", "CodeElement", "Community", "Process", "Section", "Struct", "Enum", "Macro", "Typedef", "Union", "Namespace", "Trait", "Impl", "TypeAlias", "Const", "Static", "Variable", "Property", "Record", "Delegate", "Annotation", "Constructor", "Template", "Module", "Route", "Tool", "BasicBlock"];
|
|
11
11
|
export type NodeTableName = (typeof NODE_TABLES)[number];
|
|
12
12
|
export declare const REL_TABLE_NAME = "CodeRelation";
|
|
13
|
-
export declare const REL_TYPES: readonly ["CONTAINS", "DEFINES", "IMPORTS", "CALLS", "EXTENDS", "IMPLEMENTS", "HAS_METHOD", "HAS_PROPERTY", "ACCESSES", "METHOD_OVERRIDES", "OVERRIDES", "METHOD_IMPLEMENTS", "MEMBER_OF", "STEP_IN_PROCESS", "HANDLES_ROUTE", "FETCHES", "HANDLES_TOOL", "ENTRY_POINT_OF", "WRAPS", "QUERIES"];
|
|
13
|
+
export declare const REL_TYPES: readonly ["CONTAINS", "DEFINES", "IMPORTS", "CALLS", "EXTENDS", "IMPLEMENTS", "HAS_METHOD", "HAS_PROPERTY", "ACCESSES", "METHOD_OVERRIDES", "OVERRIDES", "METHOD_IMPLEMENTS", "MEMBER_OF", "STEP_IN_PROCESS", "HANDLES_ROUTE", "FETCHES", "HANDLES_TOOL", "ENTRY_POINT_OF", "WRAPS", "QUERIES", "CFG", "REACHING_DEF", "TAINTED", "SANITIZES", "TAINT_PATH"];
|
|
14
14
|
export type RelType = (typeof REL_TYPES)[number];
|
|
15
15
|
export declare const EMBEDDING_TABLE_NAME = "CodeEmbedding";
|
|
16
16
|
//# sourceMappingURL=schema-constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-constants.d.ts","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"schema-constants.d.ts","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,WAAW,wWAkCd,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,eAAO,MAAM,SAAS,8VA6BZ,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,eAAO,MAAM,oBAAoB,kBAAkB,CAAC"}
|
|
@@ -39,6 +39,8 @@ export const NODE_TABLES = [
|
|
|
39
39
|
'Module',
|
|
40
40
|
'Route',
|
|
41
41
|
'Tool',
|
|
42
|
+
// Taint/PDG substrate (issue #2080) — inert until M1 (#2081) emits blocks.
|
|
43
|
+
'BasicBlock',
|
|
42
44
|
];
|
|
43
45
|
export const REL_TABLE_NAME = 'CodeRelation';
|
|
44
46
|
export const REL_TYPES = [
|
|
@@ -62,6 +64,14 @@ export const REL_TYPES = [
|
|
|
62
64
|
'ENTRY_POINT_OF',
|
|
63
65
|
'WRAPS',
|
|
64
66
|
'QUERIES',
|
|
67
|
+
// Taint/PDG substrate (issue #2080) — reserved edge types, emitted by no
|
|
68
|
+
// phase yet (CFG → M1, REACHING_DEF → M2, TAINTED/SANITIZES/TAINT_PATH →
|
|
69
|
+
// M3/M4). REACHING_DEF's variable name rides the relation's `reason` column.
|
|
70
|
+
'CFG',
|
|
71
|
+
'REACHING_DEF',
|
|
72
|
+
'TAINTED',
|
|
73
|
+
'SANITIZES',
|
|
74
|
+
'TAINT_PATH',
|
|
65
75
|
];
|
|
66
76
|
export const EMBEDDING_TABLE_NAME = 'CodeEmbedding';
|
|
67
77
|
//# sourceMappingURL=schema-constants.js.map
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;IACN,2EAA2E;IAC3E,YAAY;CACJ,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;IACT,yEAAyE;IACzE,yEAAyE;IACzE,6EAA6E;IAC7E,KAAK;IACL,cAAc;IACd,SAAS;IACT,WAAW;IACX,YAAY;CACJ,CAAC;AAIX,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
|
|
@@ -116,6 +116,9 @@ const LABEL_BEHAVIOR = {
|
|
|
116
116
|
Section: 'inert',
|
|
117
117
|
Route: 'inert',
|
|
118
118
|
Tool: 'inert',
|
|
119
|
+
// Taint/PDG substrate (issue #2080) — a control-flow node, never a
|
|
120
|
+
// symbol-resolution target. Inert: file index only, no owner scope.
|
|
121
|
+
BasicBlock: 'inert',
|
|
119
122
|
};
|
|
120
123
|
// ---------------------------------------------------------------------------
|
|
121
124
|
// Derived runtime collections — all keyed off LABEL_BEHAVIOR
|
|
@@ -21,3 +21,4 @@ export { processesPhase, type ProcessesOutput } from './processes.js';
|
|
|
21
21
|
export { runPipeline } from './runner.js';
|
|
22
22
|
export type { PipelinePhase, PipelineContext, PhaseResult } from './types.js';
|
|
23
23
|
export { getPhaseOutput } from './types.js';
|
|
24
|
+
export { PhaseRegistry, type RegisterPhaseOptions } from './registry.js';
|
|
@@ -22,3 +22,4 @@ export { processesPhase } from './processes.js';
|
|
|
22
22
|
// ── Infrastructure ─────────────────────────────────────────────────────────
|
|
23
23
|
export { runPipeline } from './runner.js';
|
|
24
24
|
export { getPhaseOutput } from './types.js';
|
|
25
|
+
export { PhaseRegistry } from './registry.js';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase registry seam (issue #2080, taint/PDG substrate M0).
|
|
3
|
+
*
|
|
4
|
+
* A small, behaviour-preserving abstraction over phase-list *assembly*. Today
|
|
5
|
+
* `buildPhaseList` is a hand-maintained array with a single ad-hoc
|
|
6
|
+
* `if (!skipGraphPhases)` guard; this registry generalises that guard into a
|
|
7
|
+
* per-phase `enabledWhen` predicate so later milestones can register opt-in
|
|
8
|
+
* phases (e.g. CFG → M1 #2081) without editing the array each time.
|
|
9
|
+
*
|
|
10
|
+
* M0 wires the seam with **no behaviour change**: `build(options)` must return
|
|
11
|
+
* a phase list identical in membership and order to the legacy array for every
|
|
12
|
+
* options combination. The registry covers only list assembly — the runner,
|
|
13
|
+
* topological sort, `PipelinePhase.execute`, and any result-extraction guards
|
|
14
|
+
* (e.g. the `skipGraphPhases` check in `runPipelineFromRepo`) are untouched.
|
|
15
|
+
*
|
|
16
|
+
* Generic over the options type so this module depends only on `PipelinePhase`
|
|
17
|
+
* (no import of `PipelineOptions`, which lives in `pipeline.ts` and would
|
|
18
|
+
* otherwise create an import cycle).
|
|
19
|
+
*/
|
|
20
|
+
import type { PipelinePhase } from './types.js';
|
|
21
|
+
/** Options accepted when registering a phase. */
|
|
22
|
+
export interface RegisterPhaseOptions<TOptions> {
|
|
23
|
+
/**
|
|
24
|
+
* Predicate deciding whether this phase is included for a given options
|
|
25
|
+
* object. Absent ⇒ the phase is always enabled. This is the generalised
|
|
26
|
+
* form of the legacy `if (!skipGraphPhases)` guard.
|
|
27
|
+
*
|
|
28
|
+
* `options` is required, not optional: callers normalize an absent options
|
|
29
|
+
* object once at `build()` (e.g. `buildPhaseList` passes `options ?? {}`), so
|
|
30
|
+
* individual predicates read `(o) => !o.skipGraphPhases` without a defensive
|
|
31
|
+
* `?.` on every phase (#2080 review S1).
|
|
32
|
+
*/
|
|
33
|
+
readonly enabledWhen?: (options: TOptions) => boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Ordered registry of pipeline phases. Not a global singleton — callers
|
|
37
|
+
* construct a fresh registry (so registration order is deterministic and there
|
|
38
|
+
* is no import-order or test-isolation hazard) and `build()` it per run.
|
|
39
|
+
*/
|
|
40
|
+
export declare class PhaseRegistry<TOptions = unknown> {
|
|
41
|
+
private readonly registrations;
|
|
42
|
+
/**
|
|
43
|
+
* Register a phase. This is the `registerPhase(phase, { enabledWhen })` seam
|
|
44
|
+
* named in issue #2080. Returns `this` for fluent chaining. Registration
|
|
45
|
+
* order is preserved by `build()`.
|
|
46
|
+
*/
|
|
47
|
+
register(phase: PipelinePhase, options?: RegisterPhaseOptions<TOptions>): this;
|
|
48
|
+
/**
|
|
49
|
+
* Build the ordered phase list for the given options. A phase is included
|
|
50
|
+
* iff it has no `enabledWhen` predicate or its predicate returns `true`.
|
|
51
|
+
* Order matches registration order. `options` is required — callers that may
|
|
52
|
+
* have no options normalize once at the call site (`options ?? {}`) so the
|
|
53
|
+
* predicates never see `undefined`.
|
|
54
|
+
*/
|
|
55
|
+
build(options: TOptions): PipelinePhase[];
|
|
56
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase registry seam (issue #2080, taint/PDG substrate M0).
|
|
3
|
+
*
|
|
4
|
+
* A small, behaviour-preserving abstraction over phase-list *assembly*. Today
|
|
5
|
+
* `buildPhaseList` is a hand-maintained array with a single ad-hoc
|
|
6
|
+
* `if (!skipGraphPhases)` guard; this registry generalises that guard into a
|
|
7
|
+
* per-phase `enabledWhen` predicate so later milestones can register opt-in
|
|
8
|
+
* phases (e.g. CFG → M1 #2081) without editing the array each time.
|
|
9
|
+
*
|
|
10
|
+
* M0 wires the seam with **no behaviour change**: `build(options)` must return
|
|
11
|
+
* a phase list identical in membership and order to the legacy array for every
|
|
12
|
+
* options combination. The registry covers only list assembly — the runner,
|
|
13
|
+
* topological sort, `PipelinePhase.execute`, and any result-extraction guards
|
|
14
|
+
* (e.g. the `skipGraphPhases` check in `runPipelineFromRepo`) are untouched.
|
|
15
|
+
*
|
|
16
|
+
* Generic over the options type so this module depends only on `PipelinePhase`
|
|
17
|
+
* (no import of `PipelineOptions`, which lives in `pipeline.ts` and would
|
|
18
|
+
* otherwise create an import cycle).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Ordered registry of pipeline phases. Not a global singleton — callers
|
|
22
|
+
* construct a fresh registry (so registration order is deterministic and there
|
|
23
|
+
* is no import-order or test-isolation hazard) and `build()` it per run.
|
|
24
|
+
*/
|
|
25
|
+
export class PhaseRegistry {
|
|
26
|
+
registrations = [];
|
|
27
|
+
/**
|
|
28
|
+
* Register a phase. This is the `registerPhase(phase, { enabledWhen })` seam
|
|
29
|
+
* named in issue #2080. Returns `this` for fluent chaining. Registration
|
|
30
|
+
* order is preserved by `build()`.
|
|
31
|
+
*/
|
|
32
|
+
register(phase, options) {
|
|
33
|
+
this.registrations.push({ phase, enabledWhen: options?.enabledWhen });
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the ordered phase list for the given options. A phase is included
|
|
38
|
+
* iff it has no `enabledWhen` predicate or its predicate returns `true`.
|
|
39
|
+
* Order matches registration order. `options` is required — callers that may
|
|
40
|
+
* have no options normalize once at the call site (`options ?? {}`) so the
|
|
41
|
+
* predicates never see `undefined`.
|
|
42
|
+
*/
|
|
43
|
+
build(options) {
|
|
44
|
+
return this.registrations
|
|
45
|
+
.filter((r) => r.enabledWhen === undefined || r.enabledWhen(options))
|
|
46
|
+
.map((r) => r.phase);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type PipelineProgress } from '../../_shared/index.js';
|
|
18
18
|
import { PipelineResult } from '../../types/pipeline.js';
|
|
19
|
+
import { type PipelinePhase } from './pipeline-phases/index.js';
|
|
19
20
|
export interface PipelineOptions {
|
|
20
21
|
/**
|
|
21
22
|
* Skip MRO, community detection, and process extraction for faster test runs.
|
|
@@ -104,4 +105,24 @@ export interface PipelineOptions {
|
|
|
104
105
|
*/
|
|
105
106
|
keepLocalValueSymbols?: boolean;
|
|
106
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* All pipeline phases with their dependency relationships.
|
|
110
|
+
*
|
|
111
|
+
* Phase dependency graph:
|
|
112
|
+
*
|
|
113
|
+
* scan → structure → [markdown, cobol] → parse → [routes, tools, orm]
|
|
114
|
+
* → crossFile → scopeResolution → pruneLocalSymbols
|
|
115
|
+
* → mro → communities → processes
|
|
116
|
+
*
|
|
117
|
+
* To add a new phase: create a file in pipeline-phases/, export the phase
|
|
118
|
+
* object, and `.register()` it at the appropriate position below. Opt-in
|
|
119
|
+
* phases pass an `enabledWhen` predicate (issue #2080 phase-registry seam) —
|
|
120
|
+
* the legacy `if (!skipGraphPhases)` guard is now expressed that way on the
|
|
121
|
+
* three graph phases, with no change in behaviour.
|
|
122
|
+
*
|
|
123
|
+
* Exported for the parity test (`pipeline-phase-registry.test.ts`), which
|
|
124
|
+
* asserts the produced list is byte-identical to the legacy array for every
|
|
125
|
+
* options combination.
|
|
126
|
+
*/
|
|
127
|
+
export declare function buildPhaseList(options?: PipelineOptions): PipelinePhase[];
|
|
107
128
|
export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void, options?: PipelineOptions) => Promise<PipelineResult>;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* See ARCHITECTURE.md for the full phase dependency diagram.
|
|
16
16
|
*/
|
|
17
17
|
import { createKnowledgeGraph } from '../graph/graph.js';
|
|
18
|
-
import { runPipeline, getPhaseOutput, scanPhase, structurePhase, markdownPhase, cobolPhase, parsePhase, routesPhase, toolsPhase, ormPhase, crossFilePhase, scopeResolutionPhase, pruneLocalSymbolsPhase, mroPhase, communitiesPhase, processesPhase, } from './pipeline-phases/index.js';
|
|
18
|
+
import { runPipeline, getPhaseOutput, scanPhase, structurePhase, markdownPhase, cobolPhase, parsePhase, routesPhase, toolsPhase, ormPhase, crossFilePhase, scopeResolutionPhase, pruneLocalSymbolsPhase, mroPhase, communitiesPhase, processesPhase, PhaseRegistry, } from './pipeline-phases/index.js';
|
|
19
19
|
// ── Phase registry ─────────────────────────────────────────────────────────
|
|
20
20
|
/**
|
|
21
21
|
* All pipeline phases with their dependency relationships.
|
|
@@ -27,26 +27,34 @@ import { runPipeline, getPhaseOutput, scanPhase, structurePhase, markdownPhase,
|
|
|
27
27
|
* → mro → communities → processes
|
|
28
28
|
*
|
|
29
29
|
* To add a new phase: create a file in pipeline-phases/, export the phase
|
|
30
|
-
* object, and
|
|
30
|
+
* object, and `.register()` it at the appropriate position below. Opt-in
|
|
31
|
+
* phases pass an `enabledWhen` predicate (issue #2080 phase-registry seam) —
|
|
32
|
+
* the legacy `if (!skipGraphPhases)` guard is now expressed that way on the
|
|
33
|
+
* three graph phases, with no change in behaviour.
|
|
34
|
+
*
|
|
35
|
+
* Exported for the parity test (`pipeline-phase-registry.test.ts`), which
|
|
36
|
+
* asserts the produced list is byte-identical to the legacy array for every
|
|
37
|
+
* options combination.
|
|
31
38
|
*/
|
|
32
|
-
function buildPhaseList(options) {
|
|
33
|
-
|
|
34
|
-
scanPhase
|
|
35
|
-
structurePhase
|
|
36
|
-
markdownPhase
|
|
37
|
-
cobolPhase
|
|
38
|
-
parsePhase
|
|
39
|
-
routesPhase
|
|
40
|
-
toolsPhase
|
|
41
|
-
ormPhase
|
|
42
|
-
crossFilePhase
|
|
43
|
-
scopeResolutionPhase
|
|
44
|
-
pruneLocalSymbolsPhase
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
export function buildPhaseList(options) {
|
|
40
|
+
return (new PhaseRegistry()
|
|
41
|
+
.register(scanPhase)
|
|
42
|
+
.register(structurePhase)
|
|
43
|
+
.register(markdownPhase)
|
|
44
|
+
.register(cobolPhase)
|
|
45
|
+
.register(parsePhase)
|
|
46
|
+
.register(routesPhase)
|
|
47
|
+
.register(toolsPhase)
|
|
48
|
+
.register(ormPhase)
|
|
49
|
+
.register(crossFilePhase)
|
|
50
|
+
.register(scopeResolutionPhase)
|
|
51
|
+
.register(pruneLocalSymbolsPhase)
|
|
52
|
+
.register(mroPhase, { enabledWhen: (o) => !o.skipGraphPhases })
|
|
53
|
+
.register(communitiesPhase, { enabledWhen: (o) => !o.skipGraphPhases })
|
|
54
|
+
.register(processesPhase, { enabledWhen: (o) => !o.skipGraphPhases })
|
|
55
|
+
// Normalize a missing options object once here so phase predicates above
|
|
56
|
+
// take a required PipelineOptions and need no `?.` guard (#2080 review S1).
|
|
57
|
+
.build(options ?? {}));
|
|
50
58
|
}
|
|
51
59
|
// ── Pipeline orchestrator ─────────────────────────────────────────────────
|
|
52
60
|
export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source/sink/sanitizer config model (issue #2080, taint/PDG substrate M0).
|
|
3
|
+
*
|
|
4
|
+
* The per-language taint configuration *shape*. M0 ships only the type and an
|
|
5
|
+
* (empty) registry seam — no analysis consumes it yet. M3 (#2083, intra-proc
|
|
6
|
+
* taint) populates per-language specs and reads them when emitting TAINTED /
|
|
7
|
+
* SANITIZES edges.
|
|
8
|
+
*
|
|
9
|
+
* Kept deliberately minimal: enough for M3 to express "callable X is a
|
|
10
|
+
* source / sink / sanitizer, optionally for argument position N" without M0
|
|
11
|
+
* committing to matcher semantics it cannot yet validate. The shape is
|
|
12
|
+
* expected to grow (e.g. sanitizer escape conditions, return-position taint)
|
|
13
|
+
* when M3 makes contact with real flows; that is a forward-declared-interface
|
|
14
|
+
* design choice, not a finished contract.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Identifies a callable that participates in taint flow. `name` is matched
|
|
18
|
+
* against a resolved callable (simple or qualified name — exact matching
|
|
19
|
+
* semantics are M3's call). `args` optionally narrows to specific 0-based
|
|
20
|
+
* argument positions that carry taint (for a source/sink) or clear it (for a
|
|
21
|
+
* sanitizer); omit to mean "unspecified / all".
|
|
22
|
+
*/
|
|
23
|
+
export interface TaintCallableMatcher {
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly args?: readonly number[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The taint configuration for a single language: which callables introduce
|
|
29
|
+
* taint (sources), which are dangerous to reach with tainted input (sinks),
|
|
30
|
+
* and which clear taint (sanitizers).
|
|
31
|
+
*/
|
|
32
|
+
export interface SourceSinkSanitizerSpec {
|
|
33
|
+
readonly sources: readonly TaintCallableMatcher[];
|
|
34
|
+
readonly sinks: readonly TaintCallableMatcher[];
|
|
35
|
+
readonly sanitizers: readonly TaintCallableMatcher[];
|
|
36
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source/sink/sanitizer config model (issue #2080, taint/PDG substrate M0).
|
|
3
|
+
*
|
|
4
|
+
* The per-language taint configuration *shape*. M0 ships only the type and an
|
|
5
|
+
* (empty) registry seam — no analysis consumes it yet. M3 (#2083, intra-proc
|
|
6
|
+
* taint) populates per-language specs and reads them when emitting TAINTED /
|
|
7
|
+
* SANITIZES edges.
|
|
8
|
+
*
|
|
9
|
+
* Kept deliberately minimal: enough for M3 to express "callable X is a
|
|
10
|
+
* source / sink / sanitizer, optionally for argument position N" without M0
|
|
11
|
+
* committing to matcher semantics it cannot yet validate. The shape is
|
|
12
|
+
* expected to grow (e.g. sanitizer escape conditions, return-position taint)
|
|
13
|
+
* when M3 makes contact with real flows; that is a forward-declared-interface
|
|
14
|
+
* design choice, not a finished contract.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language source/sink/sanitizer registry seam (issue #2080).
|
|
3
|
+
*
|
|
4
|
+
* A keyed registry of {@link SourceSinkSanitizerSpec} by language id. M0 stands
|
|
5
|
+
* up the empty seam — no language is registered and nothing in the pipeline
|
|
6
|
+
* reads it. M3 (#2083) registers per-language specs and queries this registry
|
|
7
|
+
* when emitting taint edges.
|
|
8
|
+
*
|
|
9
|
+
* The store is module-level (matching the codebase's other per-language
|
|
10
|
+
* registries). {@link clearSourceSinkRegistry} resets it for test isolation.
|
|
11
|
+
*/
|
|
12
|
+
import type { SourceSinkSanitizerSpec } from './source-sink-config.js';
|
|
13
|
+
/**
|
|
14
|
+
* Register the taint config for a language. Last-write-wins: re-registering
|
|
15
|
+
* the same `languageId` overwrites the previous spec (so M3 can override a
|
|
16
|
+
* built-in default). Returns nothing.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerSourceSinkConfig(languageId: string, spec: SourceSinkSanitizerSpec): void;
|
|
19
|
+
/**
|
|
20
|
+
* Look up the taint config for a language. Returns `undefined` when no spec is
|
|
21
|
+
* registered (the M0 default for every language) — never throws.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getSourceSinkConfig(languageId: string): SourceSinkSanitizerSpec | undefined;
|
|
24
|
+
/** Language ids that currently have a registered spec. Empty in M0. */
|
|
25
|
+
export declare function registeredTaintLanguages(): string[];
|
|
26
|
+
/** Reset the registry. Primarily for test isolation. */
|
|
27
|
+
export declare function clearSourceSinkRegistry(): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language source/sink/sanitizer registry seam (issue #2080).
|
|
3
|
+
*
|
|
4
|
+
* A keyed registry of {@link SourceSinkSanitizerSpec} by language id. M0 stands
|
|
5
|
+
* up the empty seam — no language is registered and nothing in the pipeline
|
|
6
|
+
* reads it. M3 (#2083) registers per-language specs and queries this registry
|
|
7
|
+
* when emitting taint edges.
|
|
8
|
+
*
|
|
9
|
+
* The store is module-level (matching the codebase's other per-language
|
|
10
|
+
* registries). {@link clearSourceSinkRegistry} resets it for test isolation.
|
|
11
|
+
*/
|
|
12
|
+
const registry = new Map();
|
|
13
|
+
/**
|
|
14
|
+
* Register the taint config for a language. Last-write-wins: re-registering
|
|
15
|
+
* the same `languageId` overwrites the previous spec (so M3 can override a
|
|
16
|
+
* built-in default). Returns nothing.
|
|
17
|
+
*/
|
|
18
|
+
export function registerSourceSinkConfig(languageId, spec) {
|
|
19
|
+
registry.set(languageId, spec);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Look up the taint config for a language. Returns `undefined` when no spec is
|
|
23
|
+
* registered (the M0 default for every language) — never throws.
|
|
24
|
+
*/
|
|
25
|
+
export function getSourceSinkConfig(languageId) {
|
|
26
|
+
return registry.get(languageId);
|
|
27
|
+
}
|
|
28
|
+
/** Language ids that currently have a registered spec. Empty in M0. */
|
|
29
|
+
export function registeredTaintLanguages() {
|
|
30
|
+
return [...registry.keys()];
|
|
31
|
+
}
|
|
32
|
+
/** Reset the registry. Primarily for test isolation. */
|
|
33
|
+
export function clearSourceSinkRegistry() {
|
|
34
|
+
registry.clear();
|
|
35
|
+
}
|
|
@@ -232,6 +232,9 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
232
232
|
const routeWriter = new BufferedCSVWriter(path.join(csvDir, 'route.csv'), 'id,name,filePath,responseKeys,errorKeys,middleware');
|
|
233
233
|
// Tool nodes for MCP tool definitions
|
|
234
234
|
const toolWriter = new BufferedCSVWriter(path.join(csvDir, 'tool.csv'), 'id,name,filePath,description');
|
|
235
|
+
// BasicBlock nodes — taint/PDG substrate (issue #2080). No `name` column;
|
|
236
|
+
// blocks are identified by id + source span. Emitted by no phase yet.
|
|
237
|
+
const basicBlockWriter = new BufferedCSVWriter(path.join(csvDir, 'basicblock.csv'), 'id,filePath,startLine,endLine,text');
|
|
235
238
|
// Multi-language node types share the same CSV shape (no isExported column)
|
|
236
239
|
const multiLangHeader = 'id,name,filePath,startLine,endLine,content,description';
|
|
237
240
|
const MULTI_LANG_TYPES = [
|
|
@@ -380,6 +383,15 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
380
383
|
escapeCSVField(node.properties.description || ''),
|
|
381
384
|
].join(','));
|
|
382
385
|
break;
|
|
386
|
+
case 'BasicBlock':
|
|
387
|
+
await basicBlockWriter.addRow([
|
|
388
|
+
escapeCSVField(node.id),
|
|
389
|
+
escapeCSVField(node.properties.filePath || ''),
|
|
390
|
+
escapeCSVNumber(node.properties.startLine, -1),
|
|
391
|
+
escapeCSVNumber(node.properties.endLine, -1),
|
|
392
|
+
escapeCSVField(node.properties.text || ''),
|
|
393
|
+
].join(','));
|
|
394
|
+
break;
|
|
383
395
|
default: {
|
|
384
396
|
// Code element nodes (Function, Class, Interface, CodeElement)
|
|
385
397
|
const writer = codeWriterMap[node.label];
|
|
@@ -433,6 +445,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
433
445
|
sectionWriter,
|
|
434
446
|
routeWriter,
|
|
435
447
|
toolWriter,
|
|
448
|
+
basicBlockWriter,
|
|
436
449
|
...multiLangWriters.values(),
|
|
437
450
|
];
|
|
438
451
|
await Promise.all(allWriters.map((w) => w.finish()));
|
|
@@ -465,6 +478,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
465
478
|
['Section', sectionWriter],
|
|
466
479
|
['Route', routeWriter],
|
|
467
480
|
['Tool', toolWriter],
|
|
481
|
+
['BasicBlock', basicBlockWriter],
|
|
468
482
|
...Array.from(multiLangWriters.entries()).map(([name, w]) => [name, w]),
|
|
469
483
|
];
|
|
470
484
|
for (const [name, writer] of tableMap) {
|
|
@@ -962,6 +962,10 @@ const getCopyQuery = (table, filePath) => {
|
|
|
962
962
|
if (table === 'Tool') {
|
|
963
963
|
return `COPY ${t}(id, name, filePath, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
964
964
|
}
|
|
965
|
+
if (table === 'BasicBlock') {
|
|
966
|
+
// Taint/PDG substrate (issue #2080) — no name column.
|
|
967
|
+
return `COPY ${t}(id, filePath, startLine, endLine, text) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
968
|
+
}
|
|
965
969
|
if (table === 'Method') {
|
|
966
970
|
return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, description, parameterCount, returnType) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
967
971
|
}
|
|
@@ -1011,6 +1015,10 @@ export const insertNodeToLbug = async (label, properties, dbPath) => {
|
|
|
1011
1015
|
: '';
|
|
1012
1016
|
query = `CREATE (n:Section {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, level: ${properties.level || 1}, content: ${escapeValue(properties.content || '')}${descPart}})`;
|
|
1013
1017
|
}
|
|
1018
|
+
else if (label === 'BasicBlock') {
|
|
1019
|
+
// Taint/PDG substrate (issue #2080) — no name column.
|
|
1020
|
+
query = `CREATE (n:BasicBlock {id: ${escapeValue(properties.id)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, text: ${escapeValue(properties.text || '')}})`;
|
|
1021
|
+
}
|
|
1014
1022
|
else if (TABLES_WITH_EXPORTED.has(label)) {
|
|
1015
1023
|
const descPart = properties.description
|
|
1016
1024
|
? `, description: ${escapeValue(properties.description)}`
|
|
@@ -1094,6 +1102,10 @@ export const batchInsertNodesToLbug = async (nodes, dbPath) => {
|
|
|
1094
1102
|
: '';
|
|
1095
1103
|
query = `MERGE (n:Section {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.level = ${properties.level || 1}, n.content = ${escapeValue(properties.content || '')}${descPart}`;
|
|
1096
1104
|
}
|
|
1105
|
+
else if (label === 'BasicBlock') {
|
|
1106
|
+
// Taint/PDG substrate (issue #2080) — no name column.
|
|
1107
|
+
query = `MERGE (n:BasicBlock {id: ${escapeValue(properties.id)}}) SET n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.text = ${escapeValue(properties.text || '')}`;
|
|
1108
|
+
}
|
|
1097
1109
|
else if (TABLES_WITH_EXPORTED.has(label)) {
|
|
1098
1110
|
const descPart = properties.description
|
|
1099
1111
|
? `, n.description = ${escapeValue(properties.description)}`
|
|
@@ -42,7 +42,8 @@ export declare const MODULE_SCHEMA: string;
|
|
|
42
42
|
export declare const ROUTE_SCHEMA = "\nCREATE NODE TABLE Route (\n id STRING,\n name STRING,\n filePath STRING,\n responseKeys STRING[],\n errorKeys STRING[],\n middleware STRING[],\n PRIMARY KEY (id)\n)";
|
|
43
43
|
export declare const TOOL_SCHEMA = "\nCREATE NODE TABLE Tool (\n id STRING,\n name STRING,\n filePath STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
44
44
|
export declare const SECTION_SCHEMA = "\nCREATE NODE TABLE Section (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n level INT64,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
45
|
-
export declare const
|
|
45
|
+
export declare const BASICBLOCK_SCHEMA = "\nCREATE NODE TABLE BasicBlock (\n id STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n text STRING,\n PRIMARY KEY (id)\n)";
|
|
46
|
+
export declare const RELATION_SCHEMA = "\nCREATE REL TABLE CodeRelation (\n FROM File TO File,\n FROM File TO Folder,\n FROM File TO Function,\n FROM File TO Class,\n FROM File TO Interface,\n FROM File TO Method,\n FROM File TO CodeElement,\n FROM File TO `Struct`,\n FROM File TO `Enum`,\n FROM File TO `Macro`,\n FROM File TO `Typedef`,\n FROM File TO `Union`,\n FROM File TO `Namespace`,\n FROM File TO `Trait`,\n FROM File TO `Impl`,\n FROM File TO `TypeAlias`,\n FROM File TO `Const`,\n FROM File TO `Static`,\n FROM File TO `Variable`,\n FROM File TO `Property`,\n FROM File TO `Record`,\n FROM File TO `Delegate`,\n FROM File TO `Annotation`,\n FROM File TO `Constructor`,\n FROM File TO `Template`,\n FROM File TO `Module`,\n FROM File TO Section,\n FROM Folder TO Folder,\n FROM Folder TO File,\n FROM Function TO Function,\n FROM Function TO Method,\n FROM Function TO Class,\n FROM Function TO Community,\n FROM Function TO `Macro`,\n FROM Function TO `Struct`,\n FROM Function TO `Template`,\n FROM Function TO `Enum`,\n FROM Function TO `Namespace`,\n FROM Function TO `TypeAlias`,\n FROM Function TO `Module`,\n FROM Function TO `Impl`,\n FROM Function TO Interface,\n FROM Function TO `Constructor`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Function TO `Property`,\n FROM Function TO CodeElement,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO Interface,\n FROM Class TO Community,\n FROM Class TO `Template`,\n FROM Class TO `TypeAlias`,\n FROM Class TO `Struct`,\n FROM Class TO `Enum`,\n FROM Class TO `Annotation`,\n FROM Class TO `Constructor`,\n FROM Class TO `Trait`,\n FROM Class TO `Macro`,\n FROM Class TO `Impl`,\n FROM Class TO `Union`,\n FROM Class TO `Namespace`,\n FROM Class TO `Typedef`,\n FROM Class TO `Property`,\n FROM Method TO Function,\n FROM Method TO Method,\n FROM Method TO Class,\n FROM Method TO Community,\n FROM Method TO `Template`,\n FROM Method TO `Struct`,\n FROM Method TO `TypeAlias`,\n FROM Method TO `Enum`,\n FROM Method TO `Macro`,\n FROM Method TO `Namespace`,\n FROM Method TO `Module`,\n FROM Method TO `Impl`,\n FROM Method TO Interface,\n FROM Method TO `Constructor`,\n FROM Method TO `Property`,\n FROM Method TO CodeElement,\n FROM `Template` TO `Template`,\n FROM `Template` TO Function,\n FROM `Template` TO Method,\n FROM `Template` TO Class,\n FROM `Template` TO `Struct`,\n FROM `Template` TO `TypeAlias`,\n FROM `Template` TO `Enum`,\n FROM `Template` TO `Macro`,\n FROM `Template` TO Interface,\n FROM `Template` TO `Constructor`,\n FROM `Module` TO `Module`,\n FROM Section TO Section,\n FROM Section TO File,\n FROM File TO Route,\n FROM Function TO Route,\n FROM Method TO Route,\n FROM File TO Tool,\n FROM Function TO Tool,\n FROM Method TO Tool,\n FROM CodeElement TO Community,\n FROM Interface TO Community,\n FROM Interface TO Function,\n FROM Interface TO Method,\n FROM Interface TO Class,\n FROM Interface TO Interface,\n FROM Interface TO `TypeAlias`,\n FROM Interface TO `Struct`,\n FROM Interface TO `Constructor`,\n FROM Interface TO `Property`,\n FROM `Struct` TO Community,\n FROM `Struct` TO `Trait`,\n FROM `Struct` TO `Struct`,\n FROM `Struct` TO Class,\n FROM `Struct` TO `Enum`,\n FROM `Struct` TO Function,\n FROM `Struct` TO Method,\n FROM `Struct` TO Interface,\n FROM `Struct` TO `Constructor`,\n FROM `Struct` TO `Property`,\n FROM `Enum` TO `Enum`,\n FROM `Enum` TO Community,\n FROM `Enum` TO Class,\n FROM `Enum` TO Interface,\n FROM `Macro` TO Community,\n FROM `Macro` TO Function,\n FROM `Macro` TO Method,\n FROM `Module` TO Function,\n FROM `Module` TO Method,\n FROM `Typedef` TO Community,\n FROM `Union` TO Community,\n FROM `Namespace` TO Community,\n FROM `Namespace` TO `Struct`,\n FROM `Trait` TO Method,\n FROM `Trait` TO `Constructor`,\n FROM `Trait` TO `Property`,\n FROM `Trait` TO Community,\n FROM `Impl` TO Method,\n FROM `Impl` TO `Constructor`,\n FROM `Impl` TO `Property`,\n FROM `Impl` TO Community,\n FROM `Impl` TO `Trait`,\n FROM `Impl` TO `Struct`,\n FROM `Impl` TO `Impl`,\n FROM `TypeAlias` TO Community,\n FROM `TypeAlias` TO `Trait`,\n FROM `TypeAlias` TO Class,\n FROM `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Variable` TO Community,\n FROM `Property` TO Community,\n FROM `Record` TO Method,\n FROM `Record` TO `Constructor`,\n FROM `Record` TO `Property`,\n FROM `Record` TO Community,\n FROM `Delegate` TO Community,\n FROM `Annotation` TO Community,\n FROM `Constructor` TO Community,\n FROM `Constructor` TO Interface,\n FROM `Constructor` TO Class,\n FROM `Constructor` TO Method,\n FROM `Constructor` TO Function,\n FROM `Constructor` TO `Constructor`,\n FROM `Constructor` TO `Struct`,\n FROM `Constructor` TO `Macro`,\n FROM `Constructor` TO `Template`,\n FROM `Constructor` TO `TypeAlias`,\n FROM `Constructor` TO `Enum`,\n FROM `Constructor` TO `Annotation`,\n FROM `Constructor` TO `Impl`,\n FROM `Constructor` TO `Namespace`,\n FROM `Constructor` TO `Module`,\n FROM `Constructor` TO `Property`,\n FROM `Constructor` TO `Typedef`,\n FROM `Template` TO Community,\n FROM `Module` TO Community,\n FROM Function TO Process,\n FROM Method TO Process,\n FROM Class TO Process,\n FROM Interface TO Process,\n FROM `Struct` TO Process,\n FROM `Constructor` TO Process,\n FROM `Module` TO Process,\n FROM `Macro` TO Process,\n FROM `Impl` TO Process,\n FROM `Typedef` TO Process,\n FROM `TypeAlias` TO Process,\n FROM `Enum` TO Process,\n FROM `Union` TO Process,\n FROM `Namespace` TO Process,\n FROM `Trait` TO Process,\n FROM `Const` TO Process,\n FROM `Static` TO Process,\n FROM `Variable` TO Process,\n FROM `Property` TO Process,\n FROM `Record` TO Process,\n FROM `Delegate` TO Process,\n FROM `Annotation` TO Process,\n FROM `Template` TO Process,\n FROM CodeElement TO Process,\n FROM Route TO Process,\n FROM Tool TO Process,\n FROM BasicBlock TO BasicBlock,\n type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
|
|
46
47
|
export declare const EMBEDDING_DIMS: number;
|
|
47
48
|
/** HNSW vector index name for the CodeEmbedding table. */
|
|
48
49
|
export declare const EMBEDDING_INDEX_NAME = "code_embedding_idx";
|
package/dist/core/lbug/schema.js
CHANGED
|
@@ -201,6 +201,22 @@ CREATE NODE TABLE Section (
|
|
|
201
201
|
description STRING,
|
|
202
202
|
PRIMARY KEY (id)
|
|
203
203
|
)`;
|
|
204
|
+
// Taint/PDG substrate (issue #2080) — intra-procedural control-flow node.
|
|
205
|
+
// Emitted by no phase yet; M1 (#2081) populates these behind an opt-in.
|
|
206
|
+
// REACHING_DEF carries its variable name in the relation's existing `reason`
|
|
207
|
+
// column (see RELATION_SCHEMA) — LadybugDB has no secondary index on rel
|
|
208
|
+
// properties, so a dedicated indexed column would buy nothing for the
|
|
209
|
+
// variable-filtered path query (M0/S1 verdict). No `name` column: blocks are
|
|
210
|
+
// identified by id + source span, not a symbol name.
|
|
211
|
+
export const BASICBLOCK_SCHEMA = `
|
|
212
|
+
CREATE NODE TABLE BasicBlock (
|
|
213
|
+
id STRING,
|
|
214
|
+
filePath STRING,
|
|
215
|
+
startLine INT64,
|
|
216
|
+
endLine INT64,
|
|
217
|
+
text STRING,
|
|
218
|
+
PRIMARY KEY (id)
|
|
219
|
+
)`;
|
|
204
220
|
// ============================================================================
|
|
205
221
|
// RELATION TABLE SCHEMA
|
|
206
222
|
// Single table with 'type' property - connects all node tables
|
|
@@ -410,6 +426,7 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
|
|
|
410
426
|
FROM CodeElement TO Process,
|
|
411
427
|
FROM Route TO Process,
|
|
412
428
|
FROM Tool TO Process,
|
|
429
|
+
FROM BasicBlock TO BasicBlock,
|
|
413
430
|
type STRING,
|
|
414
431
|
confidence DOUBLE,
|
|
415
432
|
reason STRING,
|
|
@@ -490,6 +507,11 @@ export const NODE_SCHEMA_QUERIES = [
|
|
|
490
507
|
ROUTE_SCHEMA,
|
|
491
508
|
// MCP tools
|
|
492
509
|
TOOL_SCHEMA,
|
|
510
|
+
// Taint/PDG substrate (issue #2080) — must be appended here, not just
|
|
511
|
+
// declared above: SCHEMA_QUERIES (the list initLbug actually runs) is built
|
|
512
|
+
// from NODE_SCHEMA_QUERIES. Omitting this leaves the BasicBlock table
|
|
513
|
+
// uncreated and the bulk-COPY round-trip fails with "table does not exist".
|
|
514
|
+
BASICBLOCK_SCHEMA,
|
|
493
515
|
];
|
|
494
516
|
export const REL_SCHEMA_QUERIES = [RELATION_SCHEMA];
|
|
495
517
|
export const SCHEMA_QUERIES = [...NODE_SCHEMA_QUERIES, ...REL_SCHEMA_QUERIES, EMBEDDING_SCHEMA];
|
package/dist/server/api.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export declare const landingPageHtml: () => string;
|
|
|
47
47
|
export declare const staticCacheControlSetHeaders: (res: express.Response, filePath: string) => void;
|
|
48
48
|
export declare const registerWebUI: (app: express.Express, staticDir: string | null) => void;
|
|
49
49
|
export declare const writeNdjsonRecord: (res: express.Response, record: GraphStreamRecord, signal?: AbortSignal) => Promise<void>;
|
|
50
|
+
export declare const getNodeQuery: (table: string, includeContent: boolean) => string;
|
|
50
51
|
export declare const streamGraphNdjson: (res: express.Response, includeContent?: boolean, signal?: AbortSignal) => Promise<void>;
|
|
51
52
|
/**
|
|
52
53
|
* Handle a GET /api/file request body. Extracted from createServer's route
|