@ryanstark24/sfgraph-server 1.1.0

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 (261) hide show
  1. package/dist/__tests__/context-cache.test.d.ts +2 -0
  2. package/dist/__tests__/context-cache.test.d.ts.map +1 -0
  3. package/dist/__tests__/context-cache.test.js +77 -0
  4. package/dist/__tests__/context-cache.test.js.map +1 -0
  5. package/dist/__tests__/context-default-factory.test.d.ts +2 -0
  6. package/dist/__tests__/context-default-factory.test.d.ts.map +1 -0
  7. package/dist/__tests__/context-default-factory.test.js +89 -0
  8. package/dist/__tests__/context-default-factory.test.js.map +1 -0
  9. package/dist/__tests__/network-egress.test.d.ts +2 -0
  10. package/dist/__tests__/network-egress.test.d.ts.map +1 -0
  11. package/dist/__tests__/network-egress.test.js +33 -0
  12. package/dist/__tests__/network-egress.test.js.map +1 -0
  13. package/dist/__tests__/shutdown.test.d.ts +2 -0
  14. package/dist/__tests__/shutdown.test.d.ts.map +1 -0
  15. package/dist/__tests__/shutdown.test.js +78 -0
  16. package/dist/__tests__/shutdown.test.js.map +1 -0
  17. package/dist/__tests__/tool-registry.test.d.ts +2 -0
  18. package/dist/__tests__/tool-registry.test.d.ts.map +1 -0
  19. package/dist/__tests__/tool-registry.test.js +21 -0
  20. package/dist/__tests__/tool-registry.test.js.map +1 -0
  21. package/dist/__tests__/zod-schema.test.d.ts +2 -0
  22. package/dist/__tests__/zod-schema.test.d.ts.map +1 -0
  23. package/dist/__tests__/zod-schema.test.js +15 -0
  24. package/dist/__tests__/zod-schema.test.js.map +1 -0
  25. package/dist/bin.d.ts +2 -0
  26. package/dist/bin.d.ts.map +1 -0
  27. package/dist/bin.js +14 -0
  28. package/dist/bin.js.map +1 -0
  29. package/dist/context.d.ts +29 -0
  30. package/dist/context.d.ts.map +1 -0
  31. package/dist/context.js +202 -0
  32. package/dist/context.js.map +1 -0
  33. package/dist/index.d.ts +8 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +6 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/server.d.ts +31 -0
  38. package/dist/server.d.ts.map +1 -0
  39. package/dist/server.js +91 -0
  40. package/dist/server.js.map +1 -0
  41. package/dist/shutdown.d.ts +10 -0
  42. package/dist/shutdown.d.ts.map +1 -0
  43. package/dist/shutdown.js +43 -0
  44. package/dist/shutdown.js.map +1 -0
  45. package/dist/tool-registry.d.ts +31 -0
  46. package/dist/tool-registry.d.ts.map +1 -0
  47. package/dist/tool-registry.js +29 -0
  48. package/dist/tool-registry.js.map +1 -0
  49. package/dist/tools/__tests__/_fixture.d.ts +29 -0
  50. package/dist/tools/__tests__/_fixture.d.ts.map +1 -0
  51. package/dist/tools/__tests__/_fixture.js +59 -0
  52. package/dist/tools/__tests__/_fixture.js.map +1 -0
  53. package/dist/tools/__tests__/_runner.d.ts +10 -0
  54. package/dist/tools/__tests__/_runner.d.ts.map +1 -0
  55. package/dist/tools/__tests__/_runner.js +12 -0
  56. package/dist/tools/__tests__/_runner.js.map +1 -0
  57. package/dist/tools/__tests__/analyze_field.test.d.ts +2 -0
  58. package/dist/tools/__tests__/analyze_field.test.d.ts.map +1 -0
  59. package/dist/tools/__tests__/analyze_field.test.js +92 -0
  60. package/dist/tools/__tests__/analyze_field.test.js.map +1 -0
  61. package/dist/tools/__tests__/cross_layer_flow_map.test.d.ts +2 -0
  62. package/dist/tools/__tests__/cross_layer_flow_map.test.d.ts.map +1 -0
  63. package/dist/tools/__tests__/cross_layer_flow_map.test.js +111 -0
  64. package/dist/tools/__tests__/cross_layer_flow_map.test.js.map +1 -0
  65. package/dist/tools/__tests__/cross_org_diff.test.d.ts +2 -0
  66. package/dist/tools/__tests__/cross_org_diff.test.d.ts.map +1 -0
  67. package/dist/tools/__tests__/cross_org_diff.test.js +112 -0
  68. package/dist/tools/__tests__/cross_org_diff.test.js.map +1 -0
  69. package/dist/tools/__tests__/dead_code_audit.test.d.ts +2 -0
  70. package/dist/tools/__tests__/dead_code_audit.test.d.ts.map +1 -0
  71. package/dist/tools/__tests__/dead_code_audit.test.js +71 -0
  72. package/dist/tools/__tests__/dead_code_audit.test.js.map +1 -0
  73. package/dist/tools/__tests__/deployment_manifest_gen.test.d.ts +2 -0
  74. package/dist/tools/__tests__/deployment_manifest_gen.test.d.ts.map +1 -0
  75. package/dist/tools/__tests__/deployment_manifest_gen.test.js +143 -0
  76. package/dist/tools/__tests__/deployment_manifest_gen.test.js.map +1 -0
  77. package/dist/tools/__tests__/dispatcher.test.d.ts +2 -0
  78. package/dist/tools/__tests__/dispatcher.test.d.ts.map +1 -0
  79. package/dist/tools/__tests__/dispatcher.test.js +39 -0
  80. package/dist/tools/__tests__/dispatcher.test.js.map +1 -0
  81. package/dist/tools/__tests__/explain_code.test.d.ts +2 -0
  82. package/dist/tools/__tests__/explain_code.test.d.ts.map +1 -0
  83. package/dist/tools/__tests__/explain_code.test.js +88 -0
  84. package/dist/tools/__tests__/explain_code.test.js.map +1 -0
  85. package/dist/tools/__tests__/freshness_report.test.d.ts +2 -0
  86. package/dist/tools/__tests__/freshness_report.test.d.ts.map +1 -0
  87. package/dist/tools/__tests__/freshness_report.test.js +103 -0
  88. package/dist/tools/__tests__/freshness_report.test.js.map +1 -0
  89. package/dist/tools/__tests__/get_ingest_job.test.d.ts +2 -0
  90. package/dist/tools/__tests__/get_ingest_job.test.d.ts.map +1 -0
  91. package/dist/tools/__tests__/get_ingest_job.test.js +42 -0
  92. package/dist/tools/__tests__/get_ingest_job.test.js.map +1 -0
  93. package/dist/tools/__tests__/governor_risk_check.test.d.ts +2 -0
  94. package/dist/tools/__tests__/governor_risk_check.test.d.ts.map +1 -0
  95. package/dist/tools/__tests__/governor_risk_check.test.js +66 -0
  96. package/dist/tools/__tests__/governor_risk_check.test.js.map +1 -0
  97. package/dist/tools/__tests__/impact_from_git_diff.test.d.ts +2 -0
  98. package/dist/tools/__tests__/impact_from_git_diff.test.d.ts.map +1 -0
  99. package/dist/tools/__tests__/impact_from_git_diff.test.js +115 -0
  100. package/dist/tools/__tests__/impact_from_git_diff.test.js.map +1 -0
  101. package/dist/tools/__tests__/list_orgs.test.d.ts +2 -0
  102. package/dist/tools/__tests__/list_orgs.test.d.ts.map +1 -0
  103. package/dist/tools/__tests__/list_orgs.test.js +137 -0
  104. package/dist/tools/__tests__/list_orgs.test.js.map +1 -0
  105. package/dist/tools/__tests__/ping.test.d.ts +2 -0
  106. package/dist/tools/__tests__/ping.test.d.ts.map +1 -0
  107. package/dist/tools/__tests__/ping.test.js +10 -0
  108. package/dist/tools/__tests__/ping.test.js.map +1 -0
  109. package/dist/tools/__tests__/point_in_time_diff.test.d.ts +2 -0
  110. package/dist/tools/__tests__/point_in_time_diff.test.d.ts.map +1 -0
  111. package/dist/tools/__tests__/point_in_time_diff.test.js +64 -0
  112. package/dist/tools/__tests__/point_in_time_diff.test.js.map +1 -0
  113. package/dist/tools/__tests__/security_audit.test.d.ts +2 -0
  114. package/dist/tools/__tests__/security_audit.test.d.ts.map +1 -0
  115. package/dist/tools/__tests__/security_audit.test.js +99 -0
  116. package/dist/tools/__tests__/security_audit.test.js.map +1 -0
  117. package/dist/tools/__tests__/snapshot.test.d.ts +2 -0
  118. package/dist/tools/__tests__/snapshot.test.d.ts.map +1 -0
  119. package/dist/tools/__tests__/snapshot.test.js +54 -0
  120. package/dist/tools/__tests__/snapshot.test.js.map +1 -0
  121. package/dist/tools/__tests__/staleness_check.test.d.ts +2 -0
  122. package/dist/tools/__tests__/staleness_check.test.d.ts.map +1 -0
  123. package/dist/tools/__tests__/staleness_check.test.js +51 -0
  124. package/dist/tools/__tests__/staleness_check.test.js.map +1 -0
  125. package/dist/tools/__tests__/start_ingest_job.test.d.ts +2 -0
  126. package/dist/tools/__tests__/start_ingest_job.test.d.ts.map +1 -0
  127. package/dist/tools/__tests__/start_ingest_job.test.js +55 -0
  128. package/dist/tools/__tests__/start_ingest_job.test.js.map +1 -0
  129. package/dist/tools/__tests__/test_gap_intelligence.test.d.ts +2 -0
  130. package/dist/tools/__tests__/test_gap_intelligence.test.d.ts.map +1 -0
  131. package/dist/tools/__tests__/test_gap_intelligence.test.js +77 -0
  132. package/dist/tools/__tests__/test_gap_intelligence.test.js.map +1 -0
  133. package/dist/tools/__tests__/trace.test.d.ts +2 -0
  134. package/dist/tools/__tests__/trace.test.d.ts.map +1 -0
  135. package/dist/tools/__tests__/trace.test.js +130 -0
  136. package/dist/tools/__tests__/trace.test.js.map +1 -0
  137. package/dist/tools/__tests__/what_broke.test.d.ts +2 -0
  138. package/dist/tools/__tests__/what_broke.test.d.ts.map +1 -0
  139. package/dist/tools/__tests__/what_broke.test.js +60 -0
  140. package/dist/tools/__tests__/what_broke.test.js.map +1 -0
  141. package/dist/tools/__tests__/wip.test.d.ts +2 -0
  142. package/dist/tools/__tests__/wip.test.d.ts.map +1 -0
  143. package/dist/tools/__tests__/wip.test.js +173 -0
  144. package/dist/tools/__tests__/wip.test.js.map +1 -0
  145. package/dist/tools/_define.d.ts +11 -0
  146. package/dist/tools/_define.d.ts.map +1 -0
  147. package/dist/tools/_define.js +29 -0
  148. package/dist/tools/_define.js.map +1 -0
  149. package/dist/tools/_job-store.d.ts +19 -0
  150. package/dist/tools/_job-store.d.ts.map +1 -0
  151. package/dist/tools/_job-store.js +26 -0
  152. package/dist/tools/_job-store.js.map +1 -0
  153. package/dist/tools/_project-root.d.ts +20 -0
  154. package/dist/tools/_project-root.d.ts.map +1 -0
  155. package/dist/tools/_project-root.js +44 -0
  156. package/dist/tools/_project-root.js.map +1 -0
  157. package/dist/tools/analyze_field.d.ts +2 -0
  158. package/dist/tools/analyze_field.d.ts.map +1 -0
  159. package/dist/tools/analyze_field.js +77 -0
  160. package/dist/tools/analyze_field.js.map +1 -0
  161. package/dist/tools/cross_layer_flow_map.d.ts +2 -0
  162. package/dist/tools/cross_layer_flow_map.d.ts.map +1 -0
  163. package/dist/tools/cross_layer_flow_map.js +104 -0
  164. package/dist/tools/cross_layer_flow_map.js.map +1 -0
  165. package/dist/tools/cross_org_diff.d.ts +2 -0
  166. package/dist/tools/cross_org_diff.d.ts.map +1 -0
  167. package/dist/tools/cross_org_diff.js +59 -0
  168. package/dist/tools/cross_org_diff.js.map +1 -0
  169. package/dist/tools/dead_code_audit.d.ts +2 -0
  170. package/dist/tools/dead_code_audit.d.ts.map +1 -0
  171. package/dist/tools/dead_code_audit.js +67 -0
  172. package/dist/tools/dead_code_audit.js.map +1 -0
  173. package/dist/tools/deployment_manifest_gen.d.ts +2 -0
  174. package/dist/tools/deployment_manifest_gen.d.ts.map +1 -0
  175. package/dist/tools/deployment_manifest_gen.js +43 -0
  176. package/dist/tools/deployment_manifest_gen.js.map +1 -0
  177. package/dist/tools/explain_code.d.ts +2 -0
  178. package/dist/tools/explain_code.d.ts.map +1 -0
  179. package/dist/tools/explain_code.js +109 -0
  180. package/dist/tools/explain_code.js.map +1 -0
  181. package/dist/tools/freshness_report.d.ts +2 -0
  182. package/dist/tools/freshness_report.d.ts.map +1 -0
  183. package/dist/tools/freshness_report.js +66 -0
  184. package/dist/tools/freshness_report.js.map +1 -0
  185. package/dist/tools/get_ingest_job.d.ts +2 -0
  186. package/dist/tools/get_ingest_job.d.ts.map +1 -0
  187. package/dist/tools/get_ingest_job.js +24 -0
  188. package/dist/tools/get_ingest_job.js.map +1 -0
  189. package/dist/tools/governor_risk_check.d.ts +2 -0
  190. package/dist/tools/governor_risk_check.d.ts.map +1 -0
  191. package/dist/tools/governor_risk_check.js +50 -0
  192. package/dist/tools/governor_risk_check.js.map +1 -0
  193. package/dist/tools/impact_from_git_diff.d.ts +2 -0
  194. package/dist/tools/impact_from_git_diff.d.ts.map +1 -0
  195. package/dist/tools/impact_from_git_diff.js +67 -0
  196. package/dist/tools/impact_from_git_diff.js.map +1 -0
  197. package/dist/tools/index.d.ts +27 -0
  198. package/dist/tools/index.d.ts.map +1 -0
  199. package/dist/tools/index.js +28 -0
  200. package/dist/tools/index.js.map +1 -0
  201. package/dist/tools/list_orgs.d.ts +30 -0
  202. package/dist/tools/list_orgs.d.ts.map +1 -0
  203. package/dist/tools/list_orgs.js +302 -0
  204. package/dist/tools/list_orgs.js.map +1 -0
  205. package/dist/tools/ping.d.ts +3 -0
  206. package/dist/tools/ping.d.ts.map +1 -0
  207. package/dist/tools/ping.js +23 -0
  208. package/dist/tools/ping.js.map +1 -0
  209. package/dist/tools/point_in_time_diff.d.ts +2 -0
  210. package/dist/tools/point_in_time_diff.d.ts.map +1 -0
  211. package/dist/tools/point_in_time_diff.js +37 -0
  212. package/dist/tools/point_in_time_diff.js.map +1 -0
  213. package/dist/tools/security_audit.d.ts +2 -0
  214. package/dist/tools/security_audit.d.ts.map +1 -0
  215. package/dist/tools/security_audit.js +56 -0
  216. package/dist/tools/security_audit.js.map +1 -0
  217. package/dist/tools/snapshot_create.d.ts +2 -0
  218. package/dist/tools/snapshot_create.d.ts.map +1 -0
  219. package/dist/tools/snapshot_create.js +24 -0
  220. package/dist/tools/snapshot_create.js.map +1 -0
  221. package/dist/tools/snapshot_list.d.ts +2 -0
  222. package/dist/tools/snapshot_list.d.ts.map +1 -0
  223. package/dist/tools/snapshot_list.js +22 -0
  224. package/dist/tools/snapshot_list.js.map +1 -0
  225. package/dist/tools/staleness_check.d.ts +2 -0
  226. package/dist/tools/staleness_check.d.ts.map +1 -0
  227. package/dist/tools/staleness_check.js +50 -0
  228. package/dist/tools/staleness_check.js.map +1 -0
  229. package/dist/tools/start_ingest_job.d.ts +2 -0
  230. package/dist/tools/start_ingest_job.d.ts.map +1 -0
  231. package/dist/tools/start_ingest_job.js +83 -0
  232. package/dist/tools/start_ingest_job.js.map +1 -0
  233. package/dist/tools/test_gap_intelligence_from_git_diff.d.ts +2 -0
  234. package/dist/tools/test_gap_intelligence_from_git_diff.d.ts.map +1 -0
  235. package/dist/tools/test_gap_intelligence_from_git_diff.js +50 -0
  236. package/dist/tools/test_gap_intelligence_from_git_diff.js.map +1 -0
  237. package/dist/tools/trace_downstream.d.ts +2 -0
  238. package/dist/tools/trace_downstream.d.ts.map +1 -0
  239. package/dist/tools/trace_downstream.js +43 -0
  240. package/dist/tools/trace_downstream.js.map +1 -0
  241. package/dist/tools/trace_upstream.d.ts +2 -0
  242. package/dist/tools/trace_upstream.d.ts.map +1 -0
  243. package/dist/tools/trace_upstream.js +43 -0
  244. package/dist/tools/trace_upstream.js.map +1 -0
  245. package/dist/tools/what_broke.d.ts +2 -0
  246. package/dist/tools/what_broke.d.ts.map +1 -0
  247. package/dist/tools/what_broke.js +86 -0
  248. package/dist/tools/what_broke.js.map +1 -0
  249. package/dist/tools/wip_diff.d.ts +2 -0
  250. package/dist/tools/wip_diff.d.ts.map +1 -0
  251. package/dist/tools/wip_diff.js +55 -0
  252. package/dist/tools/wip_diff.js.map +1 -0
  253. package/dist/tools/wip_impact.d.ts +2 -0
  254. package/dist/tools/wip_impact.d.ts.map +1 -0
  255. package/dist/tools/wip_impact.js +55 -0
  256. package/dist/tools/wip_impact.js.map +1 -0
  257. package/dist/tools/wip_test_gap.d.ts +2 -0
  258. package/dist/tools/wip_test_gap.d.ts.map +1 -0
  259. package/dist/tools/wip_test_gap.js +50 -0
  260. package/dist/tools/wip_test_gap.js.map +1 -0
  261. package/package.json +61 -0
