gitnexus 1.4.8 → 1.4.9

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 (211) hide show
  1. package/README.md +7 -0
  2. package/dist/cli/index-repo.d.ts +15 -0
  3. package/dist/cli/index-repo.js +115 -0
  4. package/dist/cli/index.js +11 -2
  5. package/dist/cli/setup.js +12 -9
  6. package/dist/cli/wiki.d.ts +4 -0
  7. package/dist/cli/wiki.js +174 -53
  8. package/dist/config/supported-languages.d.ts +7 -5
  9. package/dist/config/supported-languages.js +6 -4
  10. package/dist/core/graph/graph.js +9 -1
  11. package/dist/core/graph/types.d.ts +10 -2
  12. package/dist/core/ingestion/call-processor.d.ts +18 -1
  13. package/dist/core/ingestion/call-processor.js +297 -38
  14. package/dist/core/ingestion/call-routing.d.ts +3 -18
  15. package/dist/core/ingestion/call-routing.js +0 -19
  16. package/dist/core/ingestion/cobol/cobol-copy-expander.d.ts +57 -0
  17. package/dist/core/ingestion/cobol/cobol-copy-expander.js +385 -0
  18. package/dist/core/ingestion/cobol/cobol-preprocessor.d.ts +210 -0
  19. package/dist/core/ingestion/cobol/cobol-preprocessor.js +1509 -0
  20. package/dist/core/ingestion/cobol/jcl-parser.d.ts +68 -0
  21. package/dist/core/ingestion/cobol/jcl-parser.js +217 -0
  22. package/dist/core/ingestion/cobol/jcl-processor.d.ts +33 -0
  23. package/dist/core/ingestion/cobol/jcl-processor.js +229 -0
  24. package/dist/core/ingestion/cobol-processor.d.ts +54 -0
  25. package/dist/core/ingestion/cobol-processor.js +1186 -0
  26. package/dist/core/ingestion/entry-point-scoring.d.ts +17 -0
  27. package/dist/core/ingestion/entry-point-scoring.js +18 -4
  28. package/dist/core/ingestion/export-detection.d.ts +47 -8
  29. package/dist/core/ingestion/export-detection.js +29 -50
  30. package/dist/core/ingestion/field-extractor.d.ts +29 -0
  31. package/dist/core/ingestion/field-extractor.js +25 -0
  32. package/dist/core/ingestion/field-extractors/configs/c-cpp.d.ts +3 -0
  33. package/dist/core/ingestion/field-extractors/configs/c-cpp.js +108 -0
  34. package/dist/core/ingestion/field-extractors/configs/csharp.d.ts +8 -0
  35. package/dist/core/ingestion/field-extractors/configs/csharp.js +73 -0
  36. package/dist/core/ingestion/field-extractors/configs/dart.d.ts +8 -0
  37. package/dist/core/ingestion/field-extractors/configs/dart.js +76 -0
  38. package/dist/core/ingestion/field-extractors/configs/go.d.ts +11 -0
  39. package/dist/core/ingestion/field-extractors/configs/go.js +64 -0
  40. package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +44 -0
  41. package/dist/core/ingestion/field-extractors/configs/helpers.js +134 -0
  42. package/dist/core/ingestion/field-extractors/configs/jvm.d.ts +3 -0
  43. package/dist/core/ingestion/field-extractors/configs/jvm.js +118 -0
  44. package/dist/core/ingestion/field-extractors/configs/php.d.ts +8 -0
  45. package/dist/core/ingestion/field-extractors/configs/php.js +67 -0
  46. package/dist/core/ingestion/field-extractors/configs/python.d.ts +12 -0
  47. package/dist/core/ingestion/field-extractors/configs/python.js +91 -0
  48. package/dist/core/ingestion/field-extractors/configs/ruby.d.ts +16 -0
  49. package/dist/core/ingestion/field-extractors/configs/ruby.js +75 -0
  50. package/dist/core/ingestion/field-extractors/configs/rust.d.ts +9 -0
  51. package/dist/core/ingestion/field-extractors/configs/rust.js +55 -0
  52. package/dist/core/ingestion/field-extractors/configs/swift.d.ts +8 -0
  53. package/dist/core/ingestion/field-extractors/configs/swift.js +63 -0
  54. package/dist/core/ingestion/field-extractors/configs/typescript-javascript.d.ts +3 -0
  55. package/dist/core/ingestion/field-extractors/configs/typescript-javascript.js +60 -0
  56. package/dist/core/ingestion/field-extractors/generic.d.ts +46 -0
  57. package/dist/core/ingestion/field-extractors/generic.js +111 -0
  58. package/dist/core/ingestion/field-extractors/typescript.d.ts +77 -0
  59. package/dist/core/ingestion/field-extractors/typescript.js +291 -0
  60. package/dist/core/ingestion/field-types.d.ts +59 -0
  61. package/dist/core/ingestion/field-types.js +2 -0
  62. package/dist/core/ingestion/framework-detection.d.ts +87 -0
  63. package/dist/core/ingestion/framework-detection.js +65 -2
  64. package/dist/core/ingestion/heritage-processor.js +15 -17
  65. package/dist/core/ingestion/import-processor.d.ts +9 -10
  66. package/dist/core/ingestion/import-processor.js +59 -14
  67. package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.d.ts +6 -9
  68. package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.js +20 -2
  69. package/dist/core/ingestion/import-resolvers/dart.d.ts +7 -0
  70. package/dist/core/ingestion/import-resolvers/dart.js +44 -0
  71. package/dist/core/ingestion/{resolvers → import-resolvers}/go.d.ts +4 -5
  72. package/dist/core/ingestion/{resolvers → import-resolvers}/go.js +17 -0
  73. package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.d.ts +9 -1
  74. package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.js +56 -0
  75. package/dist/core/ingestion/{resolvers → import-resolvers}/php.d.ts +6 -10
  76. package/dist/core/ingestion/{resolvers → import-resolvers}/php.js +7 -2
  77. package/dist/core/ingestion/{resolvers → import-resolvers}/python.d.ts +9 -3
  78. package/dist/core/ingestion/{resolvers → import-resolvers}/python.js +35 -3
  79. package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.d.ts +5 -2
  80. package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.js +7 -2
  81. package/dist/core/ingestion/{resolvers → import-resolvers}/rust.d.ts +5 -2
  82. package/dist/core/ingestion/{resolvers → import-resolvers}/rust.js +41 -2
  83. package/dist/core/ingestion/{resolvers → import-resolvers}/standard.d.ts +15 -7
  84. package/dist/core/ingestion/{resolvers → import-resolvers}/standard.js +22 -3
  85. package/dist/core/ingestion/import-resolvers/swift.d.ts +7 -0
  86. package/dist/core/ingestion/import-resolvers/swift.js +23 -0
  87. package/dist/core/ingestion/import-resolvers/types.d.ts +44 -0
  88. package/dist/core/ingestion/import-resolvers/types.js +6 -0
  89. package/dist/core/ingestion/{resolvers → import-resolvers}/utils.d.ts +0 -3
  90. package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +0 -9
  91. package/dist/core/ingestion/language-config.d.ts +4 -1
  92. package/dist/core/ingestion/language-provider.d.ts +121 -0
  93. package/dist/core/ingestion/language-provider.js +24 -0
  94. package/dist/core/ingestion/languages/c-cpp.d.ts +12 -0
  95. package/dist/core/ingestion/languages/c-cpp.js +71 -0
  96. package/dist/core/ingestion/languages/cobol.d.ts +1 -0
  97. package/dist/core/ingestion/languages/cobol.js +26 -0
  98. package/dist/core/ingestion/languages/csharp.d.ts +8 -0
  99. package/dist/core/ingestion/languages/csharp.js +49 -0
  100. package/dist/core/ingestion/languages/dart.d.ts +12 -0
  101. package/dist/core/ingestion/languages/dart.js +58 -0
  102. package/dist/core/ingestion/languages/go.d.ts +11 -0
  103. package/dist/core/ingestion/languages/go.js +28 -0
  104. package/dist/core/ingestion/languages/index.d.ts +38 -0
  105. package/dist/core/ingestion/languages/index.js +63 -0
  106. package/dist/core/ingestion/languages/java.d.ts +9 -0
  107. package/dist/core/ingestion/languages/java.js +29 -0
  108. package/dist/core/ingestion/languages/kotlin.d.ts +9 -0
  109. package/dist/core/ingestion/languages/kotlin.js +53 -0
  110. package/dist/core/ingestion/languages/php.d.ts +8 -0
  111. package/dist/core/ingestion/languages/php.js +145 -0
  112. package/dist/core/ingestion/languages/python.d.ts +12 -0
  113. package/dist/core/ingestion/languages/python.js +39 -0
  114. package/dist/core/ingestion/languages/ruby.d.ts +9 -0
  115. package/dist/core/ingestion/languages/ruby.js +44 -0
  116. package/dist/core/ingestion/languages/rust.d.ts +12 -0
  117. package/dist/core/ingestion/languages/rust.js +44 -0
  118. package/dist/core/ingestion/languages/swift.d.ts +12 -0
  119. package/dist/core/ingestion/languages/swift.js +133 -0
  120. package/dist/core/ingestion/languages/typescript.d.ts +10 -0
  121. package/dist/core/ingestion/languages/typescript.js +60 -0
  122. package/dist/core/ingestion/mro-processor.js +14 -15
  123. package/dist/core/ingestion/{named-binding-extraction.d.ts → named-binding-processor.d.ts} +0 -9
  124. package/dist/core/ingestion/named-binding-processor.js +42 -0
  125. package/dist/core/ingestion/named-bindings/csharp.d.ts +3 -0
  126. package/dist/core/ingestion/named-bindings/csharp.js +37 -0
  127. package/dist/core/ingestion/named-bindings/java.d.ts +3 -0
  128. package/dist/core/ingestion/named-bindings/java.js +29 -0
  129. package/dist/core/ingestion/named-bindings/kotlin.d.ts +3 -0
  130. package/dist/core/ingestion/named-bindings/kotlin.js +36 -0
  131. package/dist/core/ingestion/named-bindings/php.d.ts +3 -0
  132. package/dist/core/ingestion/named-bindings/php.js +61 -0
  133. package/dist/core/ingestion/named-bindings/python.d.ts +3 -0
  134. package/dist/core/ingestion/named-bindings/python.js +49 -0
  135. package/dist/core/ingestion/named-bindings/rust.d.ts +3 -0
  136. package/dist/core/ingestion/named-bindings/rust.js +64 -0
  137. package/dist/core/ingestion/named-bindings/types.d.ts +16 -0
  138. package/dist/core/ingestion/named-bindings/types.js +6 -0
  139. package/dist/core/ingestion/named-bindings/typescript.d.ts +3 -0
  140. package/dist/core/ingestion/named-bindings/typescript.js +58 -0
  141. package/dist/core/ingestion/parsing-processor.d.ts +5 -1
  142. package/dist/core/ingestion/parsing-processor.js +115 -16
  143. package/dist/core/ingestion/pipeline.js +925 -424
  144. package/dist/core/ingestion/resolution-context.js +1 -1
  145. package/dist/core/ingestion/route-extractors/expo.d.ts +1 -0
  146. package/dist/core/ingestion/route-extractors/expo.js +36 -0
  147. package/dist/core/ingestion/route-extractors/middleware.d.ts +47 -0
  148. package/dist/core/ingestion/route-extractors/middleware.js +143 -0
  149. package/dist/core/ingestion/route-extractors/nextjs.d.ts +3 -0
  150. package/dist/core/ingestion/route-extractors/nextjs.js +76 -0
  151. package/dist/core/ingestion/route-extractors/php.d.ts +7 -0
  152. package/dist/core/ingestion/route-extractors/php.js +21 -0
  153. package/dist/core/ingestion/route-extractors/response-shapes.d.ts +20 -0
  154. package/dist/core/ingestion/route-extractors/response-shapes.js +290 -0
  155. package/dist/core/ingestion/tree-sitter-queries.d.ts +8 -7
  156. package/dist/core/ingestion/tree-sitter-queries.js +231 -9
  157. package/dist/core/ingestion/type-env.d.ts +14 -17
  158. package/dist/core/ingestion/type-env.js +66 -14
  159. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +1 -1
  160. package/dist/core/ingestion/type-extractors/csharp.js +1 -1
  161. package/dist/core/ingestion/type-extractors/dart.d.ts +15 -0
  162. package/dist/core/ingestion/type-extractors/dart.js +371 -0
  163. package/dist/core/ingestion/type-extractors/jvm.js +1 -1
  164. package/dist/core/ingestion/type-extractors/shared.d.ts +1 -13
  165. package/dist/core/ingestion/type-extractors/shared.js +9 -102
  166. package/dist/core/ingestion/type-extractors/swift.js +334 -4
  167. package/dist/core/ingestion/type-extractors/types.d.ts +3 -1
  168. package/dist/core/ingestion/{ast-helpers.d.ts → utils/ast-helpers.d.ts} +16 -13
  169. package/dist/core/ingestion/{ast-helpers.js → utils/ast-helpers.js} +111 -32
  170. package/dist/core/ingestion/{call-analysis.js → utils/call-analysis.js} +37 -0
  171. package/dist/core/ingestion/utils/event-loop.d.ts +5 -0
  172. package/dist/core/ingestion/utils/event-loop.js +5 -0
  173. package/dist/core/ingestion/utils/language-detection.d.ts +9 -0
  174. package/dist/core/ingestion/utils/language-detection.js +70 -0
  175. package/dist/core/ingestion/utils/verbose.d.ts +1 -0
  176. package/dist/core/ingestion/utils/verbose.js +7 -0
  177. package/dist/core/ingestion/workers/parse-worker.d.ts +43 -2
  178. package/dist/core/ingestion/workers/parse-worker.js +361 -150
  179. package/dist/core/lbug/csv-generator.js +34 -1
  180. package/dist/core/lbug/lbug-adapter.js +6 -0
  181. package/dist/core/lbug/schema.d.ts +5 -3
  182. package/dist/core/lbug/schema.js +39 -2
  183. package/dist/core/tree-sitter/parser-loader.js +7 -1
  184. package/dist/core/wiki/cursor-client.d.ts +31 -0
  185. package/dist/core/wiki/cursor-client.js +127 -0
  186. package/dist/core/wiki/generator.d.ts +28 -9
  187. package/dist/core/wiki/generator.js +115 -18
  188. package/dist/core/wiki/graph-queries.d.ts +4 -0
  189. package/dist/core/wiki/graph-queries.js +7 -1
  190. package/dist/core/wiki/llm-client.d.ts +2 -0
  191. package/dist/core/wiki/llm-client.js +8 -4
  192. package/dist/core/wiki/prompts.d.ts +3 -3
  193. package/dist/core/wiki/prompts.js +6 -0
  194. package/dist/mcp/core/lbug-adapter.d.ts +5 -0
  195. package/dist/mcp/core/lbug-adapter.js +11 -1
  196. package/dist/mcp/local/local-backend.d.ts +16 -5
  197. package/dist/mcp/local/local-backend.js +711 -74
  198. package/dist/mcp/tools.js +71 -2
  199. package/dist/storage/repo-manager.d.ts +3 -0
  200. package/package.json +17 -16
  201. package/dist/core/ingestion/import-resolution.d.ts +0 -101
  202. package/dist/core/ingestion/import-resolution.js +0 -251
  203. package/dist/core/ingestion/named-binding-extraction.js +0 -373
  204. package/dist/core/ingestion/resolvers/index.d.ts +0 -18
  205. package/dist/core/ingestion/resolvers/index.js +0 -13
  206. package/dist/core/ingestion/type-extractors/index.d.ts +0 -22
  207. package/dist/core/ingestion/type-extractors/index.js +0 -31
  208. package/dist/core/ingestion/utils.d.ts +0 -20
  209. package/dist/core/ingestion/utils.js +0 -242
  210. package/scripts/patch-tree-sitter-swift.cjs +0 -74
  211. /package/dist/core/ingestion/{call-analysis.d.ts → utils/call-analysis.d.ts} +0 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * JCL Parser — Regex single-pass extraction.
