gitnexus 1.6.11-rc.33 → 1.6.11-rc.35
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 +47 -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 +4 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/cli/detect-changes-format.js +21 -0
- package/dist/cli/i18n/en.d.ts +1 -0
- package/dist/cli/i18n/en.js +1 -0
- package/dist/cli/i18n/resources.d.ts +2 -0
- package/dist/cli/i18n/zh-CN.d.ts +1 -0
- package/dist/cli/i18n/zh-CN.js +1 -0
- package/dist/core/incremental/subgraph-extract.d.ts +2 -1
- package/dist/core/incremental/subgraph-extract.js +24 -1
- package/dist/core/ingestion/destination-key.d.ts +59 -0
- package/dist/core/ingestion/destination-key.js +61 -0
- package/dist/core/ingestion/frameworks/spring/destinations.d.ts +514 -0
- package/dist/core/ingestion/frameworks/spring/destinations.js +840 -0
- package/dist/core/ingestion/language-provider.d.ts +41 -0
- package/dist/core/ingestion/languages/java.js +8 -1
- package/dist/core/ingestion/languages/kotlin.js +13 -0
- 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/parse-impl.d.ts +4 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +21 -5
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.d.ts +82 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.js +489 -0
- package/dist/core/ingestion/pipeline.d.ts +2 -1
- package/dist/core/ingestion/pipeline.js +8 -2
- package/dist/core/lbug/csv-generator.d.ts +9 -0
- package/dist/core/lbug/csv-generator.js +61 -0
- package/dist/core/lbug/lbug-adapter.d.ts +41 -5
- package/dist/core/lbug/lbug-adapter.js +73 -5
- package/dist/core/lbug/schema.d.ts +2 -1
- package/dist/core/lbug/schema.js +59 -8
- package/dist/core/run-analyze.js +13 -1
- package/dist/mcp/local/local-backend.js +13 -0
- package/dist/mcp/tools.js +1 -1
- package/dist/server/api.js +21 -0
- package/package.json +1 -1
- package/web/assets/{agent-CFqT4hjR.js → agent-9RdJj3B9.js} +1 -1
- package/web/assets/{index-BMIniRtX.js → index-CGkXVu9D.js} +3 -3
- package/web/index.html +1 -1
|
@@ -5,7 +5,22 @@
|
|
|
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'
|
|
9
|
+
/**
|
|
10
|
+
* A message-broker destination — a Kafka topic, a Rabbit exchange/routing
|
|
11
|
+
* key, a JMS queue, a Spring Cloud Stream binding. The framework overlay for
|
|
12
|
+
* ASYNCHRONOUS entry/exit points, symmetric to `Route` for HTTP.
|
|
13
|
+
*
|
|
14
|
+
* Identity is `(broker, resolved ADDRESS)`, so a publisher and a consumer of
|
|
15
|
+
* the same address on the same broker land on one node and the connection is
|
|
16
|
+
* a single hop — while a Kafka topic and a Rabbit queue that share a name
|
|
17
|
+
* stay two nodes, the same way `GET /x` and `POST /x` are two Routes. A
|
|
18
|
+
* destination whose address could NOT be resolved is keyed by its source
|
|
19
|
+
* location instead and carries no `address` property at all. See
|
|
20
|
+
* `pipeline-phases/spring-destinations.ts` for why an unresolved spelling may
|
|
21
|
+
* not key a node, and `ingestion/destination-key.ts` for why the broker may.
|
|
22
|
+
*/
|
|
23
|
+
| 'Destination' | 'BasicBlock';
|
|
9
24
|
export type NodeProperties = {
|
|
10
25
|
name: string;
|
|
11
26
|
filePath: string;
|
|
@@ -54,13 +69,43 @@ export type NodeProperties = {
|
|
|
54
69
|
runtimeSource?: string;
|
|
55
70
|
/** Runtime result such as runtime-confirmed or handler-conflict. */
|
|
56
71
|
runtimeStatus?: string;
|
|
72
|
+
/** The RESOLVED broker address. Together with `broker` it is the key a
|
|
73
|
+
* cross-repository pass joins on. Present only when the address resolved:
|
|
74
|
+
* absent is the load-bearing state, because an absent property cannot match
|
|
75
|
+
* another absent property. */
|
|
76
|
+
address?: string;
|
|
77
|
+
/** Broker family the syntax attests to (`kafka`, `rabbit`, `jms`, …). Part
|
|
78
|
+
* of the node's identity alongside `address`, not a label on it. */
|
|
79
|
+
broker?: string;
|
|
80
|
+
/** How the address was arrived at (`literal`, `constant`) when it resolved,
|
|
81
|
+
* or the named reason it did not. */
|
|
82
|
+
resolution?: string;
|
|
83
|
+
/** Configuration key named by an unresolvable `${…}` placeholder. The key
|
|
84
|
+
* only — configuration VALUES are deliberately absent from this graph. */
|
|
85
|
+
configKey?: string;
|
|
86
|
+
/** The `${key:default}` default text. Not an address: configuration can
|
|
87
|
+
* override it and the graph cannot see whether it did. */
|
|
88
|
+
configDefault?: string;
|
|
57
89
|
text?: string;
|
|
58
90
|
/** BasicBlock: space-joined leaf callee names invoked in the block — the
|
|
59
91
|
* statement-precise inter-procedural reach substrate for impact mode. */
|
|
60
92
|
callees?: string;
|
|
61
93
|
[key: string]: unknown;
|
|
62
94
|
};
|
|
63
|
-
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'
|
|
95
|
+
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'
|
|
96
|
+
/** Outbound async messaging. Source = the callable that performs the publish
|
|
97
|
+
* (or its File); target = the `Destination` it publishes to. Emitted by
|
|
98
|
+
* `pipeline-phases/spring-destinations.ts` from Spring messaging-template
|
|
99
|
+
* calls (`kafkaTemplate.send(...)`, `rabbitTemplate.convertAndSend(...)`).
|
|
100
|
+
* One edge per address: a publish that names two destinations yields two
|
|
101
|
+
* edges, and `reason` records which argument each came from. */
|
|
102
|
+
| 'PUBLISHES_TO'
|
|
103
|
+
/** Inbound async messaging — the mirror of `PUBLISHES_TO`. Source = the
|
|
104
|
+
* annotated handler callable (or its File); target = the `Destination` it
|
|
105
|
+
* subscribes to. Emitted from `@KafkaListener` / `@RabbitListener` /
|
|
106
|
+
* `@JmsListener` and their siblings. Together the two types make
|
|
107
|
+
* "who else reads what this service writes" a two-hop traversal. */
|
|
108
|
+
| 'CONSUMES_FROM' | 'FETCHES' | 'HANDLES_TOOL' | 'ENTRY_POINT_OF' | 'WRAPS' | 'QUERIES'
|
|
64
109
|
/** Dependency-injection edge: a consumer class receives a likely provider
|
|
65
110
|
* through constructor, field, method, or collection injection. A
|
|
66
111
|
* per-language resolver identifies the site and provider metadata; the
|
|
@@ -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,
|
|
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', 'BasicBlock'];
|
|
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', 'Destination', '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', 'INJECTS', 'CONDITIONAL_ON', 'DECLARES', 'ADVISED_BY', 'CFG', 'REACHING_DEF', 'TAINTED', 'SANITIZES', 'TAINT_PATH', 'CDG', 'POST_DOMINATE'];
|
|
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', 'PUBLISHES_TO', 'CONSUMES_FROM', 'FETCHES', 'HANDLES_TOOL', 'ENTRY_POINT_OF', 'WRAPS', 'QUERIES', 'INJECTS', 'CONDITIONAL_ON', 'DECLARES', 'ADVISED_BY', 'CFG', 'REACHING_DEF', 'TAINTED', 'SANITIZES', 'TAINT_PATH', 'CDG', 'POST_DOMINATE'];
|
|
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,YACtB,MAAM,EACN,QAAQ,EACR,UAAU,EACV,OAAO,EACP,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,WAAW,EACX,OAAO,EACP,MAAM,EACN,WAAW,EACX,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,QAAQ,EACR,OAAO,EACP,MAAM,EAEN,YAAY,CACJ,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,eAAO,MAAM,SAAS,YACpB,UAAU,EACV,SAAS,EACT,SAAS,EACT,OAAO,EACP,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,YAAY,EAIZ,KAAK,EACL,cAAc,EACd,SAAS,EACT,WAAW,EACX,YAAY,EAKZ,KAAK,EACL,eAAe,CACP,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,eAAO,MAAM,oBAAoB,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema-constants.d.ts","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,WAAW,YACtB,MAAM,EACN,QAAQ,EACR,UAAU,EACV,OAAO,EACP,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,WAAW,EACX,OAAO,EACP,MAAM,EACN,WAAW,EACX,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,QAAQ,EACR,OAAO,EACP,MAAM,EAEN,aAAa,EAEb,YAAY,CACJ,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,eAAO,MAAM,SAAS,YACpB,UAAU,EACV,SAAS,EACT,SAAS,EACT,OAAO,EACP,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,eAAe,EACf,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,YAAY,EAIZ,KAAK,EACL,cAAc,EACd,SAAS,EACT,WAAW,EACX,YAAY,EAKZ,KAAK,EACL,eAAe,CACP,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
|
+
// Async messaging overlay — the broker-side counterpart of `Route`.
|
|
43
|
+
'Destination',
|
|
42
44
|
// Taint/PDG substrate (issue #2080) — inert until M1 (#2081) emits blocks.
|
|
43
45
|
'BasicBlock',
|
|
44
46
|
];
|
|
@@ -59,6 +61,8 @@ export const REL_TYPES = [
|
|
|
59
61
|
'MEMBER_OF',
|
|
60
62
|
'STEP_IN_PROCESS',
|
|
61
63
|
'HANDLES_ROUTE',
|
|
64
|
+
'PUBLISHES_TO',
|
|
65
|
+
'CONSUMES_FROM',
|
|
62
66
|
'FETCHES',
|
|
63
67
|
'HANDLES_TOOL',
|
|
64
68
|
'ENTRY_POINT_OF',
|
|
@@ -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;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,SAAS;IACT,gBAAgB;IAChB,UAAU;IACV,YAAY;IACZ,yEAAyE;IACzE,yEAAyE;IACzE,6EAA6E;IAC7E,KAAK;IACL,cAAc;IACd,SAAS;IACT,WAAW;IACX,YAAY;IACZ,4EAA4E;IAC5E,uEAAuE;IACvE,4EAA4E;IAC5E,8EAA8E;IAC9E,KAAK;IACL,eAAe;CACP,CAAC;AAIX,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
|
|
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,oEAAoE;IACpE,aAAa;IACb,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,cAAc;IACd,eAAe;IACf,SAAS;IACT,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,SAAS;IACT,SAAS;IACT,gBAAgB;IAChB,UAAU;IACV,YAAY;IACZ,yEAAyE;IACzE,yEAAyE;IACzE,6EAA6E;IAC7E,KAAK;IACL,cAAc;IACd,SAAS;IACT,WAAW;IACX,YAAY;IACZ,4EAA4E;IAC5E,uEAAuE;IACvE,4EAA4E;IAC5E,8EAA8E;IAC9E,KAAK;IACL,eAAe;CACP,CAAC;AAIX,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
|
|
@@ -20,6 +20,27 @@ export function formatDetectChangesResult(result) {
|
|
|
20
20
|
if (payload.truncated)
|
|
21
21
|
notes.push(t(payload.partial ? 'tool.detectChanges.truncatedDegraded' : 'tool.detectChanges.truncated'));
|
|
22
22
|
if ((summary.changed_count ?? 0) === 0) {
|
|
23
|
+
// Parse-fail payloads set `partial` and an honest `message` (#2915/#3131).
|
|
24
|
+
// Production *clean* trees also set English `message: 'No changes detected.'`
|
|
25
|
+
// — that must go through `t('tool.detectChanges.noChanges')` or zh-CN never
|
|
26
|
+
// fires. Only pass the backend string through on a degraded/parse-fail run.
|
|
27
|
+
if (payload.partial &&
|
|
28
|
+
typeof summary.message === 'string' &&
|
|
29
|
+
summary.message.trim().length > 0) {
|
|
30
|
+
return [...notes, summary.message.trim()].join('\n');
|
|
31
|
+
}
|
|
32
|
+
// Confirmed no-overlap: files parsed, mapping succeeded, zero symbols.
|
|
33
|
+
// `queryDegraded` is `partial: true` with the same counts and no message —
|
|
34
|
+
// do not call that a confirmed mapping (#3131 honesty).
|
|
35
|
+
if (!payload.partial && (summary.changed_files ?? 0) > 0) {
|
|
36
|
+
return [
|
|
37
|
+
...notes,
|
|
38
|
+
t('tool.detectChanges.noOverlappingSymbols', { files: summary.changed_files }),
|
|
39
|
+
].join('\n');
|
|
40
|
+
}
|
|
41
|
+
if (payload.partial) {
|
|
42
|
+
return notes.join('\n');
|
|
43
|
+
}
|
|
23
44
|
return [...notes, t('tool.detectChanges.noChanges')].join('\n');
|
|
24
45
|
}
|
|
25
46
|
const lines = [];
|
package/dist/cli/i18n/en.d.ts
CHANGED
|
@@ -66,6 +66,7 @@ export declare const en: {
|
|
|
66
66
|
readonly 'tool.usage.cypher': "Usage: gitnexus cypher <cypher_query>";
|
|
67
67
|
readonly 'tool.warn.unknownKind': "--kind '{{kind}}' is not a known symbol kind (e.g. Function, Class, Method); it will not narrow the result.";
|
|
68
68
|
readonly 'tool.detectChanges.noChanges': "No changes detected.";
|
|
69
|
+
readonly 'tool.detectChanges.noOverlappingSymbols': "Diff touched {{files}} file(s) but no indexed symbols overlap those hunks — not a clean tree.";
|
|
69
70
|
readonly 'tool.detectChanges.partial': "PARTIAL RESULT: a graph query failed, so changed symbols may be missing. Do not read this as a clean pre-commit check.";
|
|
70
71
|
readonly 'tool.detectChanges.truncated': "LISTING CAPPED: the changed-symbol list was capped, so it does not name every changed symbol. The counts and risk level still cover all of them.";
|
|
71
72
|
readonly 'tool.detectChanges.truncatedDegraded': "LISTING CAPPED: the changed-symbol list was capped. The run also degraded, so the counts are a lower bound, not a total.";
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -66,6 +66,7 @@ export const en = {
|
|
|
66
66
|
'tool.usage.cypher': 'Usage: gitnexus cypher <cypher_query>',
|
|
67
67
|
'tool.warn.unknownKind': "--kind '{{kind}}' is not a known symbol kind (e.g. Function, Class, Method); it will not narrow the result.",
|
|
68
68
|
'tool.detectChanges.noChanges': 'No changes detected.',
|
|
69
|
+
'tool.detectChanges.noOverlappingSymbols': 'Diff touched {{files}} file(s) but no indexed symbols overlap those hunks — not a clean tree.',
|
|
69
70
|
'tool.detectChanges.partial': 'PARTIAL RESULT: a graph query failed, so changed symbols may be missing. Do not read this as a clean pre-commit check.',
|
|
70
71
|
'tool.detectChanges.truncated': 'LISTING CAPPED: the changed-symbol list was capped, so it does not name every changed symbol. The counts and risk level still cover all of them.',
|
|
71
72
|
// The reassurance above is only true on its own. When the run also degraded,
|
|
@@ -67,6 +67,7 @@ export declare const cliResources: {
|
|
|
67
67
|
readonly 'tool.usage.cypher': "Usage: gitnexus cypher <cypher_query>";
|
|
68
68
|
readonly 'tool.warn.unknownKind': "--kind '{{kind}}' is not a known symbol kind (e.g. Function, Class, Method); it will not narrow the result.";
|
|
69
69
|
readonly 'tool.detectChanges.noChanges': "No changes detected.";
|
|
70
|
+
readonly 'tool.detectChanges.noOverlappingSymbols': "Diff touched {{files}} file(s) but no indexed symbols overlap those hunks — not a clean tree.";
|
|
70
71
|
readonly 'tool.detectChanges.partial': "PARTIAL RESULT: a graph query failed, so changed symbols may be missing. Do not read this as a clean pre-commit check.";
|
|
71
72
|
readonly 'tool.detectChanges.truncated': "LISTING CAPPED: the changed-symbol list was capped, so it does not name every changed symbol. The counts and risk level still cover all of them.";
|
|
72
73
|
readonly 'tool.detectChanges.truncatedDegraded': "LISTING CAPPED: the changed-symbol list was capped. The run also degraded, so the counts are a lower bound, not a total.";
|
|
@@ -331,6 +332,7 @@ export declare const cliResources: {
|
|
|
331
332
|
'tool.usage.cypher': string;
|
|
332
333
|
'tool.warn.unknownKind': string;
|
|
333
334
|
'tool.detectChanges.noChanges': string;
|
|
335
|
+
'tool.detectChanges.noOverlappingSymbols': string;
|
|
334
336
|
'tool.detectChanges.partial': string;
|
|
335
337
|
'tool.detectChanges.truncated': string;
|
|
336
338
|
'tool.detectChanges.truncatedDegraded': string;
|
package/dist/cli/i18n/zh-CN.d.ts
CHANGED
|
@@ -66,6 +66,7 @@ export declare const zhCN: {
|
|
|
66
66
|
'tool.usage.cypher': string;
|
|
67
67
|
'tool.warn.unknownKind': string;
|
|
68
68
|
'tool.detectChanges.noChanges': string;
|
|
69
|
+
'tool.detectChanges.noOverlappingSymbols': string;
|
|
69
70
|
'tool.detectChanges.partial': string;
|
|
70
71
|
'tool.detectChanges.truncated': string;
|
|
71
72
|
'tool.detectChanges.truncatedDegraded': string;
|
package/dist/cli/i18n/zh-CN.js
CHANGED
|
@@ -66,6 +66,7 @@ export const zhCN = {
|
|
|
66
66
|
'tool.usage.cypher': '用法:gitnexus cypher <Cypher 查询>',
|
|
67
67
|
'tool.warn.unknownKind': "--kind '{{kind}}' 不是已知的符号类型(如 Function、Class、Method),不会用于缩小结果范围。",
|
|
68
68
|
'tool.detectChanges.noChanges': '未检测到变更。',
|
|
69
|
+
'tool.detectChanges.noOverlappingSymbols': 'diff 触及 {{files}} 个文件,但没有索引符号与这些 hunk 重叠 — 并非干净工作区。',
|
|
69
70
|
'tool.detectChanges.partial': '结果不完整:图查询失败,可能遗漏已变更符号。请勿将其视为通过的提交前检查。',
|
|
70
71
|
'tool.detectChanges.truncated': '列表已截断:已变更符号列表被截断,未列出全部变更符号。计数与风险等级仍涵盖全部符号。',
|
|
71
72
|
'tool.detectChanges.truncatedDegraded': '列表已截断:已变更符号列表被截断。本次运行同时不完整,因此计数为下限而非总数。',
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* - Every node whose `properties.filePath` is in `toWriteSet`.
|
|
9
9
|
* - Graph-wide Community/Process nodes unless `includeDerivedGraphWide`
|
|
10
10
|
* is false (#3016 incremental preserve). Spring metadata placeholders
|
|
11
|
-
* are always included
|
|
11
|
+
* and `Destination` nodes are always included — their owning phase
|
|
12
|
+
* delete-alls them unconditionally before the writeback.
|
|
12
13
|
* - Every relationship where AT LEAST ONE endpoint is in the writable
|
|
13
14
|
* set above. Relationships entirely between unchanged-file nodes
|
|
14
15
|
* are skipped — their rows are still in the DB and re-inserting
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* - Every node whose `properties.filePath` is in `toWriteSet`.
|
|
9
9
|
* - Graph-wide Community/Process nodes unless `includeDerivedGraphWide`
|
|
10
10
|
* is false (#3016 incremental preserve). Spring metadata placeholders
|
|
11
|
-
* are always included
|
|
11
|
+
* and `Destination` nodes are always included — their owning phase
|
|
12
|
+
* delete-alls them unconditionally before the writeback.
|
|
12
13
|
* - Every relationship where AT LEAST ONE endpoint is in the writable
|
|
13
14
|
* set above. Relationships entirely between unchanged-file nodes
|
|
14
15
|
* are skipped — their rows are still in the DB and re-inserting
|
|
@@ -50,8 +51,30 @@
|
|
|
50
51
|
import { createKnowledgeGraph } from '../graph/graph.js';
|
|
51
52
|
import { isSpringAutoConfigurationDeclaration, isSpringAutoConfigurationSyntheticClass, } from '../ingestion/frameworks/spring/auto-configuration.js';
|
|
52
53
|
import { isSpringAopEvidenceNode } from '../ingestion/frameworks/spring/aop.js';
|
|
54
|
+
/**
|
|
55
|
+
* `Destination` is graph-wide for the same reason as the Spring AOP evidence
|
|
56
|
+
* nodes: the layer is recomputed in full on every run and deleted in full
|
|
57
|
+
* before the writeback (`deleteAllDestinations`), so it must be re-included in
|
|
58
|
+
* full or it is simply lost.
|
|
59
|
+
*
|
|
60
|
+
* The endpoint-writability rule cannot carry it. A RESOLVED destination stores
|
|
61
|
+
* no `filePath` at all — deliberately, so an incremental delete keyed on
|
|
62
|
+
* `filePath IN [...]` cannot cut a node shared across files — and the include
|
|
63
|
+
* test below starts from exactly that property. The result was a defect in both
|
|
64
|
+
* directions: a newly added file publishing to a new topic reported
|
|
65
|
+
* `added=1, exit 0` and silently put neither the destination nor the
|
|
66
|
+
* publisher's edge into the graph, so after the first index every new topic was
|
|
67
|
+
* invisible until a full rebuild; and a destination whose last referrer stopped
|
|
68
|
+
* referring to it survived forever as an edgeless orphan still carrying
|
|
69
|
+
* `address`, the cross-repository join key.
|
|
70
|
+
*
|
|
71
|
+
* Unresolved destinations DO carry a file path and would ride the ordinary
|
|
72
|
+
* rule, but they are included here too: the delete-all removes them as well, so
|
|
73
|
+
* anything not re-included would be dropped rather than merely stale.
|
|
74
|
+
*/
|
|
53
75
|
const isGraphWideNode = (node) => node.label === 'Community' ||
|
|
54
76
|
node.label === 'Process' ||
|
|
77
|
+
node.label === 'Destination' ||
|
|
55
78
|
isSpringAopEvidenceNode(node) ||
|
|
56
79
|
isSpringAutoConfigurationSyntheticClass(node);
|
|
57
80
|
/**
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared destination-identity keying — the async counterpart of `routeNodeKey`
|
|
3
|
+
* in `route-extractors/route-path.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately OUTSIDE `frameworks/spring/`, and for the same reason
|
|
6
|
+
* `routeNodeKey` sits outside the routes phase: the identity has to be mintable
|
|
7
|
+
* by anything that names a broker address, so a Node Kafka client or a Celery
|
|
8
|
+
* task queue can land on the very node a Spring publisher minted. A key that
|
|
9
|
+
* lived in the Spring module would force every other producer to import Spring,
|
|
10
|
+
* or — worse — let each one invent its own spelling, and two spellings of one
|
|
11
|
+
* address is precisely the missed connection this overlay exists to make.
|
|
12
|
+
*
|
|
13
|
+
* `broker` is a plain `string`, NOT the Spring `SpringDestinationBroker` union.
|
|
14
|
+
* Importing that union here is the dependency this module exists to avoid, and
|
|
15
|
+
* widening it costs nothing that matters: the union is a subtype of `string`,
|
|
16
|
+
* so a Spring caller passes its own values unchanged, while a future
|
|
17
|
+
* non-Spring caller stays free to attest to a broker Spring has no name for.
|
|
18
|
+
* The trade is real but small — this signature cannot reject a misspelled
|
|
19
|
+
* broker — and it is the same trade `routeNodeKey` makes by taking `method` as
|
|
20
|
+
* a `string` rather than an HTTP-verb union. Pure string logic, no
|
|
21
|
+
* dependencies.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The `Destination` node identity: `(broker, address)` when the broker is
|
|
25
|
+
* known, falling back to the address alone when it is not.
|
|
26
|
+
*
|
|
27
|
+
* The broker belongs IN the key, exactly as the HTTP verb belongs in
|
|
28
|
+
* `routeNodeKey`. `GET /x` and `POST /x` are two nodes, both fully joinable,
|
|
29
|
+
* and neither is punished for the other's existence; `kafka orders` and
|
|
30
|
+
* `rabbit orders` are two nodes on the same terms. A Kafka topic and a Rabbit
|
|
31
|
+
* queue that happen to share a name are two places, and one node for both would
|
|
32
|
+
* report a publisher and a subscriber as connected when nothing connects them.
|
|
33
|
+
*
|
|
34
|
+
* The known objection is that the broker is INFERRED — from a receiver's name,
|
|
35
|
+
* from an annotation table — so a wrong guess splits a pair that is really one.
|
|
36
|
+
* That is true and it is the cost. It is worth paying because the alternative
|
|
37
|
+
* tried first was worse: withdrawing the address from every site that named it
|
|
38
|
+
* split the pair even when the guess was RIGHT, since one unrelated third party
|
|
39
|
+
* writing the same word anywhere in the repository was enough to disconnect
|
|
40
|
+
* everybody on that spelling. Putting the broker in the key bounds the damage
|
|
41
|
+
* of a wrong guess to the one pair it was wrong about, instead of spreading it
|
|
42
|
+
* to every pair that shares an address with a stranger.
|
|
43
|
+
*
|
|
44
|
+
* ── THE ADDRESS-ONLY FALLBACK IS UNREACHABLE TODAY ──────────────────────
|
|
45
|
+
*
|
|
46
|
+
* `SpringDestinationCandidate.broker` is REQUIRED, and every annotation rule
|
|
47
|
+
* and every producer template supplies one, so no Spring caller can reach the
|
|
48
|
+
* `undefined` branch. It is written anyway, and on purpose: the parameter shape
|
|
49
|
+
* is the contract this module offers the next language, and the next language
|
|
50
|
+
* may well capture an address without being able to attest to a broker (a bare
|
|
51
|
+
* `queue.publish(name)` in a dynamic language, a binding that names only a
|
|
52
|
+
* channel). Degrading to address-only is the right answer there — silence about
|
|
53
|
+
* the broker is not a claim about it, and refusing to key such a site at all
|
|
54
|
+
* would lose a real destination over a value nobody disagreed about.
|
|
55
|
+
*
|
|
56
|
+
* Because the branch is dead, it is covered by testing THIS function directly
|
|
57
|
+
* rather than by a pipeline test staged to look as though a phase reached it.
|
|
58
|
+
*/
|
|
59
|
+
export declare function destinationNodeKey(broker: string | undefined, address: string): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared destination-identity keying — the async counterpart of `routeNodeKey`
|
|
3
|
+
* in `route-extractors/route-path.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately OUTSIDE `frameworks/spring/`, and for the same reason
|
|
6
|
+
* `routeNodeKey` sits outside the routes phase: the identity has to be mintable
|
|
7
|
+
* by anything that names a broker address, so a Node Kafka client or a Celery
|
|
8
|
+
* task queue can land on the very node a Spring publisher minted. A key that
|
|
9
|
+
* lived in the Spring module would force every other producer to import Spring,
|
|
10
|
+
* or — worse — let each one invent its own spelling, and two spellings of one
|
|
11
|
+
* address is precisely the missed connection this overlay exists to make.
|
|
12
|
+
*
|
|
13
|
+
* `broker` is a plain `string`, NOT the Spring `SpringDestinationBroker` union.
|
|
14
|
+
* Importing that union here is the dependency this module exists to avoid, and
|
|
15
|
+
* widening it costs nothing that matters: the union is a subtype of `string`,
|
|
16
|
+
* so a Spring caller passes its own values unchanged, while a future
|
|
17
|
+
* non-Spring caller stays free to attest to a broker Spring has no name for.
|
|
18
|
+
* The trade is real but small — this signature cannot reject a misspelled
|
|
19
|
+
* broker — and it is the same trade `routeNodeKey` makes by taking `method` as
|
|
20
|
+
* a `string` rather than an HTTP-verb union. Pure string logic, no
|
|
21
|
+
* dependencies.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The `Destination` node identity: `(broker, address)` when the broker is
|
|
25
|
+
* known, falling back to the address alone when it is not.
|
|
26
|
+
*
|
|
27
|
+
* The broker belongs IN the key, exactly as the HTTP verb belongs in
|
|
28
|
+
* `routeNodeKey`. `GET /x` and `POST /x` are two nodes, both fully joinable,
|
|
29
|
+
* and neither is punished for the other's existence; `kafka orders` and
|
|
30
|
+
* `rabbit orders` are two nodes on the same terms. A Kafka topic and a Rabbit
|
|
31
|
+
* queue that happen to share a name are two places, and one node for both would
|
|
32
|
+
* report a publisher and a subscriber as connected when nothing connects them.
|
|
33
|
+
*
|
|
34
|
+
* The known objection is that the broker is INFERRED — from a receiver's name,
|
|
35
|
+
* from an annotation table — so a wrong guess splits a pair that is really one.
|
|
36
|
+
* That is true and it is the cost. It is worth paying because the alternative
|
|
37
|
+
* tried first was worse: withdrawing the address from every site that named it
|
|
38
|
+
* split the pair even when the guess was RIGHT, since one unrelated third party
|
|
39
|
+
* writing the same word anywhere in the repository was enough to disconnect
|
|
40
|
+
* everybody on that spelling. Putting the broker in the key bounds the damage
|
|
41
|
+
* of a wrong guess to the one pair it was wrong about, instead of spreading it
|
|
42
|
+
* to every pair that shares an address with a stranger.
|
|
43
|
+
*
|
|
44
|
+
* ── THE ADDRESS-ONLY FALLBACK IS UNREACHABLE TODAY ──────────────────────
|
|
45
|
+
*
|
|
46
|
+
* `SpringDestinationCandidate.broker` is REQUIRED, and every annotation rule
|
|
47
|
+
* and every producer template supplies one, so no Spring caller can reach the
|
|
48
|
+
* `undefined` branch. It is written anyway, and on purpose: the parameter shape
|
|
49
|
+
* is the contract this module offers the next language, and the next language
|
|
50
|
+
* may well capture an address without being able to attest to a broker (a bare
|
|
51
|
+
* `queue.publish(name)` in a dynamic language, a binding that names only a
|
|
52
|
+
* channel). Degrading to address-only is the right answer there — silence about
|
|
53
|
+
* the broker is not a claim about it, and refusing to key such a site at all
|
|
54
|
+
* would lose a real destination over a value nobody disagreed about.
|
|
55
|
+
*
|
|
56
|
+
* Because the branch is dead, it is covered by testing THIS function directly
|
|
57
|
+
* rather than by a pipeline test staged to look as though a phase reached it.
|
|
58
|
+
*/
|
|
59
|
+
export function destinationNodeKey(broker, address) {
|
|
60
|
+
return broker ? `${broker} ${address}` : address;
|
|
61
|
+
}
|