@@ -0,0 +1,44 @@
1
+ import { existsSync, realpathSync, statSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { ConfigError } from "@ryanstark24/sfgraph-shared";
4
+ /**
5
+ * Resolve and sanity-check a user-supplied `project_root` for the WIP tools.
6
+ *
7
+ * The WIP tools walk the local filesystem under `project_root`. Without a
8
+ * containment check, a malicious or careless caller can point them at `/`,
9
+ * `/etc`, or anywhere the user can read — turning local read-access into
10
+ * an MCP-mediated arbitrary-file read.
11
+ *
12
+ * This helper:
13
+ * 1. Resolves `project_root` to an absolute path via `path.resolve`.
14
+ * 2. Verifies the path exists and is a directory.
15
+ * 3. Requires an `sfdx-project.json` at the root (proof this is a real
16
+ * Salesforce DX project, not `/home/victim`).
17
+ * 4. Returns the `realpath`-resolved root so downstream walkers operate
18
+ * on a stable, symlink-resolved path.
19
+ *
20
+ * Throws `ConfigError` on any failure.
21
+ */
22
+ export function resolveWipProjectRoot(rawProjectRoot) {
23
+ const abs = path.resolve(rawProjectRoot);
24
+ if (!existsSync(abs)) {
25
+ throw new ConfigError(`project_root does not exist: ${rawProjectRoot}`);
26
+ }
27
+ let stats;
28
+ try {
29
+ stats = statSync(abs);
30
+ }
31
+ catch (e) {
32
+ throw new ConfigError(`project_root not readable: ${e.message}`);
33
+ }
34
+ if (!stats.isDirectory()) {
35
+ throw new ConfigError(`project_root is not a directory: ${rawProjectRoot}`);
36
+ }
37
+ const real = realpathSync(abs);
38
+ const sfdxProject = path.join(real, "sfdx-project.json");
39
+ if (!existsSync(sfdxProject)) {
40
+ throw new ConfigError(`project_root is not a Salesforce DX project (no sfdx-project.json at ${real}). WIP tools refuse to walk arbitrary filesystem locations.`);
41
+ }
42
+ return real;
43
+ }
44
+ //# sourceMappingURL=_project-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_project-root.js","sourceRoot":"","sources":["../../src/tools/_project-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,qBAAqB,CAAC,cAAsB;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,WAAW,CAAC,gCAAgC,cAAc,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,KAAkC,CAAC;IACvC,IAAI,CAAC;QACH,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,WAAW,CAAC,8BAA+B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,IAAI,WAAW,CAAC,oCAAoC,cAAc,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,WAAW,CACnB,wEAAwE,IAAI,6DAA6D,CAC1I,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analyze_field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze_field.d.ts","sourceRoot":"","sources":["../../src/tools/analyze_field.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import { render } from "@ryanstark24/sfgraph-core";
2
+ import { REL_TYPES } from "@ryanstark24/sfgraph-core";
3
+ import { asQualifiedName } from "@ryanstark24/sfgraph-shared";
4
+ import { getToolContext } from "../context.js";
5
+ import { defineTool, z } from "./_define.js";
6
+ // Salesforce SObject and Field API names are letters/digits/underscore only
7
+ // (custom suffix `__c` / `__r` / etc. is allowed). Reject anything else
8
+ // up-front rather than silently returning "field not found" — agents that
9
+ // pass `object: "Account.Tier__c"` should see the validation error.
10
+ const SF_API_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*(?:__[a-zA-Z])?$/;
11
+ const inputSchema = z.object({
12
+ org: z.string().min(1),
13
+ object: z
14
+ .string()
15
+ .min(1)
16
+ .regex(SF_API_NAME_RE, "object must be a Salesforce SObject API name (no dots or spaces)"),
17
+ field: z
18
+ .string()
19
+ .min(1)
20
+ .regex(SF_API_NAME_RE, "field must be a Salesforce field API name (no dots or spaces)"),
21
+ });
22
+ defineTool({
23
+ name: "analyze_field",
24
+ description: "USE THIS for any 'where is X.Y field used' / 'who reads or writes Account.Status__c' / 'who has access to this field' question about a Salesforce CustomField. Returns every Apex method, Flow, LWC, validation rule, and formula that reads/writes the field, plus FLS grants (which Profile/PermSet can see or edit it). Prefer this over grep / file search for any field-impact question.",
25
+ inputSchema,
26
+ async execute(input) {
27
+ const ctx = await getToolContext({ orgId: input.org });
28
+ const qname = asQualifiedName(`CustomField:${input.object}.${input.field}`);
29
+ const node = ctx.graphStore.getNode(ctx.orgId, qname);
30
+ if (!node) {
31
+ return {
32
+ summary: "field not found",
33
+ markdown: `> no node \`${qname}\``,
34
+ data: { found: false },
35
+ };
36
+ }
37
+ const readers = ctx.graphStore.listEdgesTo(ctx.orgId, qname, REL_TYPES.READS_FIELD);
38
+ const writers = ctx.graphStore.listEdgesTo(ctx.orgId, qname, REL_TYPES.WRITES_FIELD);
39
+ const grants = ctx.graphStore.listEdgesTo(ctx.orgId, qname, REL_TYPES.GRANTS_FIELD_ACCESS);
40
+ const allEdges = [...readers, ...writers, ...grants];
41
+ const nodeSet = new Map();
42
+ nodeSet.set(qname, { qualifiedName: qname, label: "CustomField" });
43
+ for (const e of allEdges) {
44
+ const src = ctx.graphStore.getNode(ctx.orgId, e.srcQualifiedName);
45
+ nodeSet.set(e.srcQualifiedName, {
46
+ qualifiedName: e.srcQualifiedName,
47
+ label: src?.label ?? "Unknown",
48
+ });
49
+ }
50
+ const mermaid = render.renderDependencyGraph({
51
+ nodes: Array.from(nodeSet.values()),
52
+ edges: allEdges.map((e) => ({
53
+ srcQualifiedName: e.srcQualifiedName,
54
+ dstQualifiedName: e.dstQualifiedName,
55
+ relType: e.relType,
56
+ })),
57
+ title: `field ${qname}`,
58
+ });
59
+ const md = [
60
+ `**${qname}** — readers ${readers.length} · writers ${writers.length} · grants ${grants.length}`,
61
+ "",
62
+ "```mermaid",
63
+ mermaid,
64
+ "```",
65
+ ].join("\n");
66
+ return {
67
+ summary: `${readers.length} readers / ${writers.length} writers`,
68
+ markdown: md,
69
+ data: {
70
+ readers: readers.map((e) => e.srcQualifiedName),
71
+ writers: writers.map((e) => e.srcQualifiedName),
72
+ grants: grants.map((e) => e.srcQualifiedName),
73
+ },
74
+ };
75
+ },
76
+ });
77
+ //# sourceMappingURL=analyze_field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze_field.js","sourceRoot":"","sources":["../../src/tools/analyze_field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAE7C,4EAA4E;AAC5E,wEAAwE;AACxE,0EAA0E;AAC1E,oEAAoE;AACpE,MAAM,cAAc,GAAG,wCAAwC,CAAC;AAEhE,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,KAAK,CAAC,cAAc,EAAE,kEAAkE,CAAC;IAC5F,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,KAAK,CAAC,cAAc,EAAE,+DAA+D,CAAC;CAC1F,CAAC,CAAC;AAEH,UAAU,CAAC;IACT,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,+XAA+X;IACjY,WAAW;IACX,KAAK,CAAC,OAAO,CAAC,KAAK;QACjB,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,eAAe,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,iBAAiB;gBAC1B,QAAQ,EAAE,eAAe,KAAK,IAAI;gBAClC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;aACvB,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QACpF,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;QACrF,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC3F,MAAM,QAAQ,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoD,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QACnE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,EAAE;gBAC9B,aAAa,EAAE,CAAC,CAAC,gBAAgB;gBACjC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,SAAS;aAC/B,CAAC,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,qBAAqB,CAAC;YAC3C,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC;YACH,KAAK,EAAE,SAAS,KAAK,EAAE;SACxB,CAAC,CAAC;QACH,MAAM,EAAE,GAAG;YACT,KAAK,KAAK,gBAAgB,OAAO,CAAC,MAAM,cAAc,OAAO,CAAC,MAAM,aAAa,MAAM,CAAC,MAAM,EAAE;YAChG,EAAE;YACF,YAAY;YACZ,OAAO;YACP,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,OAAO;YACL,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,cAAc,OAAO,CAAC,MAAM,UAAU;YAChE,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE;gBACJ,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;gBAC/C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;gBAC/C,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;aAC9C;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cross_layer_flow_map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross_layer_flow_map.d.ts","sourceRoot":"","sources":["../../src/tools/cross_layer_flow_map.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { render } from "@ryanstark24/sfgraph-core";
2
+ import { REL_TYPES } from "@ryanstark24/sfgraph-core";
3
+ import { asQualifiedName } from "@ryanstark24/sfgraph-shared";
4
+ import { getToolContext } from "../context.js";
5
+ import { defineTool, z } from "./_define.js";
6
+ const inputSchema = z.object({
7
+ org: z.string().min(1),
8
+ entry: z.string().min(1),
9
+ });
10
+ const REL_PRIORITY = [
11
+ REL_TYPES.CALLS_APEX_FROM_LWC,
12
+ REL_TYPES.CALLS,
13
+ REL_TYPES.EXECUTES_SOQL,
14
+ REL_TYPES.READS_FIELD,
15
+ ];
16
+ function layerFor(label) {
17
+ if (label === "LWC" || label === "LightningComponentBundle")
18
+ return "LWC";
19
+ if (label.startsWith("Apex"))
20
+ return "Apex";
21
+ if (label === "CustomField")
22
+ return "Field";
23
+ if (label === "CustomObject")
24
+ return "SOQL";
25
+ return label;
26
+ }
27
+ defineTool({
28
+ name: "cross_layer_flow_map",
29
+ description: "USE THIS for any 'how does X flow from UI to DB' / 'trace this LWC end-to-end' / 'show the full path from accountTile to the database' question about a Salesforce entry point (LWC bundle, ApexPage, Flow). Returns the layered LWC -> Apex -> SOQL -> CustomField sequence + Mermaid sequenceDiagram.",
30
+ inputSchema,
31
+ async execute(input) {
32
+ const ctx = await getToolContext({ orgId: input.org });
33
+ const entry = asQualifiedName(input.entry);
34
+ const participants = new Map();
35
+ const messages = [];
36
+ const visited = new Set();
37
+ const queue = [entry];
38
+ visited.add(entry);
39
+ const entryNode = ctx.graphStore.getNode(ctx.orgId, entry);
40
+ if (entryNode) {
41
+ participants.set(entry, {
42
+ id: entry,
43
+ label: entry,
44
+ layer: layerFor(entryNode.label),
45
+ });
46
+ }
47
+ else {
48
+ participants.set(entry, { id: entry, label: entry, layer: "Entry" });
49
+ }
50
+ // Per-node visit cap, not per-edge step cap. Previously `steps < 50`
51
+ // counted every edge traversed across the BFS, so any moderately-fanned
52
+ // LWC -> Apex chain (30 fields + 25 SOQL reads) would silently truncate
53
+ // mid-tree. Capping visited *nodes* gives predictable depth and lets us
54
+ // emit an explicit "_truncated_" marker the user can act on.
55
+ const NODE_CAP = 100;
56
+ let truncated = false;
57
+ bfs: while (queue.length > 0) {
58
+ if (visited.size >= NODE_CAP) {
59
+ truncated = true;
60
+ break;
61
+ }
62
+ const cur = queue.shift();
63
+ if (!cur)
64
+ break;
65
+ for (const rt of REL_PRIORITY) {
66
+ const out = ctx.graphStore.listEdgesFrom(ctx.orgId, cur, rt);
67
+ for (const e of out) {
68
+ const dstNode = ctx.graphStore.getNode(ctx.orgId, e.dstQualifiedName);
69
+ if (!participants.has(e.dstQualifiedName)) {
70
+ participants.set(e.dstQualifiedName, {
71
+ id: e.dstQualifiedName,
72
+ label: e.dstQualifiedName,
73
+ layer: layerFor(dstNode?.label ?? "Unknown"),
74
+ });
75
+ }
76
+ messages.push({ fromId: cur, toId: e.dstQualifiedName, label: rt });
77
+ if (!visited.has(e.dstQualifiedName)) {
78
+ visited.add(e.dstQualifiedName);
79
+ queue.push(e.dstQualifiedName);
80
+ if (visited.size >= NODE_CAP) {
81
+ truncated = true;
82
+ break bfs;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ const mermaid = render.renderSequence({
89
+ participants: Array.from(participants.values()),
90
+ messages,
91
+ });
92
+ const mdLines = ["```mermaid", mermaid, "```"];
93
+ if (truncated) {
94
+ mdLines.push("", `_truncated_ — BFS hit the ${NODE_CAP}-node ceiling; deeper paths from this entry were not explored.`);
95
+ }
96
+ const md = mdLines.join("\n");
97
+ return {
98
+ summary: `${participants.size} participants across layers${truncated ? " (truncated)" : ""}`,
99
+ markdown: md,
100
+ data: { participants: Array.from(participants.values()), messages, truncated },
101
+ };
102
+ },
103
+ });
104
+ //# sourceMappingURL=cross_layer_flow_map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross_layer_flow_map.js","sourceRoot":"","sources":["../../src/tools/cross_layer_flow_map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cross_org_diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross_org_diff.d.ts","sourceRoot":"","sources":["../../src/tools/cross_org_diff.ts"],"names":[],"mappings":""}
@@ -0,0 +1,59 @@
1
+ import { analyze, render } from "@ryanstark24/sfgraph-core";
2
+ import { getToolContext } from "../context.js";
3
+ import { defineTool, z } from "./_define.js";
4
+ const inputSchema = z.object({
5
+ org_a: z.string().min(1),
6
+ org_b: z.string().min(1),
7
+ category: z.string().default("all"),
8
+ });
9
+ defineTool({
10
+ name: "cross_org_diff",
11
+ description: "USE THIS for any 'what is different between prod and sandbox' / 'compare two orgs' / 'org drift' question. Set difference of metadata between two ingested Salesforce orgs by category. Returns onlyInA / onlyInB / changed lists.",
12
+ inputSchema,
13
+ async execute(input) {
14
+ // Each org has its own SQLite file. Open BOTH contexts so onlyInA/onlyInB
15
+ // are computed against the right rows. getToolContext resolves aliases
16
+ // for both org_a and org_b.
17
+ const ctxA = await getToolContext({ orgId: input.org_a });
18
+ const ctxB = await getToolContext({ orgId: input.org_b });
19
+ const diff = analyze.diffOrgs({
20
+ storeA: ctxA.graphStore,
21
+ orgA: ctxA.orgId,
22
+ storeB: ctxB.graphStore,
23
+ orgB: ctxB.orgId,
24
+ category: input.category,
25
+ });
26
+ const mermaid = render.renderDiff({
27
+ added: diff.onlyInB.slice(0, 30).map((n) => ({ qualifiedName: n.qualifiedName })),
28
+ removed: diff.onlyInA.slice(0, 30).map((n) => ({ qualifiedName: n.qualifiedName })),
29
+ changed: diff.changed.slice(0, 30).map((c) => ({ qualifiedName: c.a.qualifiedName })),
30
+ });
31
+ const md = [
32
+ "| metric | count |",
33
+ "|---|---|",
34
+ `| only in A | ${diff.onlyInA.length} |`,
35
+ `| only in B | ${diff.onlyInB.length} |`,
36
+ `| changed | ${diff.changed.length} |`,
37
+ "",
38
+ "```mermaid",
39
+ mermaid,
40
+ "```",
41
+ ].join("\n");
42
+ const truncationNote = diff.truncated
43
+ ? ` — results capped at ${analyze.CROSS_ORG_PER_LABEL_CAP}/label; narrow with category filter`
44
+ : "";
45
+ return {
46
+ summary: `A-only:${diff.onlyInA.length} B-only:${diff.onlyInB.length} changed:${diff.changed.length}${truncationNote}`,
47
+ markdown: diff.truncated
48
+ ? `${md}\n\n> _Note: at least one label hit the ${analyze.CROSS_ORG_PER_LABEL_CAP}-row cap. Diff is incomplete — pass a narrower \`category\` to investigate._`
49
+ : md,
50
+ data: {
51
+ onlyInA: diff.onlyInA.map((n) => n.qualifiedName),
52
+ onlyInB: diff.onlyInB.map((n) => n.qualifiedName),
53
+ changed: diff.changed.map((c) => c.a.qualifiedName),
54
+ truncated: diff.truncated ?? false,
55
+ },
56
+ };
57
+ },
58
+ });
59
+ //# sourceMappingURL=cross_org_diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross_org_diff.js","sourceRoot":"","sources":["../../src/tools/cross_org_diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dead_code_audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dead_code_audit.d.ts","sourceRoot":"","sources":["../../src/tools/dead_code_audit.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { analyze } from "@ryanstark24/sfgraph-core";
2
+ import { getToolContext } from "../context.js";
3
+ import { defineTool, z } from "./_define.js";
4
+ const inputSchema = z.object({ org: z.string().min(1) });
5
+ function readCachedDeadCode(db, orgId) {
6
+ try {
7
+ const d = db;
8
+ const rows = d
9
+ .prepare("SELECT qualified_name, score, confidence, reasons FROM _sfgraph_dead_code_scores WHERE org_id = ? ORDER BY score ASC")
10
+ .all(orgId);
11
+ if (!rows || rows.length === 0)
12
+ return null;
13
+ return rows.map((r) => ({
14
+ qualifiedName: r.qualified_name,
15
+ score: r.score,
16
+ confidence: r.confidence,
17
+ reasons: (() => {
18
+ try {
19
+ return JSON.parse(r.reasons);
20
+ }
21
+ catch {
22
+ return [];
23
+ }
24
+ })(),
25
+ }));
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ defineTool({
32
+ name: "dead_code_audit",
33
+ description: "USE THIS for any 'what can I delete' / 'find unused Apex / LWC / Flow' / 'dead code' / 'orphan metadata' question about a Salesforce org. Returns nodes with low freshness AND zero incoming edges, bucketed by confidence with reasons.",
34
+ inputSchema,
35
+ async execute(input) {
36
+ const ctx = await getToolContext({ orgId: input.org });
37
+ const cached = ctx.db ? readCachedDeadCode(ctx.db, ctx.orgId) : null;
38
+ if (cached) {
39
+ const md = cached.length
40
+ ? [
41
+ "| qname | confidence | score | reasons |",
42
+ "|---|---|---|---|",
43
+ ...cached.map((d) => `| \`${d.qualifiedName}\` | ${d.confidence} | ${d.score.toFixed(2)} | ${d.reasons.join(", ")} |`),
44
+ ].join("\n")
45
+ : "_no dead code detected_";
46
+ return {
47
+ summary: `${cached.length} dead-code candidates (cached)`,
48
+ markdown: md,
49
+ data: { dead: cached, cached: true },
50
+ };
51
+ }
52
+ const dead = analyze.findDeadCode(ctx.graphStore, ctx.orgId);
53
+ const md = dead.length
54
+ ? [
55
+ "| qname | label |",
56
+ "|---|---|",
57
+ ...dead.map((d) => `| \`${d.qualifiedName}\` | ${d.label} |`),
58
+ ].join("\n")
59
+ : "_no dead code detected_";
60
+ return {
61
+ summary: `${dead.length} dead-code candidates`,
62
+ markdown: md,
63
+ data: { dead: dead.map((d) => d.qualifiedName), cached: false },
64
+ };
65
+ },
66
+ });
67
+ //# sourceMappingURL=dead_code_audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dead_code_audit.js","sourceRoot":"","sources":["../../src/tools/dead_code_audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=deployment_manifest_gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment_manifest_gen.d.ts","sourceRoot":"","sources":["../../src/tools/deployment_manifest_gen.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { analyze } from "@ryanstark24/sfgraph-core";
2
+ import { getToolContext } from "../context.js";
3
+ import { defineTool, z } from "./_define.js";
4
+ const inputSchema = z.object({
5
+ from_org: z.string().min(1),
6
+ to_org: z.string().min(1),
7
+ category: z.string().optional(),
8
+ });
9
+ defineTool({
10
+ name: "deployment_manifest_gen",
11
+ description: "Generate package.xml + destructiveChanges.xml from cross-org diff.",
12
+ inputSchema,
13
+ async execute(input) {
14
+ // Open BOTH org contexts so the manifest sees the target org's actual
15
+ // node set (each org has its own SQLite file). Aliases for both inputs
16
+ // are resolved by getToolContext.
17
+ const ctxA = await getToolContext({ orgId: input.from_org });
18
+ const ctxB = await getToolContext({ orgId: input.to_org });
19
+ const manifest = analyze.generateManifest({
20
+ storeA: ctxA.graphStore,
21
+ orgA: ctxA.orgId,
22
+ storeB: ctxB.graphStore,
23
+ orgB: ctxB.orgId,
24
+ category: input.category ?? "all",
25
+ });
26
+ return {
27
+ summary: `${manifest.summary.addedOrChanged} added/changed, ${manifest.summary.removed} removed`,
28
+ markdown: [
29
+ "### package.xml",
30
+ "```xml",
31
+ manifest.packageXml.trimEnd(),
32
+ "```",
33
+ "",
34
+ "### destructiveChanges.xml",
35
+ "```xml",
36
+ manifest.destructiveXml.trimEnd(),
37
+ "```",
38
+ ].join("\n"),
39
+ data: manifest,
40
+ };
41
+ },
42
+ });
43
+ //# sourceMappingURL=deployment_manifest_gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment_manifest_gen.js","sourceRoot":"","sources":["../../src/tools/deployment_manifest_gen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,UAAU,CAAC;IACT,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE,oEAAoE;IACjF,WAAW;IACX,KAAK,CAAC,OAAO,CAAC,KAAK;QACjB,sEAAsE;QACtE,uEAAuE;QACvE,kCAAkC;QAClC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;YACxC,MAAM,EAAE,IAAI,CAAC,UAAU;YACvB,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,MAAM,EAAE,IAAI,CAAC,UAAU;YACvB,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK;SAClC,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,mBAAmB,QAAQ,CAAC,OAAO,CAAC,OAAO,UAAU;YAChG,QAAQ,EAAE;gBACR,iBAAiB;gBACjB,QAAQ;gBACR,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE;gBAC7B,KAAK;gBACL,EAAE;gBACF,4BAA4B;gBAC5B,QAAQ;gBACR,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE;gBACjC,KAAK;aACN,CAAC,IAAI,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=explain_code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain_code.d.ts","sourceRoot":"","sources":["../../src/tools/explain_code.ts"],"names":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ import { asQualifiedName } from "@ryanstark24/sfgraph-shared";
2
+ import { getToolContext } from "../context.js";
3
+ import { defineTool, z } from "./_define.js";
4
+ // Cap annotation size at 16 KiB. Cached explanations are echoed back inside
5
+ // markdown blockquotes; unbounded input bloats the SQLite row and would let
6
+ // a poisoned graph break the host's markdown renderer.
7
+ const ANNOTATION_MAX_BYTES = 16 * 1024;
8
+ const inputSchema = z.object({
9
+ org: z.string().min(1),
10
+ qname: z.string().min(1),
11
+ refresh: z.boolean().default(false),
12
+ annotation: z.string().max(ANNOTATION_MAX_BYTES, "annotation exceeds 16 KiB cap").optional(),
13
+ });
14
+ defineTool({
15
+ name: "explain_code",
16
+ description: "USE THIS for any 'explain this method' / 'walk me through X' / 'what does Apex method Y do' question about a stored Salesforce code snippet. Returns the source text + cached LLM explanation (if any). Pass annotation to cache the LLM's explanation back to the graph for future use.",
17
+ inputSchema,
18
+ async execute(input) {
19
+ const ctx = await getToolContext({ orgId: input.org });
20
+ const qname = asQualifiedName(input.qname);
21
+ // Annotation write path
22
+ if (typeof input.annotation === "string" && input.annotation.length > 0) {
23
+ const now = Date.now();
24
+ const ok = ctx.graphStore.updateSnippetExplanation(ctx.orgId, qname, input.annotation, now);
25
+ if (!ok) {
26
+ return {
27
+ summary: `no snippet stored for ${input.qname} — annotation not persisted`,
28
+ markdown: `> No snippet exists for \`${input.qname}\`. Likely a non-code metadata type, or the org has not been ingested yet.`,
29
+ data: {
30
+ qname: input.qname,
31
+ sourceFormat: null,
32
+ sourceText: null,
33
+ startLine: null,
34
+ endLine: null,
35
+ cachedExplanation: null,
36
+ cachedAt: null,
37
+ stored: false,
38
+ },
39
+ };
40
+ }
41
+ const snippet = ctx.graphStore.getSnippet(ctx.orgId, qname);
42
+ return {
43
+ summary: `cached explanation for ${input.qname}`,
44
+ markdown: `> Explanation cached for \`${input.qname}\` at ${new Date(now).toISOString()}.`,
45
+ data: {
46
+ qname: input.qname,
47
+ sourceFormat: snippet?.sourceFormat ?? null,
48
+ sourceText: snippet?.sourceText ?? null,
49
+ startLine: snippet?.startLine ?? null,
50
+ endLine: snippet?.endLine ?? null,
51
+ cachedExplanation: snippet?.llmExplanation ?? input.annotation,
52
+ cachedAt: snippet?.explainedAt ?? now,
53
+ stored: true,
54
+ },
55
+ };
56
+ }
57
+ // Read path
58
+ const snippet = ctx.graphStore.getSnippet(ctx.orgId, qname);
59
+ if (!snippet) {
60
+ return {
61
+ summary: `no snippet stored for ${input.qname} — likely a non-code metadata type`,
62
+ markdown: `> No snippet stored for \`${input.qname}\`. Snippets are emitted only for code parsers (currently Apex methods). For declarative metadata, use \`analyze_field\` or \`trace_upstream\` instead.`,
63
+ data: {
64
+ qname: input.qname,
65
+ sourceFormat: null,
66
+ sourceText: null,
67
+ startLine: null,
68
+ endLine: null,
69
+ cachedExplanation: null,
70
+ cachedAt: null,
71
+ stored: false,
72
+ },
73
+ };
74
+ }
75
+ const showCached = !input.refresh && snippet.llmExplanation;
76
+ const md = [
77
+ `**${input.qname}** — \`${snippet.sourceFormat}\`${snippet.startLine != null ? ` (lines ${snippet.startLine}–${snippet.endLine ?? "?"})` : ""}`,
78
+ "",
79
+ `\`\`\`${snippet.sourceFormat}`,
80
+ snippet.sourceText,
81
+ "```",
82
+ "",
83
+ ];
84
+ if (showCached) {
85
+ md.push("**Cached explanation:**", "", `> ${snippet.llmExplanation}`);
86
+ }
87
+ else {
88
+ md.push("> No explanation cached yet — generate one and call `explain_code` again with `annotation` to persist it.");
89
+ }
90
+ md.push("", "_follow_up_tools: `analyze_field`, `trace_upstream`, `trace_downstream`_");
91
+ return {
92
+ summary: showCached
93
+ ? `snippet + cached explanation for ${input.qname}`
94
+ : `snippet for ${input.qname} (no cached explanation)`,
95
+ markdown: md.join("\n"),
96
+ data: {
97
+ qname: input.qname,
98
+ sourceFormat: snippet.sourceFormat,
99
+ sourceText: snippet.sourceText,
100
+ startLine: snippet.startLine ?? null,
101
+ endLine: snippet.endLine ?? null,
102
+ cachedExplanation: showCached ? (snippet.llmExplanation ?? null) : null,
103
+ cachedAt: showCached ? (snippet.explainedAt ?? null) : null,
104
+ stored: false,
105
+ },
106
+ };
107
+ },
108
+ });
109
+ //# sourceMappingURL=explain_code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain_code.js","sourceRoot":"","sources":["../../src/tools/explain_code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=freshness_report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freshness_report.d.ts","sourceRoot":"","sources":["../../src/tools/freshness_report.ts"],"names":[],"mappings":""}