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.
Files changed (45) hide show
  1. package/dist/_shared/graph/types.d.ts +47 -2
  2. package/dist/_shared/graph/types.d.ts.map +1 -1
  3. package/dist/_shared/lbug/schema-constants.d.ts +2 -2
  4. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  5. package/dist/_shared/lbug/schema-constants.js +4 -0
  6. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  7. package/dist/cli/detect-changes-format.js +21 -0
  8. package/dist/cli/i18n/en.d.ts +1 -0
  9. package/dist/cli/i18n/en.js +1 -0
  10. package/dist/cli/i18n/resources.d.ts +2 -0
  11. package/dist/cli/i18n/zh-CN.d.ts +1 -0
  12. package/dist/cli/i18n/zh-CN.js +1 -0
  13. package/dist/core/incremental/subgraph-extract.d.ts +2 -1
  14. package/dist/core/incremental/subgraph-extract.js +24 -1
  15. package/dist/core/ingestion/destination-key.d.ts +59 -0
  16. package/dist/core/ingestion/destination-key.js +61 -0
  17. package/dist/core/ingestion/frameworks/spring/destinations.d.ts +514 -0
  18. package/dist/core/ingestion/frameworks/spring/destinations.js +840 -0
  19. package/dist/core/ingestion/language-provider.d.ts +41 -0
  20. package/dist/core/ingestion/languages/java.js +8 -1
  21. package/dist/core/ingestion/languages/kotlin.js +13 -0
  22. package/dist/core/ingestion/model/registration-table.js +3 -0
  23. package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
  24. package/dist/core/ingestion/pipeline-phases/index.js +1 -0
  25. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +4 -0
  26. package/dist/core/ingestion/pipeline-phases/parse-impl.js +21 -5
  27. package/dist/core/ingestion/pipeline-phases/parse.d.ts +17 -0
  28. package/dist/core/ingestion/pipeline-phases/spring-destinations.d.ts +82 -0
  29. package/dist/core/ingestion/pipeline-phases/spring-destinations.js +489 -0
  30. package/dist/core/ingestion/pipeline.d.ts +2 -1
  31. package/dist/core/ingestion/pipeline.js +8 -2
  32. package/dist/core/lbug/csv-generator.d.ts +9 -0
  33. package/dist/core/lbug/csv-generator.js +61 -0
  34. package/dist/core/lbug/lbug-adapter.d.ts +41 -5
  35. package/dist/core/lbug/lbug-adapter.js +73 -5
  36. package/dist/core/lbug/schema.d.ts +2 -1
  37. package/dist/core/lbug/schema.js +59 -8
  38. package/dist/core/run-analyze.js +13 -1
  39. package/dist/mcp/local/local-backend.js +13 -0
  40. package/dist/mcp/tools.js +1 -1
  41. package/dist/server/api.js +21 -0
  42. package/package.json +1 -1
  43. package/web/assets/{agent-CFqT4hjR.js → agent-9RdJj3B9.js} +1 -1
  44. package/web/assets/{index-BMIniRtX.js → index-CGkXVu9D.js} +3 -3
  45. 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' | 'BasicBlock';
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' | 'FETCHES' | 'HANDLES_TOOL' | 'ENTRY_POINT_OF' | 'WRAPS' | 'QUERIES'
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":"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"}
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 = [];
@@ -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.";
@@ -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;
@@ -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;
@@ -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
+ }