@saptools/service-flow 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4
4
+
5
+ - Resolved helper-returned service bindings exported through named export lists, including aliased exports, while preserving helper-chain evidence.
6
+ - Parsed `cds.connect.to(alias, options)` as separate alias, destination, and service-path evidence so dynamic service paths can resolve with runtime variables.
7
+ - Improved repository discovery so valid workspace-root Git repositories no longer prevent nested repository discovery, and empty `.git` markers are ignored.
8
+ - Added explicit SQLite foreign-key constraints for fresh databases and recorded alias-expression evidence for service bindings.
9
+ - Documented clearer operator guidance for test-file hygiene, doctor severity, and list/trace selector semantics.
10
+
3
11
  ## 0.1.3
4
12
 
5
13
  - Propagated imported helper-returned `cds.connect.to(...)` bindings to caller-local service variables with helper-chain evidence.
package/README.md CHANGED
@@ -27,6 +27,8 @@ Index independent Git repositories, persist CAP/CDS facts in SQLite, resolve cro
27
27
  - 🧠 **Dynamic edge support** — preserves parameterized destinations and service paths such as `svc_${objectCode}_process`, then lets traces apply runtime `--var key=value` values
28
28
  - 📊 **Multiple output modes** — renders human-readable tables, JSON for automation, and Mermaid diagrams for architecture docs
29
29
  - 🩺 **Diagnostics-first workflow** — records parse/index issues and exposes them through `service-flow doctor` instead of hiding partial analysis
30
+ - 🧩 **CAP helper-aware binding evidence** — follows imported helpers exported directly or through named export lists and separates alias, destination, and service-path expressions for dynamic `cds.connect.to(alias, options)` calls
31
+ - 🧭 **Nested workspace discovery** — scans nested repositories even when the selected root is itself a valid Git repository, while ignoring empty `.git` placeholders
30
32
  - 🔐 **Secret-aware summaries** — redacts sensitive keys in persisted summaries and CLI output while keeping useful source evidence
31
33
  - 📦 **Standalone CLI & typed package** — ships as an npm CLI with TypeScript definitions for integration into other saptools workflows
32
34
 
@@ -180,6 +182,7 @@ service-flow list repos --workspace /path/to/workspace
180
182
  service-flow list services --workspace /path/to/workspace --repo facade-service
181
183
  service-flow list operations --workspace /path/to/workspace --repo facade-service --service /FacadeService
182
184
  service-flow list calls --workspace /path/to/workspace --repo facade-service --operation doWork