3
+ *
4
+ * Extracts JCL constructs from mainframe job streams:
5
+ * - JOB statements (job name, CLASS, MSGCLASS)
6
+ * - EXEC statements (step -> program or proc)
7
+ * - DD statements (dataset references, DISP)
8
+ * - PROC definitions (in-stream and catalogued)
9
+ * - INCLUDE MEMBER= directives
10
+ * - SET symbolic parameters
11
+ * - IF/ELSE/ENDIF conditional execution
12
+ * - JCLLIB ORDER= search paths
13
+ *
14
+ * Pattern follows cobol-preprocessor.ts — regex-only, no tree-sitter.
15
+ */
16
+ export interface JclParseResults {
17
+ jobs: Array<{
18
+ name: string;
19
+ line: number;
20
+ class?: string;
21
+ msgclass?: string;
22
+ }>;
23
+ steps: Array<{
24
+ name: string;
25
+ jobName: string;
26
+ program?: string;
27
+ proc?: string;
28
+ line: number;
29
+ }>;
30
+ ddStatements: Array<{
31
+ ddName: string;
32
+ stepName: string;
33
+ dataset?: string;
34
+ disp?: string;
35
+ line: number;
36
+ }>;
37
+ procs: Array<{
38
+ name: string;
39
+ line: number;
40
+ isInStream: boolean;
41
+ }>;
42
+ includes: Array<{
43
+ member: string;
44
+ line: number;
45
+ }>;
46
+ sets: Array<{
47
+ variable: string;
48
+ value: string;
49
+ line: number;
50
+ }>;
51
+ jcllib: Array<{
52
+ order: string[];
53
+ line: number;
54
+ }>;
55
+ conditionals: Array<{
56
+ type: 'IF' | 'ELSE' | 'ENDIF';
57
+ condition?: string;
58
+ line: number;
59
+ }>;
60
+ }
61
+ /**
62
+ * Parse a JCL file and extract all constructs.
63
+ *
64
+ * @param content - Raw JCL file content
65
+ * @param filePath - Path for diagnostics (not used in extraction)
66
+ * @returns Parsed JCL results
67
+ */
68
+ export declare function parseJcl(content: string, filePath: string): JclParseResults;
@@ -0,0 +1,217 @@
1
+ /**
2
+ * JCL Parser — Regex single-pass extraction.
3
+ *
4
+ * Extracts JCL constructs from mainframe job streams:
5
+ * - JOB statements (job name, CLASS, MSGCLASS)
6
+ * - EXEC statements (step -> program or proc)
7
+ * - DD statements (dataset references, DISP)
8
+ * - PROC definitions (in-stream and catalogued)
9
+ * - INCLUDE MEMBER= directives
10
+ * - SET symbolic parameters
11
+ * - IF/ELSE/ENDIF conditional execution
12
+ * - JCLLIB ORDER= search paths
13
+ *
14
+ * Pattern follows cobol-preprocessor.ts — regex-only, no tree-sitter.
15
+ */
16
+ // ── JCL statement patterns ─────────────────────────────────────────────
17
+ // JCL continuation: line ends with a non-blank in col 72, next line starts with //
18
+ // We handle continuations by joining lines before matching.
19
+ /** Match //jobname JOB ... */
20
+ const JOB_RE = /^\/\/(\w{1,8})\s+JOB\s+(.*)/i;
21
+ /** Match //stepname EXEC PGM=program or //stepname EXEC procname */
22
+ const EXEC_RE = /^\/\/(\w{1,8})\s+EXEC\s+(.*)/i;
23
+ /** Match //ddname DD ... */
24
+ const DD_RE = /^\/\/(\w{1,8})\s+DD\s+(.*)/i;
25
+ /** Match // JCLLIB ORDER=(lib1,lib2,...) */
26
+ const JCLLIB_RE = /^\/\/\s+JCLLIB\s+ORDER=\(([^)]+)\)/i;
27
+ /** Match // IF condition THEN */
28
+ const IF_RE = /^\/\/\s+IF\s+(.+)\s+THEN/i;
29
+ /** Match // ELSE */
30
+ const ELSE_RE = /^\/\/\s+ELSE\b/i;
31
+ /** Match // ENDIF */
32
+ const ENDIF_RE = /^\/\/\s+ENDIF\b/i;
33
+ /** Match // INCLUDE MEMBER=name */
34
+ const INCLUDE_RE = /^\/\/\s+INCLUDE\s+MEMBER=(\w+)/i;
35
+ /** Match // SET var=value */
36
+ const SET_RE = /^\/\/\s+SET\s+(\w+)=(.+)/i;
37
+ /** Match // PROC or //name PROC */
38
+ const PROC_RE = /^\/\/(\w*)\s+PROC\b/i;
39
+ /** Match // PEND */
40
+ const PEND_RE = /^\/\/\s+PEND\b/i;
41
+ // ── Parameter extractors ───────────────────────────────────────────────
42
+ function extractParam(params, key) {
43
+ // Match KEY=VALUE or KEY='VALUE' in JCL parameter string
44
+ const re = new RegExp(`${key}=(?:'([^']*)'|(\\S+?))(?:[,\\s]|$)`, 'i');
45
+ const m = params.match(re);
46
+ return m ? (m[1] ?? m[2]) : undefined;
47
+ }
48
+ function extractPgm(params) {
49
+ return extractParam(params, 'PGM');
50
+ }
51
+ function extractProc(params) {
52
+ // If no PGM= keyword, the first positional parameter is the proc name
53
+ if (/PGM=/i.test(params))
54
+ return undefined;
55
+ const cleaned = params.replace(/,.*/, '').trim();
56
+ // Proc name is the first token (no = sign)
57
+ if (cleaned && !cleaned.includes('=')) {
58
+ return cleaned.replace(/[,\s].*/s, '').toUpperCase();
59
+ }
60
+ return undefined;
61
+ }
62
+ function extractDsn(params) {
63
+ return extractParam(params, 'DSN') ?? extractParam(params, 'DSNAME');
64
+ }
65
+ function extractDisp(params) {
66
+ const m = params.match(/DISP=\(?\s*([^),\s]+)/i);
67
+ return m ? m[1] : undefined;
68
+ }
69
+ /**
70
+ * Parse a JCL file and extract all constructs.
71
+ *
72
+ * @param content - Raw JCL file content
73
+ * @param filePath - Path for diagnostics (not used in extraction)
74
+ * @returns Parsed JCL results
75
+ */
76
+ export function parseJcl(content, filePath) {
77
+ const results = {
78
+ jobs: [],
79
+ steps: [],
80
+ ddStatements: [],
81
+ procs: [],
82
+ includes: [],
83
+ sets: [],
84
+ jcllib: [],
85
+ conditionals: [],
86
+ };
87
+ const rawLines = content.split(/\r?\n/);
88
+ // Join continuation lines: a line ending with non-blank in col 71 (0-indexed)
89
+ // followed by a line starting with // is a continuation.
90
+ const lines = [];
91
+ let i = 0;
92
+ while (i < rawLines.length) {
93
+ let line = rawLines[i];
94
+ const lineNum = i + 1;
95
+ // JCL continuation: if line is exactly 72+ chars and col 72 is non-blank
96
+ // and the next line starts with //, join them.
97
+ while (i + 1 < rawLines.length &&
98
+ line.length >= 72 &&
99
+ line[71] !== ' ' &&
100
+ rawLines[i + 1].startsWith('//')) {
101
+ i++;
102
+ // Continuation text starts after // and leading spaces
103
+ const contText = rawLines[i].substring(2).replace(/^\s+/, ' ');
104
+ // Remove the continuation marker (col 72+) from current line
105
+ line = line.substring(0, 71).trimEnd() + contText;
106
+ }
107
+ lines.push({ text: line, lineNum });
108
+ i++;
109
+ }
110
+ let currentJobName = '';
111
+ let currentStepName = '';
112
+ let inStreamProcName = '';
113
+ for (const { text, lineNum } of lines) {
114
+ // Skip JCL comments (starting with //* )
115
+ if (text.startsWith('//*'))
116
+ continue;
117
+ // Skip non-JCL lines (don't start with //)
118
+ if (!text.startsWith('//'))
119
+ continue;
120
+ // PROC definition (in-stream)
121
+ const procMatch = text.match(PROC_RE);
122
+ if (procMatch) {
123
+ const procName = procMatch[1] || inStreamProcName;
124
+ if (procName) {
125
+ results.procs.push({ name: procName.toUpperCase(), line: lineNum, isInStream: true });
126
+ }
127
+ inStreamProcName = procName?.toUpperCase() || '';
128
+ continue;
129
+ }
130
+ // PEND (end of in-stream proc)
131
+ if (PEND_RE.test(text)) {
132
+ inStreamProcName = '';
133
+ continue;
134
+ }
135
+ // JCLLIB ORDER=
136
+ const jcllibMatch = text.match(JCLLIB_RE);
137
+ if (jcllibMatch) {
138
+ const libs = jcllibMatch[1].split(',').map(s => s.trim().replace(/'/g, ''));
139
+ results.jcllib.push({ order: libs, line: lineNum });
140
+ continue;
141
+ }
142
+ // IF/ELSE/ENDIF
143
+ const ifMatch = text.match(IF_RE);
144
+ if (ifMatch) {
145
+ results.conditionals.push({ type: 'IF', condition: ifMatch[1].trim(), line: lineNum });
146
+ continue;
147
+ }
148
+ if (ELSE_RE.test(text)) {
149
+ results.conditionals.push({ type: 'ELSE', line: lineNum });
150
+ continue;
151
+ }
152
+ if (ENDIF_RE.test(text)) {
153
+ results.conditionals.push({ type: 'ENDIF', line: lineNum });
154
+ continue;
155
+ }
156
+ // INCLUDE MEMBER=
157
+ const includeMatch = text.match(INCLUDE_RE);
158
+ if (includeMatch) {
159
+ results.includes.push({ member: includeMatch[1].toUpperCase(), line: lineNum });
160
+ continue;
161
+ }
162
+ // SET var=value
163
+ const setMatch = text.match(SET_RE);
164
+ if (setMatch) {
165
+ results.sets.push({
166
+ variable: setMatch[1].toUpperCase(),
167
+ value: setMatch[2].trim().replace(/,\s*$/, ''),
168
+ line: lineNum,
169
+ });
170
+ continue;
171
+ }
172
+ // JOB statement
173
+ const jobMatch = text.match(JOB_RE);
174
+ if (jobMatch) {
175
+ currentJobName = jobMatch[1].toUpperCase();
176
+ const params = jobMatch[2];
177
+ results.jobs.push({
178
+ name: currentJobName,
179
+ line: lineNum,
180
+ class: extractParam(params, 'CLASS'),
181
+ msgclass: extractParam(params, 'MSGCLASS'),
182
+ });
183
+ continue;
184
+ }
185
+ // EXEC statement
186
+ const execMatch = text.match(EXEC_RE);
187
+ if (execMatch) {
188
+ currentStepName = execMatch[1].toUpperCase();
189
+ const params = execMatch[2];
190
+ const pgm = extractPgm(params);
191
+ const proc = pgm ? undefined : extractProc(params);
192
+ results.steps.push({
193
+ name: currentStepName,
194
+ jobName: currentJobName,
195
+ program: pgm?.toUpperCase(),
196
+ proc: proc?.toUpperCase(),
197
+ line: lineNum,
198
+ });
199
+ continue;
200
+ }
201
+ // DD statement
202
+ const ddMatch = text.match(DD_RE);
203
+ if (ddMatch) {
204
+ const ddName = ddMatch[1].toUpperCase();
205
+ const params = ddMatch[2];
206
+ results.ddStatements.push({
207
+ ddName,
208
+ stepName: currentStepName,
209
+ dataset: extractDsn(params)?.toUpperCase(),
210
+ disp: extractDisp(params)?.toUpperCase(),
211
+ line: lineNum,
212
+ });
213
+ continue;
214
+ }
215
+ }
216
+ return results;
217
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * JCL Processor — Converts JCL parse results into graph nodes and edges.
3
+ *
4
+ * Maps JCL entities to existing graph types (no new tables):
5
+ * - Job -> CodeElement (description: "jcl-job class:A msgclass:X")
6
+ * - Step -> CodeElement (description: "jcl-step pgm:PROGRAMNAME")
7
+ * - Dataset -> CodeElement (description: "jcl-dataset disp:SHR")
8
+ * - PROC -> Module
9
+ *
10
+ * Edges:
11
+ * - Job CONTAINS Step
12
+ * - Step CALLS Module (when PGM= matches an indexed program)
13
+ * - Step references Dataset (CALLS edge with reason "jcl-dd")
14
+ * - Job/Step IMPORTS PROC
15
+ *
16
+ * Pattern follows detectCrossProgamContracts() in pipeline.ts.
17
+ */
18
+ import type { KnowledgeGraph } from '../../graph/types.js';
19
+ export interface JclProcessResult {
20
+ jobCount: number;
21
+ stepCount: number;
22
+ datasetCount: number;
23
+ programLinks: number;
24
+ }
25
+ /**
26
+ * Process JCL files and integrate into the knowledge graph.
27
+ *
28
+ * @param graph - The in-memory knowledge graph
29
+ * @param jclPaths - File paths of JCL files
30
+ * @param jclContents - Map of path -> file content
31
+ * @returns Summary of what was added
32
+ */
33
+ export declare function processJclFiles(graph: KnowledgeGraph, jclPaths: string[], jclContents: Map<string, string>): JclProcessResult;
@@ -0,0 +1,229 @@
1
+ /**
2
+ * JCL Processor — Converts JCL parse results into graph nodes and edges.
3
+ *
4
+ * Maps JCL entities to existing graph types (no new tables):
5
+ * - Job -> CodeElement (description: "jcl-job class:A msgclass:X")
6
+ * - Step -> CodeElement (description: "jcl-step pgm:PROGRAMNAME")
7
+ * - Dataset -> CodeElement (description: "jcl-dataset disp:SHR")
8
+ * - PROC -> Module
9
+ *
10
+ * Edges:
11
+ * - Job CONTAINS Step
12
+ * - Step CALLS Module (when PGM= matches an indexed program)
13
+ * - Step references Dataset (CALLS edge with reason "jcl-dd")
14
+ * - Job/Step IMPORTS PROC
15
+ *
16
+ * Pattern follows detectCrossProgamContracts() in pipeline.ts.
17
+ */
18
+ import { parseJcl } from './jcl-parser.js';
19
+ import { generateId } from '../../../lib/utils.js';
20
+ /**
21
+ * Process JCL files and integrate into the knowledge graph.
22
+ *
23
+ * @param graph - The in-memory knowledge graph
24
+ * @param jclPaths - File paths of JCL files
25
+ * @param jclContents - Map of path -> file content
26
+ * @returns Summary of what was added
27
+ */
28
+ export function processJclFiles(graph, jclPaths, jclContents) {
29
+ let jobCount = 0;
30
+ let stepCount = 0;
31
+ let datasetCount = 0;
32
+ let programLinks = 0;
33
+ // Collect all Module names for step -> program linking
34
+ const moduleNames = new Map(); // uppercase name -> node id
35
+ graph.forEachNode(node => {
36
+ if (node.label === 'Module') {
37
+ const nodeName = node.properties.name;
38
+ if (typeof nodeName === 'string') {
39
+ moduleNames.set(nodeName.toUpperCase(), node.id);
40
+ }
41
+ }
42
+ });
43
+ for (const filePath of jclPaths) {
44
+ const content = jclContents.get(filePath);
45
+ if (!content)
46
+ continue;
47
+ const parsed = parseJcl(content, filePath);
48
+ const result = integrateJclResults(graph, parsed, filePath, moduleNames);
49
+ jobCount += result.jobCount;
50
+ stepCount += result.stepCount;
51
+ datasetCount += result.datasetCount;
52
+ programLinks += result.programLinks;
53
+ }
54
+ return { jobCount, stepCount, datasetCount, programLinks };
55
+ }
56
+ function integrateJclResults(graph, parsed, filePath, moduleNames) {
57
+ let jobCount = 0;
58
+ let stepCount = 0;
59
+ let datasetCount = 0;
60
+ let programLinks = 0;
61
+ // Track step node IDs for DD -> step linking
62
+ const stepNodeIds = new Map(); // stepName -> nodeId
63
+ // 1. Create Job nodes
64
+ for (const job of parsed.jobs) {
65
+ const jobId = generateId('CodeElement', `${filePath}:job:${job.name}`);
66
+ const classPart = job.class ? ` class:${job.class}` : '';
67
+ const msgPart = job.msgclass ? ` msgclass:${job.msgclass}` : '';
68
+ graph.addNode({
69
+ id: jobId,
70
+ label: 'CodeElement',
71
+ properties: {
72
+ name: job.name,
73
+ filePath,
74
+ startLine: job.line,
75
+ endLine: job.line,
76
+ description: `jcl-job${classPart}${msgPart}`,
77
+ },
78
+ });
79
+ // Link File -> Job (CONTAINS)
80
+ const fileId = generateId('File', filePath);
81
+ graph.addRelationship({
82
+ id: `${fileId}_contains_${jobId}`,
83
+ type: 'CONTAINS',
84
+ sourceId: fileId,
85
+ targetId: jobId,
86
+ confidence: 1.0,
87
+ reason: 'jcl-job',
88
+ });
89
+ jobCount++;
90
+ }
91
+ // 1.5 Pre-register in-stream PROCs so steps can reference them
92
+ // (fixes ordering bug: steps processed before PROCs were registered)
93
+ for (const proc of parsed.procs) {
94
+ const procId = generateId('Module', `${filePath}:proc:${proc.name}`);
95
+ moduleNames.set(proc.name.toUpperCase(), procId);
96
+ }
97
+ // 2. Create Step nodes and link to programs
98
+ for (const step of parsed.steps) {
99
+ const stepId = generateId('CodeElement', `${filePath}:step:${step.jobName}:${step.name}`);
100
+ const pgmPart = step.program ? ` pgm:${step.program}` : '';
101
+ const procPart = step.proc ? ` proc:${step.proc}` : '';
102
+ graph.addNode({
103
+ id: stepId,
104
+ label: 'CodeElement',
105
+ properties: {
106
+ name: step.name,
107
+ filePath,
108
+ startLine: step.line,
109
+ endLine: step.line,
110
+ description: `jcl-step${pgmPart}${procPart}`,
111
+ },
112
+ });
113
+ stepNodeIds.set(step.name, stepId);
114
+ // Link Job -> Step (CONTAINS)
115
+ if (step.jobName) {
116
+ const jobId = generateId('CodeElement', `${filePath}:job:${step.jobName}`);
117
+ graph.addRelationship({
118
+ id: `${jobId}_contains_${stepId}`,
119
+ type: 'CONTAINS',
120
+ sourceId: jobId,
121
+ targetId: stepId,
122
+ confidence: 1.0,
123
+ reason: 'jcl-step',
124
+ });
125
+ }
126
+ // Link Step -> Module (CALLS) when PGM= matches an indexed program
127
+ if (step.program) {
128
+ const moduleId = moduleNames.get(step.program.toUpperCase());
129
+ if (moduleId) {
130
+ graph.addRelationship({
131
+ id: `${stepId}_calls_${moduleId}`,
132
+ type: 'CALLS',
133
+ sourceId: stepId,
134
+ targetId: moduleId,
135
+ confidence: 0.95,
136
+ reason: 'jcl-exec-pgm',
137
+ });
138
+ programLinks++;
139
+ }
140
+ }
141
+ // Link Step -> PROC (CALLS) — PROC as Module
142
+ if (step.proc) {
143
+ const procModuleId = moduleNames.get(step.proc.toUpperCase());
144
+ if (procModuleId) {
145
+ graph.addRelationship({
146
+ id: `${stepId}_calls_proc_${procModuleId}`,
147
+ type: 'CALLS',
148
+ sourceId: stepId,
149
+ targetId: procModuleId,
150
+ confidence: 0.9,
151
+ reason: 'jcl-exec-proc',
152
+ });
153
+ }
154
+ }
155
+ stepCount++;
156
+ }
157
+ // 3. Create Dataset nodes from DD statements
158
+ const seenDatasets = new Set();
159
+ for (const dd of parsed.ddStatements) {
160
+ if (!dd.dataset)
161
+ continue;
162
+ // Create dataset node (deduplicated per file)
163
+ const datasetKey = `${filePath}:dataset:${dd.dataset}`;
164
+ const datasetId = generateId('CodeElement', datasetKey);
165
+ if (!seenDatasets.has(dd.dataset)) {
166
+ const dispPart = dd.disp ? ` disp:${dd.disp}` : '';
167
+ graph.addNode({
168
+ id: datasetId,
169
+ label: 'CodeElement',
170
+ properties: {
171
+ name: dd.dataset,
172
+ filePath,
173
+ startLine: dd.line,
174
+ endLine: dd.line,
175
+ description: `jcl-dataset${dispPart}`,
176
+ },
177
+ });
178
+ seenDatasets.add(dd.dataset);
179
+ datasetCount++;
180
+ }
181
+ // Link Step -> Dataset (CALLS with reason jcl-dd)
182
+ const stepId = stepNodeIds.get(dd.stepName);
183
+ if (stepId) {
184
+ graph.addRelationship({
185
+ id: `${stepId}_dd_${dd.ddName}_${datasetId}`,
186
+ type: 'CALLS',
187
+ sourceId: stepId,
188
+ targetId: datasetId,
189
+ confidence: 0.85,
190
+ reason: `jcl-dd:${dd.ddName}`,
191
+ });
192
+ }
193
+ }
194
+ // 4. Create PROC nodes (in-stream procs as Module)
195
+ for (const proc of parsed.procs) {
196
+ if (!proc.isInStream)
197
+ continue;
198
+ const procId = generateId('Module', `${filePath}:proc:${proc.name}`);
199
+ graph.addNode({
200
+ id: procId,
201
+ label: 'Module',
202
+ properties: {
203
+ name: proc.name,
204
+ filePath,
205
+ startLine: proc.line,
206
+ endLine: proc.line,
207
+ description: 'jcl-proc-instream',
208
+ },
209
+ });
210
+ // Register for step linking
211
+ moduleNames.set(proc.name.toUpperCase(), procId);
212
+ }
213
+ // 5. INCLUDE directives -> IMPORTS edges
214
+ for (const inc of parsed.includes) {
215
+ const moduleId = moduleNames.get(inc.member.toUpperCase());
216
+ if (moduleId) {
217
+ const fileId = generateId('File', filePath);
218
+ graph.addRelationship({
219
+ id: `${fileId}_includes_${moduleId}`,
220
+ type: 'IMPORTS',
221
+ sourceId: fileId,
222
+ targetId: moduleId,
223
+ confidence: 0.9,
224
+ reason: 'jcl-include',
225
+ });
226
+ }
227
+ }
228
+ return { jobCount, stepCount, datasetCount, programLinks };
229
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * COBOL Processor
3
+ *
4
+ * Standalone regex-based processor for COBOL and JCL files.
5
+ * Follows the markdown-processor.ts pattern: takes (graph, files, allPathSet),
6
+ * does its own extraction, and writes directly to the graph.
7
+ *
8
+ * Pipeline:
9
+ * 1. Separate programs from copybooks
10
+ * 2. Build copybook map (name -> content)
11
+ * 3. For each program: expand COPY statements, then run regex extraction
12
+ * 4. Map CobolRegexResults to graph nodes and relationships
13
+ * 5. Optionally process JCL files for job-step cross-references
14
+ */
15
+ import type { KnowledgeGraph } from '../graph/types.js';
16
+ interface CobolFile {
17
+ path: string;
18
+ content: string;
19
+ }
20
+ export interface CobolProcessResult {
21
+ programs: number;
22
+ paragraphs: number;
23
+ sections: number;
24
+ dataItems: number;
25
+ calls: number;
26
+ copies: number;
27
+ execSqlBlocks: number;
28
+ execCicsBlocks: number;
29
+ entryPoints: number;
30
+ moves: number;
31
+ fileDeclarations: number;
32
+ jclJobs: number;
33
+ jclSteps: number;
34
+ sqlIncludes: number;
35
+ execDliBlocks: number;
36
+ declaratives: number;
37
+ sets: number;
38
+ inspects: number;
39
+ initializes: number;
40
+ }
41
+ /** Returns true if the file is a COBOL or copybook file. */
42
+ export declare function isCobolFile(filePath: string): boolean;
43
+ /** Returns true if the file is a JCL file. */
44
+ export declare function isJclFile(filePath: string): boolean;
45
+ /**
46
+ * Process COBOL and JCL files into the knowledge graph.
47
+ *
48
+ * @param graph - The in-memory knowledge graph
49
+ * @param files - Array of { path, content } for COBOL/JCL files
50
+ * @param allPathSet - Set of all file paths in the repository
51
+ * @returns Summary of what was extracted
52
+ */
53
+ export declare const processCobol: (graph: KnowledgeGraph, files: CobolFile[], allPathSet: Set<string>) => CobolProcessResult;
54
+ export {};