185
+ # `--operation` filters outgoing call paths/payloads; use trace/graph `--operation` for handler-origin traversal.
183
186
  ```
184
187
 
185
188
  | Command | Description |
@@ -280,6 +283,10 @@ service-flow trace --workspace /path/to/workspace --repo facade-service --operat
280
283
 
281
284
  When a concrete target exists after variable substitution, the trace shows both the parameterized evidence and the resolved match. When it does not, `service-flow` keeps the edge as a dynamic candidate or unresolved edge so the missing link remains visible.
282
285
 
286
+ Service-binding evidence keeps these fields distinct: service alias, alias expression, destination expression, service-path expression, operation-path expression, and runtime placeholders. This is important for common CAP helpers such as `cds.connect.to(`remote_${code}`, { credentials: { destination: `remote_${code}`, path: `/${entityType}ProcessService` } })`, where the alias is not the service path.
287
+
288
+ By default, production traces should be built from production source files. Keep generated credentials and local state out of git, and use explicit fixture/test workspaces when validating test-only mocked service clients so they do not pollute production graph interpretation.
289
+
283
290
  ---
284
291
 
285
292
  ## 📁 Workspace State
@@ -377,6 +384,7 @@ Run `service-flow index` after source, CDS, package metadata, or helper-package
377
384
  <summary><b>Why is an expected call unresolved?</b></summary>
378
385
 
379
386
  Check `service-flow doctor`, then inspect the facts with `service-flow list services`, `service-flow list operations`, and `service-flow list calls`. Dynamic destinations may need `--var key=value`, and custom wrappers may need new parser support.
387
+ Default doctor output is intended to focus on actionable indexing or trace-impacting issues; use `--strict` when you need exhaustive model-shape diagnostics for entity-only or extension-heavy CDS models.
380
388
 
381
389
  </details>
382
390
 
package/TECHNICAL-NOTE.md CHANGED
@@ -1,7 +1,14 @@
1
- # Service Flow 0.1.3 Resolution Notes
1
+ # Service Flow 0.1.4 Resolution Notes
2
2
 
3
3
  - Imported helper bindings: TypeScript imports are resolved for relative modules. When a caller assigns `const client = await connectToService()`, the analyzer follows the imported symbol to an exported helper that returns `cds.connect.to(...)` and persists caller-variable evidence plus the helper source/export chain.
4
4
  - Candidate ranking: operation-path matches start as weak candidates. A resolved operation edge requires a strong signal such as exact service path, CDS alias/destination context, or explicit dynamic variable overrides. Otherwise candidates are preserved in edge evidence as ambiguous or unresolved.
5
5
  - Edge states: `REMOTE_CALL_RESOLVES_TO_OPERATION` is used only above the resolution threshold; `DYNAMIC_EDGE_CANDIDATE` preserves runtime-dependent service paths/destinations; `UNRESOLVED_EDGE` carries candidate counts and reasons when static evidence is insufficient.
6
6
  - Trace cycle safety: trace queues carry repository IDs, visited scope keys are independent of depth, graph edge IDs are emitted once, and revisiting an already-seen downstream operation scope creates a cycle marker instead of recursive expansion.
7
7
  - SQLite reliability: the package uses WAL, foreign keys, busy timeouts, and retries around the SQLite adapter. Statement failures throw before output rendering so commands do not report successful JSON/table/Mermaid results after an internal database failure.
8
+
9
+ ## 0.1.4 trace-correctness additions
10
+
11
+ - Helper exports are normalized through a public-to-local export map, so `export { helper }` and `export { helper as publicHelper }` both resolve to the local declaration that contains the `cds.connect.to(...)` call.
12
+ - Two-argument CAP connections keep alias expressions distinct from `credentials.destination` and `credentials.path` / `credentials.servicePath`; dynamic placeholders from all three fields are retained for later `--var` substitution.
13
+ - Repository discovery validates `.git` markers using `HEAD`, `config`, or gitfile `gitdir:` content and keeps scanning children so outer workspaces can contain many nested repositories.
14
+ - Fresh SQLite stores now declare core parent/child foreign keys with cascading cleanup for repository-owned facts.
@@ -24,6 +24,27 @@ async function discoverRepositories(rootPath, ignore) {
24
24
  const root = path2.resolve(rootPath);
25
25
  const ignored = new Set(ignore);
26
26
  const found = [];
27
+ async function isRealGitMarker(dir) {
28
+ const gitPath = path2.join(dir, ".git");
29
+ try {
30
+ const st = await fs.stat(gitPath);
31
+ if (st.isDirectory()) {
32
+ const children = await fs.readdir(gitPath);
33
+ return children.includes("HEAD") || children.includes("config");
34
+ }
35
+ if (st.isFile()) {
36
+ const text = await fs.readFile(gitPath, "utf8");
37
+ return text.trimStart().startsWith("gitdir:");
38
+ }
39
+ } catch {
40
+ }
41
+ try {
42
+ const fixture = await fs.stat(path2.join(dir, ".git-fixture"));
43
+ return fixture.isFile() || fixture.isDirectory();
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
27
48
  async function walk(dir) {
28
49
  const rel = relativePath(root, dir);
29
50
  if (rel !== "." && rel.split("/").some((part) => ignored.has(part))) return;
@@ -33,14 +54,14 @@ async function discoverRepositories(rootPath, ignore) {
33
54
  } catch {
34
55
  return;
35
56
  }
36
- if (entries.some((e) => e.name === ".git" || e.name === ".git-fixture")) {
57
+ const hasMarker = entries.some((e) => e.name === ".git" || e.name === ".git-fixture");
58
+ if (hasMarker && await isRealGitMarker(dir)) {
37
59
  found.push({
38
60
  name: path2.basename(dir),
39
61
  absolutePath: dir,
40
62
  relativePath: relativePath(root, dir),
41
63
  isGitRepo: true
42
64
  });
43
- return;
44
65
  }
45
66
  for (const entry of entries)
46
67
  if (entry.isDirectory() && !ignore.includes(entry.name))
@@ -507,13 +528,21 @@ function connectFactFromCall(call) {
507
528
  return void 0;
508
529
  const first = call.arguments[0];
509
530
  if (!first) return void 0;
531
+ const second = call.arguments[1];
532
+ const objectArg = ts3.isObjectLiteralExpression(first) ? first : second && ts3.isObjectLiteralExpression(second) ? second : void 0;
533
+ let alias;
534
+ let aliasExpr;
510
535
  if (ts3.isStringLiteralLike(first) || ts3.isNoSubstitutionTemplateLiteral(first))
536
+ alias = first.text;
537
+ else if (!ts3.isObjectLiteralExpression(first))
538
+ aliasExpr = stringValue(first);
539
+ if ((ts3.isStringLiteralLike(first) || ts3.isNoSubstitutionTemplateLiteral(first)) && !objectArg)
511
540
  return { alias: first.text, isDynamic: false, placeholders: [] };
512
- if (!ts3.isObjectLiteralExpression(first))
541
+ if (!objectArg && aliasExpr)
513
542
  return {
514
- servicePathExpr: first.getText(),
543
+ aliasExpr,
515
544
  isDynamic: true,
516
- placeholders: []
545
+ placeholders: placeholders(aliasExpr)
517
546
  };
518
547
  let destinationExpr;
519
548
  let servicePathExpr;
@@ -529,12 +558,15 @@ function connectFactFromCall(call) {
529
558
  visitObject(prop.initializer);
530
559
  }
531
560
  }
532
- visitObject(first);
561
+ if (objectArg) visitObject(objectArg);
533
562
  const ph = [
563
+ ...placeholders(aliasExpr ?? alias),
534
564
  ...placeholders(destinationExpr),
535
565
  ...placeholders(servicePathExpr)
536
566
  ];
537
567
  return {
568
+ alias,
569
+ aliasExpr,
538
570
  destinationExpr,
539
571
  servicePathExpr,
540
572
  isDynamic: ph.length > 0 || !destinationExpr && !servicePathExpr,
@@ -577,7 +609,9 @@ async function readSource(abs) {
577
609
  }
578
610
  async function resolveImport(repoPath, fromFile, spec) {
579
611
  if (!spec.startsWith(".")) return void 0;
580
- const base = path8.resolve(repoPath, path8.dirname(fromFile), spec);
612
+ const rawBase = path8.resolve(repoPath, path8.dirname(fromFile), spec);
613
+ const parsed = path8.parse(rawBase);
614
+ const base = [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"].includes(parsed.ext) ? path8.join(parsed.dir, parsed.name) : rawBase;
581
615
  for (const candidate of [
582
616
  base,
583
617
  `${base}.ts`,
@@ -622,15 +656,33 @@ async function importsFor(repoPath, filePath, sf) {
622
656
  }
623
657
  return imports;
624
658
  }
659
+ function exportedLocalNames(sf) {
660
+ const exports = /* @__PURE__ */ new Map();
661
+ for (const stmt of sf.statements) {
662
+ const direct = ts3.canHaveModifiers(stmt) ? ts3.getModifiers(stmt)?.some(
663
+ (m) => m.kind === ts3.SyntaxKind.ExportKeyword
664
+ ) ?? false : false;
665
+ if (direct && ts3.isFunctionDeclaration(stmt) && stmt.name)
666
+ exports.set(stmt.name.text, stmt.name.text);
667
+ if (direct && ts3.isVariableStatement(stmt)) {
668
+ for (const decl of stmt.declarationList.declarations)
669
+ if (ts3.isIdentifier(decl.name)) exports.set(decl.name.text, decl.name.text);
670
+ }
671
+ if (!ts3.isExportDeclaration(stmt) || !stmt.exportClause) continue;
672
+ if (!ts3.isNamedExports(stmt.exportClause)) continue;
673
+ for (const el of stmt.exportClause.elements)
674
+ exports.set(el.name.text, el.propertyName?.text ?? el.name.text);
675
+ }
676
+ return exports;
677
+ }
625
678
  async function helperBindings(repoPath, filePath) {
626
679
  const sf = await readSource(path8.join(repoPath, filePath));
627
680
  if (!sf) return [];
628
681
  const sourceFileAst = sf;
629
682
  const out = [];
683
+ const exportedLocals = exportedLocalNames(sf);
684
+ const factsByLocal = /* @__PURE__ */ new Map();
630
685
  for (const stmt of sf.statements) {
631
- const exported = ts3.canHaveModifiers(stmt) ? ts3.getModifiers(stmt)?.some(
632
- (m) => m.kind === ts3.SyntaxKind.ExportKeyword
633
- ) ?? false : false;
634
686
  if (ts3.isFunctionDeclaration(stmt) && stmt.name) {
635
687
  let fact;
636
688
  stmt.forEachChild(function visit(node) {
@@ -638,27 +690,29 @@ async function helperBindings(repoPath, filePath) {
638
690
  fact = findConnectInExpression(node.expression);
639
691
  if (!fact) ts3.forEachChild(node, visit);
640
692
  });
641
- if (fact && exported)
642
- out.push({
643
- ...fact,
644
- exportedName: stmt.name.text,
645
- sourceFile: normalizePath(filePath),
646
- sourceLine: lineOf4(sf, stmt)
647
- });
693
+ if (fact) factsByLocal.set(stmt.name.text, { ...fact, sourceLine: lineOf4(sf, stmt) });
648
694
  }
649
695
  if (ts3.isVariableStatement(stmt))
650
696
  for (const decl of stmt.declarationList.declarations) {
651
697
  if (!ts3.isIdentifier(decl.name) || !decl.initializer) continue;
652
698
  const fact = findConnectInExpression(decl.initializer);
653
- if (fact && exported)
654
- out.push({
699
+ if (fact)
700
+ factsByLocal.set(decl.name.text, {
655
701
  ...fact,
656
- exportedName: decl.name.text,
657
- sourceFile: normalizePath(filePath),
658
702
  sourceLine: lineOf4(sourceFileAst, decl)
659
703
  });
660
704
  }
661
705
  }
706
+ for (const [exportedName, localName] of exportedLocals) {
707
+ const fact = factsByLocal.get(localName);
708
+ if (fact)
709
+ out.push({
710
+ ...fact,
711
+ exportedName,
712
+ sourceFile: normalizePath(filePath),
713
+ sourceLine: fact.sourceLine
714
+ });
715
+ }
662
716
  return out;
663
717
  }
664
718
  async function parseServiceBindings(repoPath, filePath) {
@@ -668,6 +722,7 @@ async function parseServiceBindings(repoPath, filePath) {
668
722
  const out = [];
669
723
  const imports = await importsFor(repoPath, filePath, sf);
670
724
  const helperCache = /* @__PURE__ */ new Map();
725
+ const classHelpers = collectClassHelpers(sourceFileAst);
671
726
  async function importedHelper(localName) {
672
727
  const imp = imports.find((i) => i.localName === localName && i.sourceFile);
673
728
  if (!imp?.sourceFile) return void 0;
@@ -697,6 +752,7 @@ async function parseServiceBindings(repoPath, filePath) {
697
752
  out.push({
698
753
  variableName: decl.name.text,
699
754
  alias: resolved.helper.alias,
755
+ aliasExpr: resolved.helper.aliasExpr,
700
756
  destinationExpr: resolved.helper.destinationExpr,
701
757
  servicePathExpr: resolved.helper.servicePathExpr,
702
758
  isDynamic: resolved.helper.isDynamic,
@@ -716,15 +772,105 @@ async function parseServiceBindings(repoPath, filePath) {
716
772
  });
717
773
  }
718
774
  }
775
+ function recordDestructuredClassHelper(decl) {
776
+ if (!ts3.isObjectBindingPattern(decl.name) || !decl.initializer) return;
777
+ const call = unwrapCall(decl.initializer);
778
+ if (!call || !ts3.isPropertyAccessExpression(call.expression)) return;
779
+ const target = call.expression;
780
+ if (target.expression.kind !== ts3.SyntaxKind.ThisKeyword) return;
781
+ for (const el of decl.name.elements) {
782
+ if (!ts3.isIdentifier(el.name)) continue;
783
+ const propertyName = el.propertyName && ts3.isIdentifier(el.propertyName) ? el.propertyName.text : el.name.text;
784
+ const helper = classHelpers.find(
785
+ (h) => h.helperName === target.name.text && h.propertyName === propertyName
786
+ );
787
+ if (!helper) continue;
788
+ out.push({
789
+ variableName: el.name.text,
790
+ ...helper.fact,
791
+ sourceFile: normalizePath(filePath),
792
+ sourceLine: lineOf4(sourceFileAst, decl),
793
+ helperChain: [
794
+ {
795
+ callerVariable: el.name.text,
796
+ className: helper.className,
797
+ classHelper: helper.helperName,
798
+ returnedProperty: helper.propertyName,
799
+ helperVariable: helper.variableName,
800
+ helperSourceFile: normalizePath(filePath),
801
+ helperSourceLine: helper.sourceLine
802
+ }
803
+ ]
804
+ });
805
+ }
806
+ }
719
807
  const declarations = [];
720
808
  function collectDeclarations(node) {
721
809
  if (ts3.isVariableDeclaration(node)) declarations.push(node);
722
810
  ts3.forEachChild(node, collectDeclarations);
723
811
  }
724
812
  collectDeclarations(sourceFileAst);
725
- for (const decl of declarations) await recordVariable(decl);
813
+ for (const decl of declarations) {
814
+ recordDestructuredClassHelper(decl);
815
+ await recordVariable(decl);
816
+ }
726
817
  return out;
727
818
  }
819
+ function collectClassHelpers(sf) {
820
+ const helpers = [];
821
+ for (const stmt of sf.statements) {
822
+ if (!ts3.isClassDeclaration(stmt) || !stmt.name) continue;
823
+ for (const member of stmt.members) {
824
+ let visit2 = function(node) {
825
+ if (ts3.isVariableDeclaration(node) && ts3.isIdentifier(node.name) && node.initializer) {
826
+ const fact = findConnectInExpression(node.initializer);
827
+ if (fact) bindings.set(node.name.text, fact);
828
+ }
829
+ if (ts3.isReturnStatement(node) && node.expression && ts3.isObjectLiteralExpression(node.expression)) {
830
+ for (const prop of node.expression.properties) {
831
+ if (ts3.isShorthandPropertyAssignment(prop)) {
832
+ const fact = bindings.get(prop.name.text);
833
+ if (fact)
834
+ helpers.push({
835
+ className,
836
+ helperName,
837
+ propertyName: prop.name.text,
838
+ variableName: prop.name.text,
839
+ fact,
840
+ sourceLine: lineOf4(sf, prop)
841
+ });
842
+ }
843
+ if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.initializer)) {
844
+ const propertyName = ts3.isIdentifier(prop.name) || ts3.isStringLiteralLike(prop.name) ? prop.name.text : void 0;
845
+ const fact = propertyName ? bindings.get(prop.initializer.text) : void 0;
846
+ if (propertyName && fact)
847
+ helpers.push({
848
+ className,
849
+ helperName,
850
+ propertyName,
851
+ variableName: prop.initializer.text,
852
+ fact,
853
+ sourceLine: lineOf4(sf, prop)
854
+ });
855
+ }
856
+ }
857
+ }
858
+ ts3.forEachChild(node, visit2);
859
+ };
860
+ var visit = visit2;
861
+ if (!ts3.isPropertyDeclaration(member) || !member.initializer) continue;
862
+ if (!ts3.isIdentifier(member.name)) continue;
863
+ const className = stmt.name.text;
864
+ const helperName = member.name.text;
865
+ const initializer = member.initializer;
866
+ if (!ts3.isArrowFunction(initializer) && !ts3.isFunctionExpression(initializer))
867
+ continue;
868
+ const bindings = /* @__PURE__ */ new Map();
869
+ visit2(initializer);
870
+ }
871
+ }
872
+ return helpers;
873
+ }
728
874
 
729
875
  // src/linker/dynamic-edge-resolver.ts
730
876
  function applyVariables(template, vars) {
@@ -851,7 +997,7 @@ function linkWorkspace(db, workspaceId, vars = {}) {
851
997
  let edges = linkHelperPackages(db, workspaceId);
852
998
  let unresolved = 0;
853
999
  const calls = db.prepare(
854
- `SELECT c.*,r.name repoName,b.alias,b.destination_expr destinationExpr,b.service_path_expr servicePathExpr,b.is_dynamic isDynamic,b.placeholders_json placeholdersJson,b.helper_chain_json helperChainJson,req.service_path requireServicePath,req.destination requireDestination FROM outbound_calls c JOIN repositories r ON r.id=c.repo_id LEFT JOIN service_bindings b ON b.id=c.service_binding_id LEFT JOIN cds_requires req ON req.repo_id=c.repo_id AND req.alias=b.alias WHERE r.workspace_id=?`
1000
+ `SELECT c.*,r.name repoName,b.alias,b.alias_expr aliasExpr,b.destination_expr destinationExpr,b.service_path_expr servicePathExpr,b.is_dynamic isDynamic,b.placeholders_json placeholdersJson,b.helper_chain_json helperChainJson,req.service_path requireServicePath,req.destination requireDestination FROM outbound_calls c JOIN repositories r ON r.id=c.repo_id LEFT JOIN service_bindings b ON b.id=c.service_binding_id LEFT JOIN cds_requires req ON req.repo_id=c.repo_id AND req.alias=b.alias WHERE r.workspace_id=?`
855
1001
  ).all(workspaceId);
856
1002
  for (const call of calls) {
857
1003
  const callType = String(call.call_type);
@@ -882,6 +1028,7 @@ function linkWorkspace(db, workspaceId, vars = {}) {
882
1028
  line: call.source_line,
883
1029
  repo: call.repoName,
884
1030
  serviceAlias: call.alias,
1031
+ serviceAliasExpr: call.aliasExpr,
885
1032
  destination,
886
1033
  servicePath,
887
1034
  operationPath: op,
@@ -1163,4 +1310,4 @@ export {
1163
1310
  linkWorkspace,
1164
1311
  trace
1165
1312
  };
1166
- //# sourceMappingURL=chunk-SIKIGT42.js.map
1313
+ //# sourceMappingURL=chunk-JY6GBGZT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/discovery/discover-repositories.ts","../src/utils/path-utils.ts","../src/parsers/package-json-parser.ts","../src/parsers/cds-parser.ts","../src/parsers/decorator-parser.ts","../src/parsers/ts-project.ts","../src/parsers/handler-registration-parser.ts","../src/utils/redaction.ts","../src/parsers/outbound-call-parser.ts","../src/parsers/service-binding-parser.ts","../src/linker/dynamic-edge-resolver.ts","../src/linker/service-resolver.ts","../src/linker/helper-package-linker.ts","../src/linker/cross-repo-linker.ts","../src/trace/trace-engine.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { DiscoveredRepository } from '../types.js';\nimport { relativePath } from '../utils/path-utils.js';\nexport async function discoverRepositories(\n rootPath: string,\n ignore: readonly string[]\n): Promise<DiscoveredRepository[]> {\n const root = path.resolve(rootPath);\n const ignored = new Set(ignore);\n const found: DiscoveredRepository[] = [];\n async function isRealGitMarker(dir: string): Promise<boolean> {\n const gitPath = path.join(dir, '.git');\n try {\n const st = await fs.stat(gitPath);\n if (st.isDirectory()) {\n const children = await fs.readdir(gitPath);\n return children.includes('HEAD') || children.includes('config');\n }\n if (st.isFile()) {\n const text = await fs.readFile(gitPath, 'utf8');\n return text.trimStart().startsWith('gitdir:');\n }\n } catch {\n /* not a normal git marker */\n }\n try {\n const fixture = await fs.stat(path.join(dir, '.git-fixture'));\n return fixture.isFile() || fixture.isDirectory();\n } catch {\n return false;\n }\n }\n async function walk(dir: string): Promise<void> {\n const rel = relativePath(root, dir);\n if (rel !== '.' && rel.split('/').some((part) => ignored.has(part))) return;\n let entries: Array<{ name: string; isDirectory: () => boolean }>;\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n const hasMarker = entries.some((e) => e.name === '.git' || e.name === '.git-fixture');\n if (hasMarker && await isRealGitMarker(dir)) {\n found.push({\n name: path.basename(dir),\n absolutePath: dir,\n relativePath: relativePath(root, dir),\n isGitRepo: true\n });\n }\n for (const entry of entries)\n if (entry.isDirectory() && !ignore.includes(entry.name))\n await walk(path.join(dir, entry.name));\n }\n await walk(root);\n return found.sort((a, b) => a.relativePath.localeCompare(b.relativePath));\n}\n","import path from 'node:path';\nexport function normalizePath(value: string): string {\n return value.split(path.sep).join('/');\n}\nexport function relativePath(root: string, value: string): string {\n return normalizePath(path.relative(root, value) || '.');\n}\nexport function ensureLeadingSlash(value: string): string {\n return value.startsWith('/') ? value : `/${value}`;\n}\nexport function stripQuotes(value: string): string {\n return value.replace(/^['\"`]|['\"`]$/g, '');\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CdsRequire, PackageFacts } from '../types.js';\nfunction recordOfString(value: unknown): Record<string, string> {\n if (!value || typeof value !== 'object') return {};\n return Object.fromEntries(\n Object.entries(value).filter(([, v]) => typeof v === 'string')\n ) as Record<string, string>;\n}\nfunction readRequires(cds: unknown): CdsRequire[] {\n const requires =\n cds && typeof cds === 'object' && 'requires' in cds\n ? (cds as { requires?: unknown }).requires\n : undefined;\n if (!requires || typeof requires !== 'object') return [];\n return Object.entries(requires).flatMap(([alias, raw]) => {\n if (!raw || typeof raw !== 'object') return [];\n const obj = raw as Record<string, unknown>;\n const credentials =\n obj.credentials && typeof obj.credentials === 'object'\n ? (obj.credentials as Record<string, unknown>)\n : {};\n return [\n {\n alias,\n kind: typeof obj.kind === 'string' ? obj.kind : undefined,\n model: typeof obj.model === 'string' ? obj.model : undefined,\n destination:\n typeof credentials.destination === 'string'\n ? credentials.destination\n : undefined,\n servicePath:\n typeof credentials.path === 'string' ? credentials.path : undefined,\n requestTimeout:\n typeof credentials.requestTimeout === 'number'\n ? credentials.requestTimeout\n : undefined,\n rawJson: JSON.stringify(raw)\n }\n ];\n });\n}\nexport async function parsePackageJson(\n repoPath: string\n): Promise<PackageFacts> {\n try {\n const raw = await fs.readFile(path.join(repoPath, 'package.json'), 'utf8');\n const json = JSON.parse(raw) as Record<string, unknown>;\n return {\n packageName: typeof json.name === 'string' ? json.name : undefined,\n packageVersion:\n typeof json.version === 'string' ? json.version : undefined,\n dependencies: {\n ...recordOfString(json.dependencies),\n ...recordOfString(json.devDependencies)\n },\n cdsRequires: readRequires(json.cds),\n scripts: recordOfString(json.scripts)\n };\n } catch {\n return { dependencies: {}, cdsRequires: [], scripts: {} };\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CdsOperationFact, CdsServiceFact } from '../types.js';\nimport { ensureLeadingSlash, normalizePath } from '../utils/path-utils.js';\n\nfunction lineOf(text: string, index: number): number {\n return text.slice(0, index).split('\\n').length;\n}\n\nfunction maskCommentsAndStrings(text: string): string {\n let out = '';\n let mode: 'code' | 'line' | 'block' | 'single' | 'double' | 'template' =\n 'code';\n for (let i = 0; i < text.length; i += 1) {\n const c = text[i] ?? '';\n const n = text[i + 1] ?? '';\n if (mode === 'code' && c === '/' && n === '/') {\n mode = 'line';\n out += ' ';\n i += 1;\n continue;\n }\n if (mode === 'code' && c === '/' && n === '*') {\n mode = 'block';\n out += ' ';\n i += 1;\n continue;\n }\n if (mode === 'line' && c === '\\n') mode = 'code';\n if (mode === 'block' && c === '*' && n === '/') {\n mode = 'code';\n out += ' ';\n i += 1;\n continue;\n }\n if (mode === 'code' && (c === \"'\" || c === '\"' || c === '`')) {\n mode = c === \"'\" ? 'single' : c === '\"' ? 'double' : 'template';\n out += ' ';\n continue;\n }\n if ((mode === 'single' && c === \"'\") || (mode === 'double' && c === '\"') || (mode === 'template' && c === '`'))\n mode = 'code';\n out += mode === 'code' || c === '\\n' ? c : ' ';\n }\n return out;\n}\n\nfunction readAnnotation(text: string, index: number): { end: number; raw: string } | undefined {\n if (text[index] !== '@') return undefined;\n let i = index + 1;\n while (/\\s/.test(text[i] ?? '')) i += 1;\n if (text[i] !== '(') return undefined;\n let depth = 0;\n for (; i < text.length; i += 1) {\n if (text[i] === '(') depth += 1;\n if (text[i] === ')') depth -= 1;\n if (depth === 0) return { end: i + 1, raw: text.slice(index, i + 1) };\n }\n return undefined;\n}\n\nfunction collectAnnotations(text: string, index: number): { end: number; raw: string } {\n let i = index;\n let raw = '';\n while (i < text.length) {\n while (/\\s/.test(text[i] ?? '')) i += 1;\n const annotation = readAnnotation(text, i);\n if (!annotation) break;\n raw += annotation.raw;\n i = annotation.end;\n }\n return { end: i, raw };\n}\n\nfunction pathAnnotation(raw: string): string | undefined {\n return /path\\s*:\\s*['\"]([^'\"]+)['\"]/s.exec(raw)?.[1];\n}\n\nfunction matchingBrace(text: string, open: number): number {\n let depth = 0;\n for (let i = open; i < text.length; i += 1) {\n if (text[i] === '{') depth += 1;\n if (text[i] === '}') depth -= 1;\n if (depth === 0) return i;\n }\n return text.length - 1;\n}\n\nfunction operationsFromBody(text: string, maskedBody: string, bodyOffset: number, filePath: string): CdsOperationFact[] {\n return [...maskedBody.matchAll(/\\b(action|function|event)\\s+(\\w+)\\s*(?:\\(([^)]*)\\))?\\s*(?:returns\\s+([^;{]+))?/g)].map((m) => ({\n operationType: (m[1] as 'action' | 'function' | 'event') ?? 'action',\n operationName: m[2] ?? 'unknown',\n operationPath: ensureLeadingSlash(m[2] ?? 'unknown'),\n paramsJson: JSON.stringify((m[3] ?? '').split(',').map((part) => part.trim()).filter(Boolean)),\n returnType: m[4]?.trim(),\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, bodyOffset + (m.index ?? 0))\n }));\n}\n\nexport async function parseCdsFile(repoPath: string, filePath: string): Promise<CdsServiceFact[]> {\n const absolute = path.join(repoPath, filePath);\n const text = await fs.readFile(absolute, 'utf8');\n const masked = maskCommentsAndStrings(text);\n const namespace = /namespace\\s+([\\w.]+)\\s*;/.exec(masked)?.[1];\n const services: CdsServiceFact[] = [];\n const pendingAnnotations: Array<{ end: number; raw: string }> = [];\n for (const a of masked.matchAll(/@\\s*\\(/g)) {\n const annotation = collectAnnotations(masked, a.index ?? 0);\n pendingAnnotations.push(annotation);\n }\n const serviceRegex = /\\b(extend\\s+)?service\\s+([\\w.]+)\\b/g;\n let match: RegExpExecArray | null;\n while ((match = serviceRegex.exec(masked))) {\n const afterName = collectAnnotations(masked, serviceRegex.lastIndex);\n const open = masked.indexOf('{', afterName.end);\n if (open === -1) continue;\n const matchIndex = match.index;\n const prefix = pendingAnnotations\n .filter((a) => a.end <= matchIndex && matchIndex - a.end < 8)\n .map((a) => a.raw)\n .join('');\n const annotations = `${prefix}${afterName.raw}`;\n const end = matchingBrace(masked, open);\n const body = masked.slice(open + 1, end);\n const name = match[2] ?? 'UnknownService';\n const serviceName = name.split('.').pop() ?? name;\n const servicePath = ensureLeadingSlash(pathAnnotation(annotations) ?? serviceName);\n services.push({\n namespace,\n serviceName,\n qualifiedName: name.includes('.') ? name : namespace ? `${namespace}.${name}` : name,\n servicePath,\n isExtend: Boolean(match[1]),\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, match.index),\n operations: operationsFromBody(text, body, open + 1, filePath)\n });\n serviceRegex.lastIndex = end + 1;\n }\n const baseOps = new Map(services.filter((s) => !s.isExtend).map((s) => [s.qualifiedName, s.operations]));\n for (const service of services.filter((s) => s.isExtend && s.operations.length === 0)) {\n const inherited = baseOps.get(service.qualifiedName) ?? baseOps.get(service.serviceName);\n if (inherited) service.operations = inherited.map((op) => ({ ...op, sourceFile: service.sourceFile, sourceLine: service.sourceLine }));\n }\n return services;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport ts from 'typescript';\nimport type { HandlerClassFact } from '../types.js';\nimport { createSourceFile } from './ts-project.js';\nimport { normalizePath, stripQuotes } from '../utils/path-utils.js';\nfunction line(sf: ts.SourceFile, pos: number): number {\n return sf.getLineAndCharacterOfPosition(pos).line + 1;\n}\nfunction decs(node: ts.Node): ts.Decorator[] {\n return ts.canHaveDecorators(node) ? [...(ts.getDecorators(node) ?? [])] : [];\n}\nfunction callName(d: ts.Decorator): string {\n const e = d.expression;\n return ts.isCallExpression(e) ? e.expression.getText() : e.getText();\n}\nfunction firstArg(d: ts.Decorator): string {\n const e = d.expression;\n return ts.isCallExpression(e) && e.arguments[0]\n ? e.arguments[0].getText()\n : '';\n}\nexport async function parseDecorators(\n repoPath: string,\n filePath: string\n): Promise<HandlerClassFact[]> {\n const text = await fs.readFile(path.join(repoPath, filePath), 'utf8');\n const sf = createSourceFile(filePath, text);\n const constants = new Map<string, string>();\n const handlers: HandlerClassFact[] = [];\n function visit(node: ts.Node): void {\n if (\n ts.isVariableDeclaration(node) &&\n ts.isIdentifier(node.name) &&\n node.initializer &&\n ts.isStringLiteralLike(node.initializer)\n )\n constants.set(node.name.text, node.initializer.text);\n if (ts.isClassDeclaration(node)) {\n const className = node.name?.text ?? 'AnonymousHandler';\n const hasHandler = decs(node).some((d) => callName(d) === 'Handler');\n const methods = node.members.filter(ts.isMethodDeclaration).flatMap((m) =>\n decs(m)\n .filter((d) =>\n ['Func', 'Action', 'On', 'Event'].includes(callName(d))\n )\n .map((d) => {\n const raw = firstArg(d);\n const value =\n raw.startsWith('\"') || raw.startsWith(\"'\") || raw.startsWith('`')\n ? stripQuotes(raw)\n : (constants.get(raw) ??\n (raw.endsWith('.name') ? raw.split('.').at(-2) : undefined));\n return {\n methodName: m.name.getText(),\n decoratorKind: callName(d),\n decoratorValue: value,\n decoratorRawExpression: raw,\n sourceFile: normalizePath(filePath),\n sourceLine: line(sf, m.getStart())\n };\n })\n );\n if (hasHandler || methods.length > 0)\n handlers.push({\n className,\n sourceFile: normalizePath(filePath),\n sourceLine: line(sf, node.getStart()),\n methods\n });\n }\n ts.forEachChild(node, visit);\n }\n visit(sf);\n return handlers;\n}\n","import ts from 'typescript';\nexport function createSourceFile(\n filePath: string,\n text: string\n): ts.SourceFile {\n return ts.createSourceFile(\n filePath,\n text,\n ts.ScriptTarget.Latest,\n true,\n filePath.endsWith('.js') ? ts.ScriptKind.JS : ts.ScriptKind.TS\n );\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { HandlerRegistrationFact } from '../types.js';\nimport { normalizePath } from '../utils/path-utils.js';\nfunction lineOf(text: string, idx: number): number {\n return text.slice(0, idx).split('\\n').length;\n}\nexport async function parseHandlerRegistrations(\n repoPath: string,\n filePath: string\n): Promise<HandlerRegistrationFact[]> {\n const text = await fs.readFile(path.join(repoPath, filePath), 'utf8');\n const out: HandlerRegistrationFact[] = [];\n for (const m of text.matchAll(\n /createCombinedHandler\\s*\\(|srv\\.prepend\\s*\\(|cds\\.serve\\s*\\(/g\n ))\n out.push({\n registrationFile: normalizePath(filePath),\n registrationLine: lineOf(text, m.index ?? 0),\n registrationKind: m[0].startsWith('cds')\n ? 'cds.serve'\n : 'combined-handler',\n confidence: 0.8\n });\n for (const m of text.matchAll(\n /(?:const|export\\s+const)\\s+handlers\\s*=\\s*\\[([\\s\\S]*?)\\]/g\n ))\n for (const c of (m[1] ?? '').matchAll(/\\b(\\w+Handler)\\b/g))\n out.push({\n className: c[1],\n registrationFile: normalizePath(filePath),\n registrationLine: lineOf(text, (m.index ?? 0) + (c.index ?? 0)),\n registrationKind: 'handler-array',\n confidence: 0.9\n });\n return out;\n}\n","const SENSITIVE = /authorization|cookie|token|secret|password|key|credential/i;\nexport function redactText(text: string): string {\n return text.replace(\n /(authorization|cookie|token|secret|password|key|credential)\\s*[:=]\\s*(['\"`]?)[^,'\"`}\\s]+\\2/gi,\n '$1: [REDACTED]'\n );\n}\nexport function redactValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(redactValue);\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value))\n out[k] = SENSITIVE.test(k) ? '[REDACTED]' : redactValue(v);\n return out;\n }\n return typeof value === 'string' ? redactText(value) : value;\n}\nexport function summarizeExpression(text: string): string {\n return redactText(text).slice(0, 240);\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { OutboundCallFact } from '../types.js';\nimport { normalizePath, stripQuotes } from '../utils/path-utils.js';\nimport { summarizeExpression } from '../utils/redaction.js';\nfunction lineOf(text: string, idx: number): number {\n return text.slice(0, idx).split('\\n').length;\n}\nfunction firstArg(body: string, key: string): string | undefined {\n return new RegExp(`${key}\\\\s*:\\\\s*([^,}\\\\n]+)`).exec(body)?.[1]?.trim();\n}\nfunction matchingParen(text: string, open: number): number {\n let depth = 0;\n let quote: string | undefined;\n let escaped = false;\n for (let i = open; i < text.length; i += 1) {\n const ch = text[i] ?? '';\n if (quote) {\n if (escaped) escaped = false;\n else if (ch === '\\\\') escaped = true;\n else if (ch === quote) quote = undefined;\n continue;\n }\n if (ch === '\"' || ch === \"'\" || ch === '`') {\n quote = ch;\n continue;\n }\n if (ch === '(') depth += 1;\n if (ch === ')') {\n depth -= 1;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\nfunction argumentForCall(expr: string, marker: string): string | undefined {\n const idx = expr.indexOf(marker);\n if (idx < 0) return undefined;\n const open = expr.indexOf('(', idx + marker.length);\n if (open < 0) return undefined;\n const close = matchingParen(expr, open);\n return close > open ? expr.slice(open + 1, close).trim() : undefined;\n}\nfunction entityFromArg(arg: string | undefined): string | undefined {\n if (!arg) return undefined;\n const first = arg.split(',')[0]?.trim();\n if (!first) return undefined;\n return stripQuotes(first).replace(/^this\\./, '');\n}\nfunction extractQueryEntity(expr: string): string | undefined {\n return (\n entityFromArg(argumentForCall(expr, 'SELECT.one.from')) ??\n entityFromArg(argumentForCall(expr, 'SELECT.from')) ??\n entityFromArg(argumentForCall(expr, 'INSERT.into')) ??\n entityFromArg(argumentForCall(expr, 'UPDATE')) ??\n entityFromArg(argumentForCall(expr, 'DELETE.from'))\n );\n}\nexport async function parseOutboundCalls(\n repoPath: string,\n filePath: string,\n): Promise<OutboundCallFact[]> {\n const text = await fs.readFile(path.join(repoPath, filePath), 'utf8');\n const out: OutboundCallFact[] = [];\n for (const m of text.matchAll(/(\\w+)\\.send\\s*\\(\\s*\\{([\\s\\S]*?)\\}\\s*\\)/g)) {\n const body = m[2] ?? '';\n const query = firstArg(body, 'query');\n const op = firstArg(body, 'path') ?? firstArg(body, 'event');\n out.push({\n callType: query ? 'remote_query' : 'remote_action',\n serviceVariableName: m[1],\n method: stripQuotes(firstArg(body, 'method') ?? 'POST'),\n operationPathExpr: op\n ? `/${stripQuotes(op).replace(/^\\//, '')}`\n : undefined,\n queryEntity: extractQueryEntity(query ?? ''),\n payloadSummary: summarizeExpression(body),\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, m.index ?? 0),\n confidence: op || query ? 0.8 : 0.4,\n });\n }\n for (const m of text.matchAll(/cds\\.run\\s*\\(/g)) {\n const open = (m.index ?? 0) + m[0].lastIndexOf('(');\n const close = matchingParen(text, open);\n const expr = close > open ? text.slice(open + 1, close) : '';\n const entity = extractQueryEntity(expr);\n out.push({\n callType: 'local_db_query',\n queryEntity: entity,\n payloadSummary: summarizeExpression(expr),\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, m.index ?? 0),\n confidence: entity ? 0.9 : 0.55,\n unresolvedReason: entity\n ? undefined\n : 'Could not resolve CAP query target entity from nested expression',\n });\n }\n for (const m of text.matchAll(\n /(\\w+)\\.(emit|publish|on)\\s*\\(\\s*(['\"`])([^'\"`]+)\\3/g,\n ))\n out.push({\n callType: m[2] === 'on' ? 'async_subscribe' : 'async_emit',\n serviceVariableName: m[1],\n eventNameExpr: m[4],\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, m.index ?? 0),\n confidence: 0.8,\n });\n for (const m of text.matchAll(\n /(?:axios\\s*\\(|executeHttpRequest\\s*\\(|useOrFetchDestination\\s*\\()([\\s\\S]*?)\\)/g,\n ))\n out.push({\n callType: 'external_http',\n payloadSummary: summarizeExpression(m[1] ?? ''),\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, m.index ?? 0),\n confidence: 0.7,\n unresolvedReason:\n 'External HTTP destination is outside indexed CAP services',\n });\n for (const m of text.matchAll(\n /cds\\.services(?:\\[['\"]([^'\"]+)['\"]\\]|\\.(\\w+))\\.(\\w+)\\s*\\(/g,\n ))\n out.push({\n callType: 'local_service_call',\n operationPathExpr: `/${m[3] ?? ''}`,\n payloadSummary: m[1] ?? m[2],\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(text, m.index ?? 0),\n confidence: 0.75,\n });\n return out;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport ts from 'typescript';\nimport type { ServiceBindingFact } from '../types.js';\nimport { normalizePath } from '../utils/path-utils.js';\n\ninterface HelperBinding {\n exportedName: string;\n alias?: string;\n aliasExpr?: string;\n destinationExpr?: string;\n servicePathExpr?: string;\n isDynamic: boolean;\n placeholders: string[];\n sourceFile: string;\n sourceLine: number;\n}\ninterface ImportBinding {\n localName: string;\n exportedName: string;\n sourceFile?: string;\n}\ninterface ClassHelperReturn {\n className: string;\n helperName: string;\n propertyName: string;\n variableName: string;\n fact: Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'>;\n sourceLine: number;\n}\n\nfunction lineOf(sf: ts.SourceFile, node: ts.Node): number {\n return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n}\nfunction stringValue(node: ts.Expression | undefined): string | undefined {\n if (!node) return undefined;\n if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node))\n return node.text;\n if (ts.isTemplateExpression(node))\n return node.getText().replace(/^`|`$/g, '');\n return node.getText();\n}\nfunction placeholders(value?: string): string[] {\n return [...(value ?? '').matchAll(/\\$\\{\\s*(\\w+)\\s*\\}/g)]\n .map((m) => m[1] ?? '')\n .filter(Boolean);\n}\nfunction connectFactFromCall(\n call: ts.CallExpression,\n):\n | Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'>\n | undefined {\n const expr = call.expression;\n if (!ts.isPropertyAccessExpression(expr) || expr.name.text !== 'to')\n return undefined;\n const inner = expr.expression;\n if (\n !ts.isPropertyAccessExpression(inner) ||\n inner.name.text !== 'connect' ||\n inner.expression.getText() !== 'cds'\n )\n return undefined;\n const first = call.arguments[0];\n if (!first) return undefined;\n const second = call.arguments[1];\n const objectArg = ts.isObjectLiteralExpression(first)\n ? first\n : second && ts.isObjectLiteralExpression(second)\n ? second\n : undefined;\n let alias: string | undefined;\n let aliasExpr: string | undefined;\n if (ts.isStringLiteralLike(first) || ts.isNoSubstitutionTemplateLiteral(first))\n alias = first.text;\n else if (!ts.isObjectLiteralExpression(first))\n aliasExpr = stringValue(first);\n if (\n (ts.isStringLiteralLike(first) || ts.isNoSubstitutionTemplateLiteral(first)) &&\n !objectArg\n )\n return { alias: first.text, isDynamic: false, placeholders: [] };\n if (!objectArg && aliasExpr)\n return {\n aliasExpr,\n isDynamic: true,\n placeholders: placeholders(aliasExpr),\n };\n let destinationExpr: string | undefined;\n let servicePathExpr: string | undefined;\n function visitObject(obj: ts.ObjectLiteralExpression): void {\n for (const prop of obj.properties) {\n if (!ts.isPropertyAssignment(prop)) continue;\n const name =\n ts.isIdentifier(prop.name) || ts.isStringLiteralLike(prop.name)\n ? prop.name.text\n : undefined;\n if (name === 'destination')\n destinationExpr = stringValue(prop.initializer);\n if (name === 'path' || name === 'servicePath')\n servicePathExpr = stringValue(prop.initializer);\n if (ts.isObjectLiteralExpression(prop.initializer))\n visitObject(prop.initializer);\n }\n }\n if (objectArg) visitObject(objectArg);\n const ph = [\n ...placeholders(aliasExpr ?? alias),\n ...placeholders(destinationExpr),\n ...placeholders(servicePathExpr),\n ];\n return {\n alias,\n aliasExpr,\n destinationExpr,\n servicePathExpr,\n isDynamic: ph.length > 0 || (!destinationExpr && !servicePathExpr),\n placeholders: ph,\n };\n}\nfunction unwrapCall(expr: ts.Expression): ts.CallExpression | undefined {\n if (ts.isAwaitExpression(expr)) return unwrapCall(expr.expression);\n if (ts.isCallExpression(expr)) return expr;\n return undefined;\n}\nfunction findConnectInExpression(\n expr: ts.Expression,\n):\n | Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'>\n | undefined {\n const direct = unwrapCall(expr);\n if (direct) {\n const fact = connectFactFromCall(direct);\n if (fact) return fact;\n }\n let found:\n | Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'>\n | undefined;\n function visit(node: ts.Node): void {\n if (found) return;\n if (ts.isCallExpression(node)) found = connectFactFromCall(node);\n if (!found) ts.forEachChild(node, visit);\n }\n visit(expr);\n return found;\n}\nasync function readSource(abs: string): Promise<ts.SourceFile | undefined> {\n try {\n const text = await fs.readFile(abs, 'utf8');\n return ts.createSourceFile(\n abs,\n text,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n } catch {\n return undefined;\n }\n}\nasync function resolveImport(\n repoPath: string,\n fromFile: string,\n spec: string,\n): Promise<string | undefined> {\n if (!spec.startsWith('.')) return undefined;\n const rawBase = path.resolve(repoPath, path.dirname(fromFile), spec);\n const parsed = path.parse(rawBase);\n const base = ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'].includes(parsed.ext)\n ? path.join(parsed.dir, parsed.name)\n : rawBase;\n for (const candidate of [\n base,\n `${base}.ts`,\n `${base}.js`,\n path.join(base, 'index.ts'),\n path.join(base, 'index.js'),\n ]) {\n try {\n const st = await fs.stat(candidate);\n if (st.isFile()) return normalizePath(path.relative(repoPath, candidate));\n } catch {\n /* continue */\n }\n }\n return undefined;\n}\nasync function importsFor(\n repoPath: string,\n filePath: string,\n sf: ts.SourceFile,\n): Promise<ImportBinding[]> {\n const imports: ImportBinding[] = [];\n for (const stmt of sf.statements) {\n if (\n !ts.isImportDeclaration(stmt) ||\n !ts.isStringLiteralLike(stmt.moduleSpecifier)\n )\n continue;\n const sourceFile = await resolveImport(\n repoPath,\n filePath,\n stmt.moduleSpecifier.text,\n );\n const clause = stmt.importClause;\n if (!clause) continue;\n if (clause.name)\n imports.push({\n localName: clause.name.text,\n exportedName: 'default',\n sourceFile,\n });\n const bindings = clause.namedBindings;\n if (bindings && ts.isNamedImports(bindings))\n for (const el of bindings.elements)\n imports.push({\n localName: el.name.text,\n exportedName: el.propertyName?.text ?? el.name.text,\n sourceFile,\n });\n }\n return imports;\n}\nfunction exportedLocalNames(sf: ts.SourceFile): Map<string, string> {\n const exports = new Map<string, string>();\n for (const stmt of sf.statements) {\n const direct = ts.canHaveModifiers(stmt)\n ? (ts\n .getModifiers(stmt)\n ?.some(\n (m: ts.ModifierLike) => m.kind === ts.SyntaxKind.ExportKeyword,\n ) ?? false)\n : false;\n if (direct && ts.isFunctionDeclaration(stmt) && stmt.name)\n exports.set(stmt.name.text, stmt.name.text);\n if (direct && ts.isVariableStatement(stmt))\n for (const decl of stmt.declarationList.declarations)\n if (ts.isIdentifier(decl.name)) exports.set(decl.name.text, decl.name.text);\n if (!ts.isExportDeclaration(stmt) || !stmt.exportClause) continue;\n if (!ts.isNamedExports(stmt.exportClause)) continue;\n for (const el of stmt.exportClause.elements)\n exports.set(el.name.text, el.propertyName?.text ?? el.name.text);\n }\n return exports;\n}\nasync function helperBindings(\n repoPath: string,\n filePath: string,\n): Promise<HelperBinding[]> {\n const sf = await readSource(path.join(repoPath, filePath));\n if (!sf) return [];\n const sourceFileAst = sf;\n const out: HelperBinding[] = [];\n const exportedLocals = exportedLocalNames(sf);\n const factsByLocal = new Map<\n string,\n Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'> & {\n sourceLine: number;\n }\n >();\n for (const stmt of sf.statements) {\n if (ts.isFunctionDeclaration(stmt) && stmt.name) {\n let fact:\n | Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'>\n | undefined;\n stmt.forEachChild(function visit(node): void {\n if (!fact && ts.isReturnStatement(node) && node.expression)\n fact = findConnectInExpression(node.expression);\n if (!fact) ts.forEachChild(node, visit);\n });\n if (fact) factsByLocal.set(stmt.name.text, { ...fact, sourceLine: lineOf(sf, stmt) });\n }\n if (ts.isVariableStatement(stmt))\n for (const decl of stmt.declarationList.declarations) {\n if (!ts.isIdentifier(decl.name) || !decl.initializer) continue;\n const fact = findConnectInExpression(decl.initializer);\n if (fact)\n factsByLocal.set(decl.name.text, {\n ...fact,\n sourceLine: lineOf(sourceFileAst, decl),\n });\n }\n }\n for (const [exportedName, localName] of exportedLocals) {\n const fact = factsByLocal.get(localName);\n if (fact)\n out.push({\n ...fact,\n exportedName,\n sourceFile: normalizePath(filePath),\n sourceLine: fact.sourceLine,\n });\n }\n return out;\n}\n\nexport async function parseServiceBindings(\n repoPath: string,\n filePath: string,\n): Promise<ServiceBindingFact[]> {\n const sf = await readSource(path.join(repoPath, filePath));\n if (!sf) return [];\n const sourceFileAst = sf;\n const out: ServiceBindingFact[] = [];\n const imports = await importsFor(repoPath, filePath, sf);\n const helperCache = new Map<string, HelperBinding[]>();\n const classHelpers = collectClassHelpers(sourceFileAst);\n async function importedHelper(\n localName: string,\n ): Promise<{ imp: ImportBinding; helper: HelperBinding } | undefined> {\n const imp = imports.find((i) => i.localName === localName && i.sourceFile);\n if (!imp?.sourceFile) return undefined;\n if (!helperCache.has(imp.sourceFile))\n helperCache.set(\n imp.sourceFile,\n await helperBindings(repoPath, imp.sourceFile),\n );\n const helper = helperCache\n .get(imp.sourceFile)\n ?.find((h) => h.exportedName === imp.exportedName);\n return helper ? { imp, helper } : undefined;\n }\n async function recordVariable(decl: ts.VariableDeclaration): Promise<void> {\n if (!ts.isIdentifier(decl.name) || !decl.initializer) return;\n const call = unwrapCall(decl.initializer);\n if (!call) return;\n const direct = connectFactFromCall(call);\n if (direct)\n out.push({\n variableName: decl.name.text,\n ...direct,\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(sourceFileAst, decl),\n });\n else if (ts.isIdentifier(call.expression)) {\n const resolved = await importedHelper(call.expression.text);\n if (resolved)\n out.push({\n variableName: decl.name.text,\n alias: resolved.helper.alias,\n aliasExpr: resolved.helper.aliasExpr,\n destinationExpr: resolved.helper.destinationExpr,\n servicePathExpr: resolved.helper.servicePathExpr,\n isDynamic: resolved.helper.isDynamic,\n placeholders: resolved.helper.placeholders,\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(sourceFileAst, decl),\n helperChain: [\n {\n callerVariable: decl.name.text,\n importedHelper: call.expression.text,\n importSource: resolved.imp.sourceFile,\n exportedSymbol: resolved.imp.exportedName,\n helperSourceFile: resolved.helper.sourceFile,\n helperSourceLine: resolved.helper.sourceLine,\n },\n ],\n });\n }\n }\n function recordDestructuredClassHelper(decl: ts.VariableDeclaration): void {\n if (!ts.isObjectBindingPattern(decl.name) || !decl.initializer) return;\n const call = unwrapCall(decl.initializer);\n if (!call || !ts.isPropertyAccessExpression(call.expression)) return;\n const target = call.expression;\n if (target.expression.kind !== ts.SyntaxKind.ThisKeyword) return;\n for (const el of decl.name.elements) {\n if (!ts.isIdentifier(el.name)) continue;\n const propertyName = el.propertyName && ts.isIdentifier(el.propertyName)\n ? el.propertyName.text\n : el.name.text;\n const helper = classHelpers.find(\n (h) => h.helperName === target.name.text && h.propertyName === propertyName,\n );\n if (!helper) continue;\n out.push({\n variableName: el.name.text,\n ...helper.fact,\n sourceFile: normalizePath(filePath),\n sourceLine: lineOf(sourceFileAst, decl),\n helperChain: [\n {\n callerVariable: el.name.text,\n className: helper.className,\n classHelper: helper.helperName,\n returnedProperty: helper.propertyName,\n helperVariable: helper.variableName,\n helperSourceFile: normalizePath(filePath),\n helperSourceLine: helper.sourceLine,\n },\n ],\n });\n }\n }\n const declarations: ts.VariableDeclaration[] = [];\n function collectDeclarations(node: ts.Node): void {\n if (ts.isVariableDeclaration(node)) declarations.push(node);\n ts.forEachChild(node, collectDeclarations);\n }\n collectDeclarations(sourceFileAst);\n for (const decl of declarations) {\n recordDestructuredClassHelper(decl);\n await recordVariable(decl);\n }\n return out;\n}\n\nfunction collectClassHelpers(sf: ts.SourceFile): ClassHelperReturn[] {\n const helpers: ClassHelperReturn[] = [];\n for (const stmt of sf.statements) {\n if (!ts.isClassDeclaration(stmt) || !stmt.name) continue;\n for (const member of stmt.members) {\n if (!ts.isPropertyDeclaration(member) || !member.initializer) continue;\n if (!ts.isIdentifier(member.name)) continue;\n const className = stmt.name.text;\n const helperName = member.name.text;\n const initializer = member.initializer;\n if (!ts.isArrowFunction(initializer) && !ts.isFunctionExpression(initializer))\n continue;\n const bindings = new Map<\n string,\n Omit<HelperBinding, 'exportedName' | 'sourceFile' | 'sourceLine'>\n >();\n function visit(node: ts.Node): void {\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {\n const fact = findConnectInExpression(node.initializer);\n if (fact) bindings.set(node.name.text, fact);\n }\n if (ts.isReturnStatement(node) && node.expression && ts.isObjectLiteralExpression(node.expression)) {\n for (const prop of node.expression.properties) {\n if (ts.isShorthandPropertyAssignment(prop)) {\n const fact = bindings.get(prop.name.text);\n if (fact)\n helpers.push({\n className,\n helperName,\n propertyName: prop.name.text,\n variableName: prop.name.text,\n fact,\n sourceLine: lineOf(sf, prop),\n });\n }\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.initializer)) {\n const propertyName =\n ts.isIdentifier(prop.name) || ts.isStringLiteralLike(prop.name)\n ? prop.name.text\n : undefined;\n const fact = propertyName ? bindings.get(prop.initializer.text) : undefined;\n if (propertyName && fact)\n helpers.push({\n className,\n helperName,\n propertyName,\n variableName: prop.initializer.text,\n fact,\n sourceLine: lineOf(sf, prop),\n });\n }\n }\n }\n ts.forEachChild(node, visit);\n }\n visit(initializer);\n }\n }\n return helpers;\n}\n","export function applyVariables(\n template: string | undefined,\n vars: Record<string, string>\n): string | undefined {\n if (!template) return undefined;\n return template.replace(\n /\\$\\{\\s*(\\w+)\\s*\\}/g,\n (_m, key: string) => vars[key] ?? `\\${${key}}`\n );\n}\nexport function extractPlaceholders(template: string | undefined): string[] {\n return [...(template ?? '').matchAll(/\\$\\{\\s*(\\w+)\\s*\\}/g)]\n .map((m) => m[1] ?? '')\n .filter(Boolean);\n}\n","import type { Db } from '../db/connection.js';\nexport interface OperationTarget {\n operationId: number;\n repoName: string;\n servicePath: string;\n operationPath: string;\n operationName: string;\n sourceFile: string;\n sourceLine: number;\n score: number;\n reasons: string[];\n}\nexport interface OperationResolution {\n status: 'resolved' | 'ambiguous' | 'unresolved' | 'dynamic';\n target?: OperationTarget;\n candidates: OperationTarget[];\n reasons: string[];\n}\nfunction rows(\n db: Db,\n operationPath: string,\n workspaceId?: number,\n): OperationTarget[] {\n return db\n .prepare(\n `SELECT o.id operationId,r.name repoName,s.service_path servicePath,o.operation_path operationPath,o.operation_name operationName,o.source_file sourceFile,o.source_line sourceLine,0 score,'' reasons\n FROM cds_operations o JOIN cds_services s ON s.id=o.service_id JOIN repositories r ON r.id=s.repo_id\n WHERE (? IS NULL OR r.workspace_id=?) AND (o.operation_path=? OR o.operation_name=?) ORDER BY r.name,s.service_path,o.operation_name`,\n )\n .all(\n workspaceId,\n workspaceId,\n operationPath,\n operationPath.replace(/^\\//, ''),\n ) as unknown as OperationTarget[];\n}\nexport function resolveOperation(\n db: Db,\n signals: {\n servicePath?: string;\n alias?: string;\n destination?: string;\n operationPath?: string;\n hasExplicitOverride?: boolean;\n isDynamic?: boolean;\n },\n workspaceId?: number,\n): OperationResolution {\n if (!signals.operationPath)\n return {\n status: 'unresolved',\n candidates: [],\n reasons: ['missing_operation_path'],\n };\n const candidates = rows(db, signals.operationPath, workspaceId).map((c) => ({\n ...c,\n score: 0.2,\n reasons: ['operation_path_match'],\n }));\n if (candidates.length === 0)\n return {\n status: 'unresolved',\n candidates: [],\n reasons: ['no_operation_candidates'],\n };\n const hasStrongSignal = Boolean(\n signals.servicePath ||\n signals.alias ||\n signals.destination ||\n signals.hasExplicitOverride,\n );\n for (const c of candidates) {\n if (signals.servicePath && c.servicePath === signals.servicePath) {\n c.score += 0.75;\n c.reasons.push('exact_service_path');\n }\n if (signals.servicePath && c.servicePath !== signals.servicePath) {\n c.score -= 0.1;\n c.reasons.push('service_path_mismatch');\n }\n if (signals.hasExplicitOverride) {\n c.score += 0.2;\n c.reasons.push('explicit_dynamic_override');\n }\n }\n candidates.sort(\n (a, b) => b.score - a.score || a.repoName.localeCompare(b.repoName),\n );\n const best = candidates[0];\n const second = candidates[1];\n if (signals.isDynamic && !signals.hasExplicitOverride && !signals.servicePath)\n return {\n status: 'dynamic',\n candidates,\n reasons: ['dynamic_target_without_override'],\n };\n if (!hasStrongSignal)\n return {\n status: candidates.length > 1 ? 'ambiguous' : 'unresolved',\n candidates,\n reasons: ['operation_path_only_has_no_strong_target_signal'],\n };\n if (\n best &&\n best.score >= 0.9 &&\n (!second || best.score - second.score >= 0.25)\n )\n return {\n status: 'resolved',\n target: best,\n candidates,\n reasons: best.reasons,\n };\n return {\n status: candidates.length > 1 ? 'ambiguous' : 'unresolved',\n candidates,\n reasons: ['candidate_score_below_resolution_threshold'],\n };\n}\nexport function findOperation(\n db: Db,\n servicePath: string | undefined,\n operationPath: string | undefined,\n workspaceId?: number,\n): OperationTarget | undefined {\n return resolveOperation(db, { servicePath, operationPath }, workspaceId)\n .target;\n}\n","import type { Db } from '../db/connection.js';\nexport function linkHelperPackages(db: Db, workspaceId: number): number {\n const repos = db\n .prepare(\n 'SELECT id,name,dependencies_json FROM repositories WHERE workspace_id=?'\n )\n .all(workspaceId) as Array<{\n id: number;\n name: string;\n dependencies_json: string;\n }>;\n let count = 0;\n for (const repo of repos) {\n const deps = JSON.parse(repo.dependencies_json) as Record<string, string>;\n for (const dep of Object.keys(deps)) {\n const helper = repos.find((r) => r.name === dep || dep.endsWith(r.name));\n if (helper) {\n db.prepare(\n 'INSERT INTO graph_edges(workspace_id,edge_type,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic) VALUES(?,?,?,?,?,?,?,?,?)'\n ).run(\n workspaceId,\n 'REPO_IMPORTS_HELPER_PACKAGE',\n 'repo',\n String(repo.id),\n 'repo',\n String(helper.id),\n 0.9,\n JSON.stringify({ dependency: dep }),\n 0\n );\n count += 1;\n }\n }\n }\n return count;\n}\n","import type { Db } from '../db/connection.js';\nimport { applyVariables } from './dynamic-edge-resolver.js';\nimport { resolveOperation } from './service-resolver.js';\nimport { linkHelperPackages } from './helper-package-linker.js';\nexport function linkWorkspace(\n db: Db,\n workspaceId: number,\n vars: Record<string, string> = {},\n): { edgeCount: number; unresolvedCount: number } {\n db.prepare('DELETE FROM graph_edges WHERE workspace_id=?').run(workspaceId);\n let edges = linkHelperPackages(db, workspaceId);\n let unresolved = 0;\n const calls = db\n .prepare(\n `SELECT c.*,r.name repoName,b.alias,b.alias_expr aliasExpr,b.destination_expr destinationExpr,b.service_path_expr servicePathExpr,b.is_dynamic isDynamic,b.placeholders_json placeholdersJson,b.helper_chain_json helperChainJson,req.service_path requireServicePath,req.destination requireDestination FROM outbound_calls c JOIN repositories r ON r.id=c.repo_id LEFT JOIN service_bindings b ON b.id=c.service_binding_id LEFT JOIN cds_requires req ON req.repo_id=c.repo_id AND req.alias=b.alias WHERE r.workspace_id=?`,\n )\n .all(workspaceId) as Array<Record<string, unknown>>;\n for (const call of calls) {\n const callType = String(call.call_type);\n const op = applyVariables(String(call.operation_path_expr ?? ''), vars);\n const servicePath = applyVariables(\n (call.servicePathExpr as string | undefined) ??\n (call.requireServicePath as string | undefined),\n vars,\n );\n const destination =\n (call.destinationExpr as string | undefined) ??\n (call.requireDestination as string | undefined);\n const isDynamic = Boolean(Number(call.isDynamic ?? 0));\n const resolution = callType.startsWith('remote')\n ? resolveOperation(\n db,\n {\n servicePath,\n operationPath: op,\n alias: call.alias as string | undefined,\n destination,\n isDynamic,\n hasExplicitOverride: Object.keys(vars).length > 0,\n },\n workspaceId,\n )\n : { status: 'unresolved' as const, candidates: [], reasons: [] };\n const target = resolution.target;\n const evidence = {\n sourceFile: call.source_file,\n sourceLine: call.source_line,\n file: call.source_file,\n line: call.source_line,\n repo: call.repoName,\n serviceAlias: call.alias,\n serviceAliasExpr: call.aliasExpr,\n destination,\n servicePath,\n operationPath: op,\n targetRepo: target?.repoName,\n targetOperation: target?.operationName,\n helperChain: call.helperChainJson\n ? (JSON.parse(String(call.helperChainJson)) as unknown)\n : undefined,\n candidates: resolution.candidates,\n candidateCount: resolution.candidates.length,\n resolutionStatus: resolution.status,\n resolutionReasons: resolution.reasons,\n };\n if (target) {\n db.prepare(\n 'INSERT INTO graph_edges(workspace_id,edge_type,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic) VALUES(?,?,?,?,?,?,?,?,?)',\n ).run(\n workspaceId,\n 'REMOTE_CALL_RESOLVES_TO_OPERATION',\n 'call',\n String(call.id),\n 'operation',\n String(target.operationId),\n target.score,\n JSON.stringify(evidence),\n isDynamic ? 1 : 0,\n );\n edges += 1;\n } else {\n const edgeType =\n callType === 'local_db_query'\n ? 'HANDLER_RUNS_DB_QUERY'\n : callType === 'external_http'\n ? 'HANDLER_CALLS_EXTERNAL_HTTP'\n : callType === 'async_emit'\n ? 'HANDLER_EMITS_EVENT'\n : callType === 'async_subscribe'\n ? 'EVENT_CONSUMED_BY_HANDLER'\n : resolution.status === 'dynamic'\n ? 'DYNAMIC_EDGE_CANDIDATE'\n : 'UNRESOLVED_EDGE';\n db.prepare(\n 'INSERT INTO graph_edges(workspace_id,edge_type,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,unresolved_reason) VALUES(?,?,?,?,?,?,?,?,?,?)',\n ).run(\n workspaceId,\n edgeType,\n 'call',\n String(call.id),\n callType.startsWith('async_') ? 'event' : 'external',\n String(call.event_name_expr ?? call.query_entity ?? op ?? call.id),\n Number(call.confidence ?? 0.2),\n JSON.stringify(evidence),\n isDynamic || resolution.status === 'dynamic' ? 1 : 0,\n String(\n call.unresolved_reason ??\n (resolution.status === 'ambiguous'\n ? 'Ambiguous operation candidates require a strong service signal'\n : resolution.status === 'dynamic'\n ? 'Dynamic target requires runtime variable overrides'\n : 'No indexed target operation matched'),\n ),\n );\n edges += 1;\n unresolved += edgeType === 'UNRESOLVED_EDGE' ? 1 : 0;\n }\n }\n return { edgeCount: edges, unresolvedCount: unresolved };\n}\n","import type { Db } from '../db/connection.js';\nimport { applyVariables } from '../linker/dynamic-edge-resolver.js';\nimport type { TraceEdge, TraceResult, TraceStart } from '../types.js';\n\ninterface RepoRef {\n id: number;\n name: string;\n}\ninterface StartScope {\n repo?: RepoRef;\n sourceFiles?: Set<string>;\n selectorMatched: boolean;\n}\ninterface CallRow extends Record<string, unknown> {\n id: number;\n repo_id: number;\n repoName: string;\n source_file: string;\n source_line: number;\n call_type: string;\n confidence: number;\n}\ninterface GraphRow extends Record<string, unknown> {\n id: number;\n edge_type: string;\n from_id: string;\n to_kind: string;\n to_id: string;\n confidence: number;\n evidence_json: string;\n unresolved_reason?: string;\n}\ninterface Candidate {\n servicePath?: string;\n operationPath?: string;\n repoName?: string;\n operationName?: string;\n score?: number;\n}\n\nfunction normalizeOperation(value: string | undefined): string | undefined {\n if (!value) return undefined;\n return value.startsWith('/') ? value.slice(1) : value;\n}\nfunction positiveDepth(value: number): number {\n return Number.isFinite(value) && value > 0 ? Math.floor(value) : 25;\n}\nfunction sourceFilesForStart(\n db: Db,\n repoId: number | undefined,\n start: TraceStart,\n): Set<string> | undefined {\n const handler = start.handler;\n const operation = normalizeOperation(start.operation ?? start.operationPath);\n if (!handler && !operation) return undefined;\n const rows = db\n .prepare(\n `SELECT DISTINCT hc.source_file sourceFile\n FROM handler_classes hc LEFT JOIN handler_methods hm ON hm.handler_class_id=hc.id\n WHERE (? IS NULL OR hc.repo_id=?) AND (? IS NULL OR hc.class_name=? OR hm.method_name=?)\n AND (? IS NULL OR hm.decorator_value=? OR hm.method_name=?)`,\n )\n .all(\n repoId,\n repoId,\n handler,\n handler,\n handler,\n operation,\n operation,\n operation,\n ) as Array<{ sourceFile?: string }>;\n if (rows.length === 0) return undefined;\n return new Set(rows.map((row) => row.sourceFile).filter(Boolean) as string[]);\n}\nfunction startScope(db: Db, start: TraceStart): StartScope {\n const repo = start.repo\n ? (db\n .prepare(\n 'SELECT id,name FROM repositories WHERE name=? OR package_name=?',\n )\n .get(start.repo, start.repo) as RepoRef | undefined)\n : undefined;\n if (start.repo && !repo) return { repo, selectorMatched: false };\n const sourceFiles = sourceFilesForStart(db, repo?.id, start);\n const hasSelector = Boolean(\n start.handler ?? start.operation ?? start.operationPath,\n );\n return {\n repo,\n sourceFiles,\n selectorMatched: !hasSelector || sourceFiles !== undefined,\n };\n}\nfunction handlerFilesForOperation(db: Db, operationId: string): Set<string> {\n const op = db\n .prepare(\n `SELECT o.operation_name operationName,o.operation_path operationPath,s.repo_id repoId\n FROM cds_operations o JOIN cds_services s ON s.id=o.service_id WHERE o.id=?`,\n )\n .get(operationId) as\n | { operationName?: string; operationPath?: string; repoId?: number }\n | undefined;\n if (!op) return new Set();\n const operation = normalizeOperation(op.operationPath ?? op.operationName);\n const rows = db\n .prepare(\n `SELECT DISTINCT hc.source_file sourceFile FROM handler_classes hc\n JOIN handler_methods hm ON hm.handler_class_id=hc.id\n WHERE hc.repo_id=? AND (hm.decorator_value=? OR hm.method_name=? OR hm.decorator_value=?)`,\n )\n .all(op.repoId, operation, operation, op.operationName) as Array<{\n sourceFile?: string;\n }>;\n return new Set(rows.map((row) => row.sourceFile).filter(Boolean) as string[]);\n}\nfunction includeCall(\n type: string,\n options: {\n includeExternal?: boolean;\n includeDb?: boolean;\n includeAsync?: boolean;\n },\n): boolean {\n if (!options.includeDb && type === 'local_db_query') return false;\n if (!options.includeExternal && type === 'external_http') return false;\n if (!options.includeAsync && type.startsWith('async_')) return false;\n return true;\n}\nfunction graphForCalls(db: Db, callIds: number[]): Map<number, GraphRow[]> {\n const map = new Map<number, GraphRow[]>();\n if (callIds.length === 0) return map;\n const rows = db\n .prepare(\n `SELECT * FROM graph_edges WHERE from_kind='call' AND from_id IN (${callIds.map(() => '?').join(',')}) ORDER BY id`,\n )\n .all(...callIds) as GraphRow[];\n for (const row of rows) {\n const id = Number(row.from_id);\n map.set(id, [...(map.get(id) ?? []), row]);\n }\n return map;\n}\nfunction candidatesFromEvidence(\n evidence: Record<string, unknown>,\n): Candidate[] {\n return Array.isArray(evidence.candidates)\n ? evidence.candidates.filter(\n (candidate): candidate is Candidate =>\n typeof candidate === 'object' && candidate !== null,\n )\n : [];\n}\nfunction evidenceWithRuntimeVariables(\n evidence: Record<string, unknown>,\n vars: Record<string, string> | undefined,\n): Record<string, unknown> {\n if (!vars || Object.keys(vars).length === 0) return evidence;\n const servicePath =\n typeof evidence.servicePath === 'string'\n ? applyVariables(evidence.servicePath, vars)\n : undefined;\n const operationPath =\n typeof evidence.operationPath === 'string'\n ? applyVariables(evidence.operationPath, vars)\n : undefined;\n const candidates = candidatesFromEvidence(evidence);\n const matched = servicePath\n ? candidates.find((candidate) => candidate.servicePath === servicePath)\n : undefined;\n return {\n ...evidence,\n servicePath: servicePath ?? evidence.servicePath,\n operationPath: operationPath ?? evidence.operationPath,\n runtimeVariablesApplied: true,\n runtimeResolvedCandidate: matched\n ? {\n repoName: matched.repoName,\n servicePath: matched.servicePath,\n operationPath: matched.operationPath,\n operationName: matched.operationName,\n score: matched.score,\n }\n : undefined,\n };\n}\nfunction edgeTarget(row: GraphRow, evidence: Record<string, unknown>): string {\n const runtimeCandidate = evidence.runtimeResolvedCandidate as\n | Candidate\n | undefined;\n if (runtimeCandidate?.servicePath && runtimeCandidate.operationPath)\n return `${runtimeCandidate.servicePath}${runtimeCandidate.operationPath}`;\n const servicePath =\n typeof evidence.servicePath === 'string' ? evidence.servicePath : undefined;\n const operationPath =\n typeof evidence.operationPath === 'string'\n ? evidence.operationPath\n : undefined;\n const targetOperation =\n typeof evidence.targetOperation === 'string'\n ? evidence.targetOperation\n : undefined;\n const targetRepo =\n typeof evidence.targetRepo === 'string' ? evidence.targetRepo : '';\n return servicePath && operationPath\n ? `${servicePath}${operationPath}`\n : targetOperation\n ? `${targetRepo}:${targetOperation}`\n : row.to_id;\n}\nexport function trace(\n db: Db,\n start: TraceStart,\n options: {\n depth: number;\n vars?: Record<string, string>;\n includeExternal?: boolean;\n includeDb?: boolean;\n includeAsync?: boolean;\n },\n): TraceResult {\n const scope = startScope(db, start);\n const diagnostics = db\n .prepare(\n 'SELECT severity,code,message,source_file sourceFile,source_line sourceLine FROM diagnostics WHERE (? IS NULL OR repo_id=?)',\n )\n .all(scope.repo?.id, scope.repo?.id) as Array<Record<string, unknown>>;\n if (!scope.selectorMatched)\n diagnostics.unshift({\n severity: 'warning',\n code: 'trace_start_not_found',\n message: 'No handler source matched the requested trace start selector',\n });\n const maxDepth = positiveDepth(options.depth);\n const edges: TraceEdge[] = [];\n const nodes = new Map<string, Record<string, unknown>>();\n const queue: Array<{ repoId?: number; files?: Set<string>; depth: number }> =\n scope.selectorMatched\n ? [{ repoId: scope.repo?.id, files: scope.sourceFiles, depth: 1 }]\n : [];\n const seenScopes = new Set<string>();\n const seenEdges = new Set<number>();\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current || current.depth > maxDepth) continue;\n const key = `${current.repoId ?? '*'}:${[...(current.files ?? new Set(['*']))].sort().join(',')}`;\n if (seenScopes.has(key)) continue;\n seenScopes.add(key);\n const calls = db\n .prepare(\n `SELECT c.*,r.name repoName FROM outbound_calls c JOIN repositories r ON r.id=c.repo_id WHERE (? IS NULL OR c.repo_id=?) ORDER BY c.source_file,c.source_line`,\n )\n .all(current.repoId, current.repoId) as CallRow[];\n const filtered = calls.filter(\n (c) =>\n (!current.files || current.files.has(String(c.source_file))) &&\n includeCall(String(c.call_type), options),\n );\n const graph = graphForCalls(\n db,\n filtered.map((c) => Number(c.id)),\n );\n for (const call of filtered) {\n const callNode = `call:${call.id}`;\n nodes.set(callNode, {\n id: callNode,\n kind: 'outbound_call',\n repo: call.repoName,\n file: call.source_file,\n line: call.source_line,\n callType: call.call_type,\n });\n const graphRows = graph.get(Number(call.id)) ?? [];\n for (const row of graphRows) {\n if (seenEdges.has(Number(row.id))) continue;\n seenEdges.add(Number(row.id));\n const rawEvidence = JSON.parse(\n String(row.evidence_json || '{}'),\n ) as Record<string, unknown>;\n const evidence = evidenceWithRuntimeVariables(\n rawEvidence,\n options.vars,\n );\n const targetNode = `${row.to_kind}:${row.to_id}`;\n nodes.set(targetNode, {\n id: targetNode,\n kind: row.to_kind,\n label: row.to_id,\n ...evidence,\n });\n const to = edgeTarget(row, evidence);\n edges.push({\n step: current.depth,\n type: String(call.call_type),\n from: `${call.repoName}:${call.source_file}`,\n to,\n evidence,\n confidence: Number(row.confidence ?? call.confidence),\n unresolvedReason: row.unresolved_reason,\n });\n if (row.to_kind === 'operation' && current.depth < maxDepth) {\n const files = handlerFilesForOperation(db, row.to_id);\n if (files.size > 0) {\n const targetRepoId = db\n .prepare(\n 'SELECT s.repo_id repoId FROM cds_operations o JOIN cds_services s ON s.id=o.service_id WHERE o.id=?',\n )\n .get(row.to_id)?.repoId as number | undefined;\n const nextKey = `${targetRepoId ?? '*'}:${[...files].sort().join(',')}`;\n if (seenScopes.has(nextKey))\n edges.push({\n step: current.depth + 1,\n type: 'cycle',\n from: to,\n to: nextKey,\n evidence: { ...evidence, cycle: true },\n confidence: 1,\n unresolvedReason:\n 'Cycle detected; downstream scope already visited',\n });\n else\n queue.push({\n repoId: targetRepoId,\n files,\n depth: current.depth + 1,\n });\n }\n }\n }\n }\n }\n return { start, nodes: [...nodes.values()], edges, diagnostics };\n}\n"],"mappings":"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","names":["path","path","fs","path","fs","path","path","fs","fs","path","ts","ts","fs","path","fs","path","lineOf","fs","path","fs","path","lineOf","firstArg","fs","path","fs","path","ts","lineOf","ts","fs","path","visit","rows"]}