studiograph 1.1.3 → 1.2.0-beta.10

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 (356) hide show
  1. package/README.md +2 -8
  2. package/dist/agent/orchestrator.d.ts +53 -0
  3. package/dist/agent/orchestrator.js +197 -12
  4. package/dist/agent/orchestrator.js.map +1 -1
  5. package/dist/agent/prompts/system.md +43 -11
  6. package/dist/agent/skill-loader.d.ts +48 -0
  7. package/dist/agent/skill-loader.js +166 -0
  8. package/dist/agent/skill-loader.js.map +1 -0
  9. package/dist/agent/skills/{bundled/enrich-entities.md → enrich-entities.md} +12 -0
  10. package/dist/agent/skills/entity-schema.md +502 -0
  11. package/dist/agent/skills/obsidian-source-setup.md +246 -0
  12. package/dist/agent/skills/sync-configuration.md +144 -0
  13. package/dist/agent/skills/sync-setup.md +84 -0
  14. package/dist/agent/tools/connector-tools.d.ts +37 -0
  15. package/dist/agent/tools/connector-tools.js +132 -0
  16. package/dist/agent/tools/connector-tools.js.map +1 -0
  17. package/dist/agent/tools/fs-tools.d.ts +39 -0
  18. package/dist/agent/tools/fs-tools.js +106 -0
  19. package/dist/agent/tools/fs-tools.js.map +1 -0
  20. package/dist/agent/tools/graph-tools.d.ts +33 -1
  21. package/dist/agent/tools/graph-tools.js +192 -44
  22. package/dist/agent/tools/graph-tools.js.map +1 -1
  23. package/dist/agent/tools/load-skill.d.ts +1 -1
  24. package/dist/agent/tools/load-skill.js +1 -1
  25. package/dist/agent/tools/load-skill.js.map +1 -1
  26. package/dist/agent/tools/ops-tools.d.ts +24 -0
  27. package/dist/agent/tools/ops-tools.js +542 -0
  28. package/dist/agent/tools/ops-tools.js.map +1 -0
  29. package/dist/agent/tools/sync-tools.d.ts +33 -0
  30. package/dist/agent/tools/sync-tools.js +947 -0
  31. package/dist/agent/tools/sync-tools.js.map +1 -0
  32. package/dist/auth/github.d.ts +11 -8
  33. package/dist/auth/github.js +56 -75
  34. package/dist/auth/github.js.map +1 -1
  35. package/dist/cli/colors.d.ts +54 -0
  36. package/dist/cli/colors.js +133 -0
  37. package/dist/cli/colors.js.map +1 -0
  38. package/dist/cli/commands/app.js +121 -18
  39. package/dist/cli/commands/app.js.map +1 -1
  40. package/dist/cli/commands/auth.d.ts +1 -1
  41. package/dist/cli/commands/auth.js +26 -10
  42. package/dist/cli/commands/auth.js.map +1 -1
  43. package/dist/cli/commands/clone.d.ts +9 -0
  44. package/dist/cli/commands/clone.js +167 -0
  45. package/dist/cli/commands/clone.js.map +1 -0
  46. package/dist/cli/commands/commit.d.ts +8 -0
  47. package/dist/cli/commands/commit.js +44 -0
  48. package/dist/cli/commands/commit.js.map +1 -0
  49. package/dist/cli/commands/connector.js +10 -2
  50. package/dist/cli/commands/connector.js.map +1 -1
  51. package/dist/cli/commands/deploy.d.ts +4 -6
  52. package/dist/cli/commands/deploy.js +292 -115
  53. package/dist/cli/commands/deploy.js.map +1 -1
  54. package/dist/cli/commands/enrich.d.ts +11 -0
  55. package/dist/cli/commands/enrich.js +135 -0
  56. package/dist/cli/commands/enrich.js.map +1 -0
  57. package/dist/cli/commands/graphrag.d.ts +12 -0
  58. package/dist/cli/commands/graphrag.js +122 -0
  59. package/dist/cli/commands/graphrag.js.map +1 -0
  60. package/dist/cli/commands/init.js +29 -196
  61. package/dist/cli/commands/init.js.map +1 -1
  62. package/dist/cli/commands/join.js +23 -3
  63. package/dist/cli/commands/join.js.map +1 -1
  64. package/dist/cli/commands/orphans.d.ts +8 -0
  65. package/dist/cli/commands/orphans.js +125 -0
  66. package/dist/cli/commands/orphans.js.map +1 -0
  67. package/dist/cli/commands/provision.js +11 -7
  68. package/dist/cli/commands/provision.js.map +1 -1
  69. package/dist/cli/commands/r2.js +8 -2
  70. package/dist/cli/commands/r2.js.map +1 -1
  71. package/dist/cli/commands/redeploy.d.ts +9 -0
  72. package/dist/cli/commands/redeploy.js +203 -0
  73. package/dist/cli/commands/redeploy.js.map +1 -0
  74. package/dist/cli/commands/reset.d.ts +12 -0
  75. package/dist/cli/commands/reset.js +137 -0
  76. package/dist/cli/commands/reset.js.map +1 -0
  77. package/dist/cli/commands/resolve.d.ts +8 -0
  78. package/dist/cli/commands/resolve.js +85 -0
  79. package/dist/cli/commands/resolve.js.map +1 -0
  80. package/dist/cli/commands/review.d.ts +19 -0
  81. package/dist/cli/commands/review.js +128 -0
  82. package/dist/cli/commands/review.js.map +1 -0
  83. package/dist/cli/commands/serve.js +55 -8
  84. package/dist/cli/commands/serve.js.map +1 -1
  85. package/dist/cli/commands/source.d.ts +16 -0
  86. package/dist/cli/commands/source.js +159 -0
  87. package/dist/cli/commands/source.js.map +1 -0
  88. package/dist/cli/commands/start.js +307 -55
  89. package/dist/cli/commands/start.js.map +1 -1
  90. package/dist/cli/commands/sync-entities.d.ts +13 -0
  91. package/dist/cli/commands/sync-entities.js +242 -0
  92. package/dist/cli/commands/sync-entities.js.map +1 -0
  93. package/dist/cli/commands/sync.js +81 -5
  94. package/dist/cli/commands/sync.js.map +1 -1
  95. package/dist/cli/index.js +45 -9
  96. package/dist/cli/index.js.map +1 -1
  97. package/dist/cli/scaffolding.d.ts +2 -1
  98. package/dist/cli/scaffolding.js +38 -23
  99. package/dist/cli/scaffolding.js.map +1 -1
  100. package/dist/cli/setup-wizard.d.ts +30 -0
  101. package/dist/cli/setup-wizard.js +244 -0
  102. package/dist/cli/setup-wizard.js.map +1 -0
  103. package/dist/cli/sync-review-interactive.d.ts +31 -0
  104. package/dist/cli/sync-review-interactive.js +393 -0
  105. package/dist/cli/sync-review-interactive.js.map +1 -0
  106. package/dist/cli/theme.d.ts +31 -0
  107. package/dist/cli/theme.js +116 -0
  108. package/dist/cli/theme.js.map +1 -0
  109. package/dist/core/graph.d.ts +40 -12
  110. package/dist/core/graph.js +344 -104
  111. package/dist/core/graph.js.map +1 -1
  112. package/dist/core/migration-runner.d.ts +4 -1
  113. package/dist/core/migration-runner.js +14 -3
  114. package/dist/core/migration-runner.js.map +1 -1
  115. package/dist/core/types.d.ts +2 -4
  116. package/dist/core/types.js +1 -2
  117. package/dist/core/types.js.map +1 -1
  118. package/dist/core/user-config.d.ts +12 -0
  119. package/dist/core/user-config.js.map +1 -1
  120. package/dist/core/workspace-manager.d.ts +6 -1
  121. package/dist/core/workspace-manager.js +29 -4
  122. package/dist/core/workspace-manager.js.map +1 -1
  123. package/dist/core/workspace.d.ts +13 -5
  124. package/dist/core/workspace.js +115 -33
  125. package/dist/core/workspace.js.map +1 -1
  126. package/dist/lib/lib/utils.d.ts +2 -0
  127. package/dist/lib/lib/utils.js +6 -0
  128. package/dist/lib/lib/utils.js.map +1 -0
  129. package/dist/mcp/connector-manager.d.ts +7 -3
  130. package/dist/mcp/connector-manager.js +61 -16
  131. package/dist/mcp/connector-manager.js.map +1 -1
  132. package/dist/mcp/connectors/asana.d.ts +2 -0
  133. package/dist/mcp/connectors/asana.js +20 -0
  134. package/dist/mcp/connectors/asana.js.map +1 -0
  135. package/dist/mcp/connectors/definitions.d.ts +3 -1
  136. package/dist/mcp/connectors/definitions.js +19 -127
  137. package/dist/mcp/connectors/definitions.js.map +1 -1
  138. package/dist/mcp/connectors/figma.d.ts +5 -0
  139. package/dist/mcp/connectors/figma.js +21 -0
  140. package/dist/mcp/connectors/figma.js.map +1 -0
  141. package/dist/mcp/connectors/gdrive.d.ts +2 -0
  142. package/dist/mcp/connectors/gdrive.js +20 -0
  143. package/dist/mcp/connectors/gdrive.js.map +1 -0
  144. package/dist/mcp/connectors/granola.d.ts +2 -0
  145. package/dist/mcp/connectors/granola.js +12 -0
  146. package/dist/mcp/connectors/granola.js.map +1 -0
  147. package/dist/mcp/connectors/linear.d.ts +2 -0
  148. package/dist/mcp/connectors/linear.js +19 -0
  149. package/dist/mcp/connectors/linear.js.map +1 -0
  150. package/dist/mcp/connectors/obsidian.d.ts +2 -0
  151. package/dist/mcp/connectors/obsidian.js +19 -0
  152. package/dist/mcp/connectors/obsidian.js.map +1 -0
  153. package/dist/mcp/connectors/pipedrive.d.ts +2 -0
  154. package/dist/mcp/connectors/pipedrive.js +20 -0
  155. package/dist/mcp/connectors/pipedrive.js.map +1 -0
  156. package/dist/mcp/connectors/slack.d.ts +2 -0
  157. package/dist/mcp/connectors/slack.js +21 -0
  158. package/dist/mcp/connectors/slack.js.map +1 -0
  159. package/dist/mcp/oauth-provider.d.ts +41 -0
  160. package/dist/mcp/oauth-provider.js +160 -0
  161. package/dist/mcp/oauth-provider.js.map +1 -0
  162. package/dist/server/index.js +97 -11
  163. package/dist/server/index.js.map +1 -1
  164. package/dist/server/plugin-loader.d.ts +8 -0
  165. package/dist/server/plugin-loader.js +54 -2
  166. package/dist/server/plugin-loader.js.map +1 -1
  167. package/dist/server/routes/chat.d.ts +3 -2
  168. package/dist/server/routes/chat.js +67 -16
  169. package/dist/server/routes/chat.js.map +1 -1
  170. package/dist/server/routes/git-api.d.ts +9 -0
  171. package/dist/server/routes/git-api.js +82 -0
  172. package/dist/server/routes/git-api.js.map +1 -0
  173. package/dist/server/routes/graph-api.d.ts +2 -2
  174. package/dist/server/routes/graph-api.js +164 -3
  175. package/dist/server/routes/graph-api.js.map +1 -1
  176. package/dist/server/routes/workspace-api.d.ts +9 -0
  177. package/dist/server/routes/workspace-api.js +170 -0
  178. package/dist/server/routes/workspace-api.js.map +1 -0
  179. package/dist/services/assets/base.d.ts +2 -2
  180. package/dist/services/assets/base.js +4 -4
  181. package/dist/services/assets/base.js.map +1 -1
  182. package/dist/services/assets/index.d.ts +6 -6
  183. package/dist/services/assets/index.js +12 -12
  184. package/dist/services/assets/index.js.map +1 -1
  185. package/dist/services/git.d.ts +31 -0
  186. package/dist/services/git.js +92 -3
  187. package/dist/services/git.js.map +1 -1
  188. package/dist/services/github-provisioner.d.ts +8 -3
  189. package/dist/services/github-provisioner.js +35 -8
  190. package/dist/services/github-provisioner.js.map +1 -1
  191. package/dist/services/lint-service.js +8 -1
  192. package/dist/services/lint-service.js.map +1 -1
  193. package/dist/services/markdown.js +3 -3
  194. package/dist/services/markdown.js.map +1 -1
  195. package/dist/services/memory-service.d.ts +1 -1
  196. package/dist/services/memory-service.js +2 -3
  197. package/dist/services/memory-service.js.map +1 -1
  198. package/dist/services/orphan-service.d.ts +31 -0
  199. package/dist/services/orphan-service.js +100 -0
  200. package/dist/services/orphan-service.js.map +1 -0
  201. package/dist/services/sync/commit.d.ts +60 -0
  202. package/dist/services/sync/commit.js +370 -0
  203. package/dist/services/sync/commit.js.map +1 -0
  204. package/dist/services/sync/context-index.d.ts +69 -0
  205. package/dist/services/sync/context-index.js +280 -0
  206. package/dist/services/sync/context-index.js.map +1 -0
  207. package/dist/services/sync/derive.d.ts +34 -0
  208. package/dist/services/sync/derive.js +164 -0
  209. package/dist/services/sync/derive.js.map +1 -0
  210. package/dist/services/sync/enrichment-state.d.ts +31 -0
  211. package/dist/services/sync/enrichment-state.js +63 -0
  212. package/dist/services/sync/enrichment-state.js.map +1 -0
  213. package/dist/services/sync/enrichment.d.ts +25 -0
  214. package/dist/services/sync/enrichment.js +121 -0
  215. package/dist/services/sync/enrichment.js.map +1 -0
  216. package/dist/services/sync/frontmatter-extractor.d.ts +40 -0
  217. package/dist/services/sync/frontmatter-extractor.js +273 -0
  218. package/dist/services/sync/frontmatter-extractor.js.map +1 -0
  219. package/dist/services/sync/graph-match-state.d.ts +33 -0
  220. package/dist/services/sync/graph-match-state.js +61 -0
  221. package/dist/services/sync/graph-match-state.js.map +1 -0
  222. package/dist/services/sync/graph-match.d.ts +53 -0
  223. package/dist/services/sync/graph-match.js +316 -0
  224. package/dist/services/sync/graph-match.js.map +1 -0
  225. package/dist/services/sync/graphrag-client.d.ts +43 -0
  226. package/dist/services/sync/graphrag-client.js +94 -0
  227. package/dist/services/sync/graphrag-client.js.map +1 -0
  228. package/dist/services/sync/graphrag-config.d.ts +16 -0
  229. package/dist/services/sync/graphrag-config.js +39 -0
  230. package/dist/services/sync/graphrag-config.js.map +1 -0
  231. package/dist/services/sync/graphrag-context.d.ts +14 -0
  232. package/dist/services/sync/graphrag-context.js +109 -0
  233. package/dist/services/sync/graphrag-context.js.map +1 -0
  234. package/dist/services/sync/graphrag-indexer.d.ts +30 -0
  235. package/dist/services/sync/graphrag-indexer.js +358 -0
  236. package/dist/services/sync/graphrag-indexer.js.map +1 -0
  237. package/dist/services/sync/llm.d.ts +32 -0
  238. package/dist/services/sync/llm.js +115 -0
  239. package/dist/services/sync/llm.js.map +1 -0
  240. package/dist/services/sync/mcp-client.d.ts +59 -0
  241. package/dist/services/sync/mcp-client.js +285 -0
  242. package/dist/services/sync/mcp-client.js.map +1 -0
  243. package/dist/services/sync/model-factory.d.ts +10 -0
  244. package/dist/services/sync/model-factory.js +24 -0
  245. package/dist/services/sync/model-factory.js.map +1 -0
  246. package/dist/services/sync/name-quality.d.ts +31 -0
  247. package/dist/services/sync/name-quality.js +60 -0
  248. package/dist/services/sync/name-quality.js.map +1 -0
  249. package/dist/services/sync/output-schemas.d.ts +92 -0
  250. package/dist/services/sync/output-schemas.js +43 -0
  251. package/dist/services/sync/output-schemas.js.map +1 -0
  252. package/dist/services/sync/prompts.d.ts +19 -0
  253. package/dist/services/sync/prompts.js +128 -0
  254. package/dist/services/sync/prompts.js.map +1 -0
  255. package/dist/services/sync/reconciler.d.ts +48 -0
  256. package/dist/services/sync/reconciler.js +295 -0
  257. package/dist/services/sync/reconciler.js.map +1 -0
  258. package/dist/services/sync/source-config.d.ts +45 -0
  259. package/dist/services/sync/source-config.js +208 -0
  260. package/dist/services/sync/source-config.js.map +1 -0
  261. package/dist/services/sync/source-definitions/asana.d.ts +15 -0
  262. package/dist/services/sync/source-definitions/asana.js +48 -0
  263. package/dist/services/sync/source-definitions/asana.js.map +1 -0
  264. package/dist/services/sync/source-definitions/definitions.d.ts +21 -0
  265. package/dist/services/sync/source-definitions/definitions.js +26 -0
  266. package/dist/services/sync/source-definitions/definitions.js.map +1 -0
  267. package/dist/services/sync/source-definitions/gdrive.d.ts +16 -0
  268. package/dist/services/sync/source-definitions/gdrive.js +68 -0
  269. package/dist/services/sync/source-definitions/gdrive.js.map +1 -0
  270. package/dist/services/sync/source-definitions/granola.d.ts +2 -0
  271. package/dist/services/sync/source-definitions/granola.js +28 -0
  272. package/dist/services/sync/source-definitions/granola.js.map +1 -0
  273. package/dist/services/sync/source-definitions/linear.d.ts +2 -0
  274. package/dist/services/sync/source-definitions/linear.js +60 -0
  275. package/dist/services/sync/source-definitions/linear.js.map +1 -0
  276. package/dist/services/sync/source-definitions/obsidian.d.ts +2 -0
  277. package/dist/services/sync/source-definitions/obsidian.js +55 -0
  278. package/dist/services/sync/source-definitions/obsidian.js.map +1 -0
  279. package/dist/services/sync/source-definitions/pipedrive.d.ts +2 -0
  280. package/dist/services/sync/source-definitions/pipedrive.js +52 -0
  281. package/dist/services/sync/source-definitions/pipedrive.js.map +1 -0
  282. package/dist/services/sync/staging.d.ts +53 -0
  283. package/dist/services/sync/staging.js +131 -0
  284. package/dist/services/sync/staging.js.map +1 -0
  285. package/dist/services/sync/structured-extractor.d.ts +49 -0
  286. package/dist/services/sync/structured-extractor.js +344 -0
  287. package/dist/services/sync/structured-extractor.js.map +1 -0
  288. package/dist/services/sync/sync-runner.d.ts +32 -0
  289. package/dist/services/sync/sync-runner.js +195 -0
  290. package/dist/services/sync/sync-runner.js.map +1 -0
  291. package/dist/services/sync/sync-state.d.ts +43 -0
  292. package/dist/services/sync/sync-state.js +154 -0
  293. package/dist/services/sync/sync-state.js.map +1 -0
  294. package/dist/services/sync/types.d.ts +203 -0
  295. package/dist/services/sync/types.js +8 -0
  296. package/dist/services/sync/types.js.map +1 -0
  297. package/dist/services/sync/unstructured-extractor.d.ts +29 -0
  298. package/dist/services/sync/unstructured-extractor.js +197 -0
  299. package/dist/services/sync/unstructured-extractor.js.map +1 -0
  300. package/dist/services/vector-service.d.ts +11 -0
  301. package/dist/services/vector-service.js +42 -0
  302. package/dist/services/vector-service.js.map +1 -1
  303. package/dist/utils/git.d.ts +31 -4
  304. package/dist/utils/git.js +65 -7
  305. package/dist/utils/git.js.map +1 -1
  306. package/dist/utils/merge-resolver.d.ts +60 -0
  307. package/dist/utils/merge-resolver.js +304 -0
  308. package/dist/utils/merge-resolver.js.map +1 -0
  309. package/dist/utils/preflight.d.ts +2 -1
  310. package/dist/utils/preflight.js +8 -1
  311. package/dist/utils/preflight.js.map +1 -1
  312. package/dist/utils/workspace-config.d.ts +8 -0
  313. package/dist/utils/workspace-config.js +22 -0
  314. package/dist/utils/workspace-config.js.map +1 -0
  315. package/dist/web/_app/env.js +1 -0
  316. package/dist/web/_app/immutable/assets/0.BwJV4fvl.css +1 -0
  317. package/dist/web/_app/immutable/assets/2.DRHi7ABa.css +1 -0
  318. package/dist/web/_app/immutable/assets/3.CnAQdPKU.css +1 -0
  319. package/dist/web/_app/immutable/assets/4.BG92MufE.css +1 -0
  320. package/dist/web/_app/immutable/assets/5.CfrQIPYs.css +1 -0
  321. package/dist/web/_app/immutable/assets/ChatPanel.BNzaCFTL.css +1 -0
  322. package/dist/web/_app/immutable/assets/editor.D6Rjo7RE.css +1 -0
  323. package/dist/web/_app/immutable/chunks/4QY4j-jX.js +1 -0
  324. package/dist/web/_app/immutable/chunks/B4G4uWkV.js +1 -0
  325. package/dist/web/_app/immutable/chunks/BB_5th5W.js +3383 -0
  326. package/dist/web/_app/immutable/chunks/CUzqHQY_.js +1 -0
  327. package/dist/web/_app/immutable/chunks/CYrVHOHA.js +1 -0
  328. package/dist/web/_app/immutable/chunks/CksE5s8n.js +1 -0
  329. package/dist/web/_app/immutable/chunks/CqkleIqs.js +1 -0
  330. package/dist/web/_app/immutable/chunks/D0JBkEPE.js +86 -0
  331. package/dist/web/_app/immutable/chunks/D2K5GzLj.js +1 -0
  332. package/dist/web/_app/immutable/chunks/DEkoussQ.js +2 -0
  333. package/dist/web/_app/immutable/chunks/DW-KmHRi.js +1 -0
  334. package/dist/web/_app/immutable/chunks/DcCr4z9k.js +1 -0
  335. package/dist/web/_app/immutable/chunks/Dg2wWwJu.js +2 -0
  336. package/dist/web/_app/immutable/chunks/Dh_H7Owr.js +18 -0
  337. package/dist/web/_app/immutable/chunks/DnlgZ_Tk.js +5 -0
  338. package/dist/web/_app/immutable/chunks/DtVH--hH.js +6 -0
  339. package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +1 -0
  340. package/dist/web/_app/immutable/chunks/SBEriEQR.js +1 -0
  341. package/dist/web/_app/immutable/chunks/WSUKABI_.js +1 -0
  342. package/dist/web/_app/immutable/chunks/YTERt3Ul.js +6 -0
  343. package/dist/web/_app/immutable/chunks/m_R7HatS.js +1 -0
  344. package/dist/web/_app/immutable/chunks/vlmEnjfO.js +1 -0
  345. package/dist/web/_app/immutable/entry/app.B9pwpU_x.js +2 -0
  346. package/dist/web/_app/immutable/entry/start.CDuNCEco.js +1 -0
  347. package/dist/web/_app/immutable/nodes/0.YEQhw1us.js +1 -0
  348. package/dist/web/_app/immutable/nodes/1.CvmHhpRy.js +1 -0
  349. package/dist/web/_app/immutable/nodes/2.c5k1r7dq.js +1 -0
  350. package/dist/web/_app/immutable/nodes/3.B24tcdLK.js +1 -0
  351. package/dist/web/_app/immutable/nodes/4.kX2m5Pp9.js +16 -0
  352. package/dist/web/_app/immutable/nodes/5.DELt6wTD.js +2 -0
  353. package/dist/web/_app/version.json +1 -0
  354. package/dist/web/index.html +41 -0
  355. package/package.json +21 -7
  356. /package/dist/agent/skills/{bundled/gather-context.md → gather-context.md} +0 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Filesystem tools for the agent.
3
+ *
4
+ * Gives the agent read/write access to local files outside the workspace
5
+ * (e.g. Obsidian vaults, project docs, config files).
6
+ */
7
+ export declare function createFsTools(): ({
8
+ name: string;
9
+ description: string;
10
+ parameters: import("@sinclair/typebox").TObject<{
11
+ path: import("@sinclair/typebox").TString;
12
+ }>;
13
+ execute: (_toolCallId: string, params: {
14
+ path: string;
15
+ }) => Promise<{
16
+ content: {
17
+ type: "text";
18
+ text: string;
19
+ }[];
20
+ details: any;
21
+ }>;
22
+ } | {
23
+ name: string;
24
+ description: string;
25
+ parameters: import("@sinclair/typebox").TObject<{
26
+ path: import("@sinclair/typebox").TString;
27
+ content: import("@sinclair/typebox").TString;
28
+ }>;
29
+ execute: (_toolCallId: string, params: {
30
+ path: string;
31
+ content: string;
32
+ }) => Promise<{
33
+ content: {
34
+ type: "text";
35
+ text: string;
36
+ }[];
37
+ details: any;
38
+ }>;
39
+ })[];
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Filesystem tools for the agent.
3
+ *
4
+ * Gives the agent read/write access to local files outside the workspace
5
+ * (e.g. Obsidian vaults, project docs, config files).
6
+ */
7
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, existsSync } from 'fs';
8
+ import { join, resolve, dirname } from 'path';
9
+ import { Type as T } from '@sinclair/typebox';
10
+ import { wrapToolResult } from './graph-tools.js';
11
+ export function createFsTools() {
12
+ return [
13
+ {
14
+ name: 'read_file',
15
+ description: 'Read a file from the local filesystem by absolute or ~-relative path. ' +
16
+ 'Returns the file contents as text. Use for reading docs, configs, or any file outside the workspace.',
17
+ parameters: T.Object({
18
+ path: T.String({ description: 'Absolute path or ~/relative path to the file' }),
19
+ }),
20
+ execute: async (_toolCallId, params) => {
21
+ try {
22
+ const resolved = resolvePath(params.path);
23
+ const stat = statSync(resolved);
24
+ if (stat.isDirectory()) {
25
+ return wrapToolResult({
26
+ success: false,
27
+ error: `Path is a directory, not a file. Use list_directory instead.`,
28
+ });
29
+ }
30
+ const content = readFileSync(resolved, 'utf-8');
31
+ return wrapToolResult({ success: true, path: resolved, content });
32
+ }
33
+ catch (error) {
34
+ return wrapToolResult({
35
+ success: false,
36
+ error: error instanceof Error ? error.message : 'Unknown error',
37
+ });
38
+ }
39
+ },
40
+ },
41
+ {
42
+ name: 'list_directory',
43
+ description: 'List files and subdirectories at a given path. ' +
44
+ 'Returns names with a trailing / for directories. Use to explore folders before reading files.',
45
+ parameters: T.Object({
46
+ path: T.String({ description: 'Absolute path or ~/relative path to the directory' }),
47
+ }),
48
+ execute: async (_toolCallId, params) => {
49
+ try {
50
+ const resolved = resolvePath(params.path);
51
+ if (!existsSync(resolved)) {
52
+ return wrapToolResult({ success: false, error: `Path not found: ${resolved}` });
53
+ }
54
+ const entries = readdirSync(resolved).map(name => {
55
+ const full = join(resolved, name);
56
+ try {
57
+ return statSync(full).isDirectory() ? `${name}/` : name;
58
+ }
59
+ catch {
60
+ return name;
61
+ }
62
+ });
63
+ return wrapToolResult({ success: true, path: resolved, entries });
64
+ }
65
+ catch (error) {
66
+ return wrapToolResult({
67
+ success: false,
68
+ error: error instanceof Error ? error.message : 'Unknown error',
69
+ });
70
+ }
71
+ },
72
+ },
73
+ {
74
+ name: 'write_file',
75
+ description: 'Write content to a file on the local filesystem. Creates parent directories if needed. ' +
76
+ 'Overwrites the file if it already exists. Use for creating or updating docs, configs, or any file outside the workspace.',
77
+ parameters: T.Object({
78
+ path: T.String({ description: 'Absolute path or ~/relative path to the file' }),
79
+ content: T.String({ description: 'Full file content to write' }),
80
+ }),
81
+ execute: async (_toolCallId, params) => {
82
+ try {
83
+ const resolved = resolvePath(params.path);
84
+ mkdirSync(dirname(resolved), { recursive: true });
85
+ writeFileSync(resolved, params.content, 'utf-8');
86
+ return wrapToolResult({ success: true, path: resolved, bytesWritten: Buffer.byteLength(params.content, 'utf-8') });
87
+ }
88
+ catch (error) {
89
+ return wrapToolResult({
90
+ success: false,
91
+ error: error instanceof Error ? error.message : 'Unknown error',
92
+ });
93
+ }
94
+ },
95
+ },
96
+ ];
97
+ }
98
+ /** Expand ~ and resolve to absolute path */
99
+ function resolvePath(p) {
100
+ if (p.startsWith('~/') || p === '~') {
101
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? '';
102
+ return resolve(join(home, p.slice(1)));
103
+ }
104
+ return resolve(p);
105
+ }
106
+ //# sourceMappingURL=fs-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-tools.js","sourceRoot":"","sources":["../../../src/agent/tools/fs-tools.ts"],"names":[],"mappings":"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"}
@@ -8,14 +8,30 @@
8
8
  * - Upload assets
9
9
  */
10
10
  import { WorkspaceManager } from '../../core/workspace-manager.js';
11
+ /**
12
+ * Helper to wrap tool results in AgentToolResult format
13
+ */
14
+ export declare function wrapToolResult(result: any): {
15
+ content: {
16
+ type: "text";
17
+ text: string;
18
+ }[];
19
+ details: any;
20
+ };
11
21
  /**
12
22
  * Create graph tools for the agent
13
23
  */
24
+ export interface MutationEvent {
25
+ action: 'created' | 'updated' | 'deleted';
26
+ repo: string;
27
+ entityType: string;
28
+ entityId: string;
29
+ }
14
30
  export declare function createGraphTools(workspaceManager: WorkspaceManager, gitUser: {
15
31
  id: string;
16
32
  name: string;
17
33
  email: string;
18
- }): ({
34
+ }, workspacePath?: string, onHighlight?: (ids: string[]) => void, onMutation?: (m: MutationEvent) => void): ({
19
35
  name: string;
20
36
  label: string;
21
37
  description: string;
@@ -45,4 +61,20 @@ export declare function createGraphTools(workspaceManager: WorkspaceManager, git
45
61
  }[];
46
62
  details: any;
47
63
  }>;
64
+ } | {
65
+ name: string;
66
+ label: string;
67
+ description: string;
68
+ parameters: import("@sinclair/typebox").TObject<{
69
+ entityIds: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
70
+ }>;
71
+ execute: (_toolCallId: string, params: {
72
+ entityIds: string[];
73
+ }) => Promise<{
74
+ content: {
75
+ type: "text";
76
+ text: string;
77
+ }[];
78
+ details: any;
79
+ }>;
48
80
  })[];
@@ -10,10 +10,12 @@
10
10
  import { Type as T } from '@sinclair/typebox';
11
11
  import { ENTITY_SCHEMAS } from '../../core/validation.js';
12
12
  import { lintWorkspace } from '../../services/lint-service.js';
13
+ import { findOrphans } from '../../services/orphan-service.js';
14
+ import { SyncStateManager } from '../../services/sync/sync-state.js';
13
15
  /**
14
16
  * Helper to wrap tool results in AgentToolResult format
15
17
  */
16
- function wrapToolResult(result) {
18
+ export function wrapToolResult(result) {
17
19
  const text = JSON.stringify(result, null, 2);
18
20
  return {
19
21
  content: [{ type: 'text', text }],
@@ -21,17 +23,22 @@ function wrapToolResult(result) {
21
23
  };
22
24
  }
23
25
  /**
24
- * Create graph tools for the agent
26
+ * Strip entity_type/entity_id from data to avoid confusing the LLM
27
+ * (these are already surfaced as top-level entityType/entityId fields)
25
28
  */
26
- export function createGraphTools(workspaceManager, gitUser) {
29
+ function cleanData(data) {
30
+ const { entity_type, entity_id, ...rest } = data;
31
+ return rest;
32
+ }
33
+ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation) {
27
34
  return [
28
35
  // Create entity
29
36
  {
30
37
  name: 'create_entity',
31
38
  label: 'Create Entity',
32
- description: 'Create a new entity in a repository. Always validate required fields before calling.',
39
+ description: 'Create a new entity in a repository. Always validate required fields before calling. Repo is auto-resolved for app-defined types (deck, document, etc.).',
33
40
  parameters: T.Object({
34
- repo: T.String({ description: 'Repository name' }),
41
+ repo: T.Optional(T.String({ description: 'Repository name (auto-resolved for app entity types)' })),
35
42
  entityType: T.String({ description: 'Entity type (project, client, decision, etc.)' }),
36
43
  entityId: T.String({ description: 'Unique entity ID in kebab-case' }),
37
44
  data: T.Object({}, { description: 'Entity data (YAML frontmatter)', additionalProperties: true }),
@@ -40,7 +47,13 @@ export function createGraphTools(workspaceManager, gitUser) {
40
47
  }),
41
48
  execute: async (toolCallId, params) => {
42
49
  try {
43
- const graph = workspaceManager.getGraph(params.repo);
50
+ let repoName = params.repo;
51
+ if (!repoName) {
52
+ repoName = workspaceManager.getRepoForEntityType(params.entityType);
53
+ if (!repoName)
54
+ return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
55
+ }
56
+ const graph = workspaceManager.getGraph(repoName);
44
57
  // Add timestamps and user info
45
58
  const now = new Date().toISOString();
46
59
  const dataWithMeta = {
@@ -51,22 +64,26 @@ export function createGraphTools(workspaceManager, gitUser) {
51
64
  created_by: gitUser.id,
52
65
  updated_by: gitUser.id,
53
66
  };
67
+ // Sanitize double-escaped newlines from LLM JSON output
68
+ const sanitizedContent = (params.content || '').replace(/\\n/g, '\n');
54
69
  const entity = await graph.create({
55
70
  entityType: params.entityType,
56
71
  entityId: params.entityId,
57
72
  data: dataWithMeta,
58
- content: params.content || '',
73
+ content: sanitizedContent,
59
74
  commitMessage: params.commitMessage,
60
75
  });
76
+ onMutation?.({ action: 'created', repo: repoName, entityType: params.entityType, entityId: params.entityId });
61
77
  return wrapToolResult({
62
78
  success: true,
63
79
  entity: {
64
- id: entity.id,
65
- type: entity.entityType,
80
+ entityId: entity.id,
81
+ entityType: entity.entityType,
82
+ repo: repoName,
66
83
  path: entity.path,
67
- data: entity.data,
84
+ data: cleanData(entity.data),
68
85
  },
69
- message: `Created ${params.entityType}: ${params.entityId}`,
86
+ message: `Created ${params.entityType}: ${params.entityId} in ${repoName}. Auto-committed — ready to push.`,
70
87
  });
71
88
  }
72
89
  catch (error) {
@@ -81,23 +98,26 @@ export function createGraphTools(workspaceManager, gitUser) {
81
98
  {
82
99
  name: 'get_entity',
83
100
  label: 'Get Entity',
84
- description: 'Retrieve an entity by type and ID',
101
+ description: 'Retrieve full entity details. Use repo, entityType, entityId from search/list results. entityType is optional — if omitted it is read from the file.',
85
102
  parameters: T.Object({
86
103
  repo: T.String({ description: 'Repository name' }),
87
- entityType: T.String({ description: 'Entity type' }),
104
+ entityType: T.Optional(T.String({ description: 'Entity type (optional — resolved from frontmatter if omitted)' })),
88
105
  entityId: T.String({ description: 'Entity ID' }),
89
106
  }),
90
107
  execute: async (toolCallId, params) => {
91
108
  try {
92
109
  const graph = workspaceManager.getGraph(params.repo);
93
- const entity = graph.get(params.entityType, params.entityId);
110
+ const entity = params.entityType
111
+ ? graph.get(params.entityType, params.entityId)
112
+ : graph.getById(params.entityId);
94
113
  return wrapToolResult({
95
114
  success: true,
96
115
  entity: {
97
- id: entity.id,
98
- type: entity.entityType,
116
+ entityId: entity.id,
117
+ entityType: entity.entityType,
118
+ repo: params.repo,
99
119
  path: entity.path,
100
- data: entity.data,
120
+ data: cleanData(entity.data),
101
121
  content: entity.document.content,
102
122
  wikilinks: entity.document.wikilinks,
103
123
  },
@@ -115,9 +135,9 @@ export function createGraphTools(workspaceManager, gitUser) {
115
135
  {
116
136
  name: 'update_entity',
117
137
  label: 'Update Entity',
118
- description: 'Update an existing entity',
138
+ description: 'Update an existing entity. Repo is auto-resolved for app-defined types.',
119
139
  parameters: T.Object({
120
- repo: T.String({ description: 'Repository name' }),
140
+ repo: T.Optional(T.String({ description: 'Repository name (auto-resolved for app entity types)' })),
121
141
  entityType: T.String({ description: 'Entity type' }),
122
142
  entityId: T.String({ description: 'Entity ID' }),
123
143
  data: T.Optional(T.Object({}, { description: 'Updated data fields', additionalProperties: true })),
@@ -126,7 +146,13 @@ export function createGraphTools(workspaceManager, gitUser) {
126
146
  }),
127
147
  execute: async (toolCallId, params) => {
128
148
  try {
129
- const graph = workspaceManager.getGraph(params.repo);
149
+ let repoName = params.repo;
150
+ if (!repoName) {
151
+ repoName = workspaceManager.getRepoForEntityType(params.entityType);
152
+ if (!repoName)
153
+ return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
154
+ }
155
+ const graph = workspaceManager.getGraph(repoName);
130
156
  // Add update metadata
131
157
  const dataWithMeta = params.data
132
158
  ? {
@@ -135,21 +161,26 @@ export function createGraphTools(workspaceManager, gitUser) {
135
161
  updated_by: gitUser.id,
136
162
  }
137
163
  : undefined;
164
+ // Sanitize double-escaped newlines from LLM JSON output
165
+ const sanitizedContent = params.content !== undefined
166
+ ? params.content.replace(/\\n/g, '\n') : params.content;
138
167
  const entity = await graph.update({
139
168
  entityType: params.entityType,
140
169
  entityId: params.entityId,
141
170
  data: dataWithMeta,
142
- content: params.content,
171
+ content: sanitizedContent,
143
172
  commitMessage: params.commitMessage,
144
173
  });
174
+ onMutation?.({ action: 'updated', repo: repoName, entityType: params.entityType, entityId: params.entityId });
145
175
  return wrapToolResult({
146
176
  success: true,
147
177
  entity: {
148
- id: entity.id,
149
- type: entity.entityType,
150
- data: entity.data,
178
+ entityId: entity.id,
179
+ entityType: entity.entityType,
180
+ repo: repoName,
181
+ data: cleanData(entity.data),
151
182
  },
152
- message: `Updated ${params.entityType}: ${params.entityId}`,
183
+ message: `Updated ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
153
184
  });
154
185
  }
155
186
  catch (error) {
@@ -164,20 +195,71 @@ export function createGraphTools(workspaceManager, gitUser) {
164
195
  {
165
196
  name: 'delete_entity',
166
197
  label: 'Delete Entity',
167
- description: 'Delete an entity. Use with caution!',
198
+ description: 'Delete an entity. Use with caution! Repo is auto-resolved for app-defined types.',
168
199
  parameters: T.Object({
169
- repo: T.String({ description: 'Repository name' }),
200
+ repo: T.Optional(T.String({ description: 'Repository name (auto-resolved for app entity types)' })),
170
201
  entityType: T.String({ description: 'Entity type' }),
171
202
  entityId: T.String({ description: 'Entity ID' }),
172
203
  commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
173
204
  }),
174
205
  execute: async (toolCallId, params) => {
175
206
  try {
176
- const graph = workspaceManager.getGraph(params.repo);
207
+ let repoName = params.repo;
208
+ if (!repoName) {
209
+ repoName = workspaceManager.getRepoForEntityType(params.entityType);
210
+ if (!repoName)
211
+ return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
212
+ }
213
+ const graph = workspaceManager.getGraph(repoName);
177
214
  await graph.delete(params.entityType, params.entityId, params.commitMessage);
215
+ onMutation?.({ action: 'deleted', repo: repoName, entityType: params.entityType, entityId: params.entityId });
178
216
  return wrapToolResult({
179
217
  success: true,
180
- message: `Deleted ${params.entityType}: ${params.entityId}`,
218
+ message: `Deleted ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
219
+ });
220
+ }
221
+ catch (error) {
222
+ return wrapToolResult({
223
+ success: false,
224
+ error: error instanceof Error ? error.message : 'Unknown error',
225
+ });
226
+ }
227
+ },
228
+ },
229
+ // Move entity between repos
230
+ {
231
+ name: 'move_entity',
232
+ label: 'Move Entity',
233
+ description: 'Move an entity from one repository to another. Preserves all data, content, and wikilinks.',
234
+ parameters: T.Object({
235
+ sourceRepo: T.String({ description: 'Source repository name' }),
236
+ targetRepo: T.String({ description: 'Target repository name' }),
237
+ entityType: T.String({ description: 'Entity type' }),
238
+ entityId: T.String({ description: 'Entity ID' }),
239
+ commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
240
+ }),
241
+ execute: async (toolCallId, params) => {
242
+ try {
243
+ const sourceGraph = workspaceManager.getGraph(params.sourceRepo);
244
+ const targetGraph = workspaceManager.getGraph(params.targetRepo);
245
+ // Read the full entity from source
246
+ const entity = sourceGraph.get(params.entityType, params.entityId);
247
+ // Create in target repo
248
+ const now = new Date().toISOString();
249
+ await targetGraph.create({
250
+ entityType: params.entityType,
251
+ entityId: params.entityId,
252
+ data: { ...entity.data, updated_at: now, updated_by: gitUser.id },
253
+ content: entity.document.content || '',
254
+ commitMessage: params.commitMessage || `Move ${params.entityType} ${params.entityId} from ${params.sourceRepo} to ${params.targetRepo}`,
255
+ });
256
+ // Delete from source repo
257
+ await sourceGraph.delete(params.entityType, params.entityId, `Move ${params.entityType} ${params.entityId} to ${params.targetRepo}`);
258
+ onMutation?.({ action: 'deleted', repo: params.sourceRepo, entityType: params.entityType, entityId: params.entityId });
259
+ onMutation?.({ action: 'created', repo: params.targetRepo, entityType: params.entityType, entityId: params.entityId });
260
+ return wrapToolResult({
261
+ success: true,
262
+ message: `Moved ${params.entityType}: ${params.entityId} from ${params.sourceRepo} to ${params.targetRepo}. Changes were auto-committed in both repos — ready to push.`,
181
263
  });
182
264
  }
183
265
  catch (error) {
@@ -192,7 +274,7 @@ export function createGraphTools(workspaceManager, gitUser) {
192
274
  {
193
275
  name: 'search_entities',
194
276
  label: 'Search Entities',
195
- description: 'Search for entities across repositories with filters',
277
+ description: 'Search for entities across repositories with filters. Note: source configs, sync settings, and connector configs are NOT entities — use sync_list_sources for those.',
196
278
  parameters: T.Object({
197
279
  query: T.Optional(T.String({ description: 'Search query (full-text)' })),
198
280
  entityType: T.Optional(T.String({ description: 'Filter by entity type' })),
@@ -223,9 +305,9 @@ export function createGraphTools(workspaceManager, gitUser) {
223
305
  count: results.length,
224
306
  results: results.map(r => ({
225
307
  repo: r.repoName,
226
- id: r.id,
227
- type: r.entityType,
228
- data: r.data,
308
+ entityId: r.id,
309
+ entityType: r.entityType,
310
+ data: cleanData(r.data),
229
311
  })),
230
312
  });
231
313
  }
@@ -254,9 +336,9 @@ export function createGraphTools(workspaceManager, gitUser) {
254
336
  count: results.length,
255
337
  results: results.map(r => ({
256
338
  repo: r.repoName,
257
- id: r.id,
258
- type: r.entityType,
259
- data: r.data,
339
+ entityId: r.id,
340
+ entityType: r.entityType,
341
+ data: cleanData(r.data),
260
342
  })),
261
343
  });
262
344
  }
@@ -272,7 +354,7 @@ export function createGraphTools(workspaceManager, gitUser) {
272
354
  {
273
355
  name: 'get_related',
274
356
  label: 'Get Related Entities',
275
- description: 'Get entities related to a given entity via wikilinks (cross-repo supported)',
357
+ description: 'Get entities related to a given entity via wikilinks (cross-repo supported). Pass repo, entityType, entityId from search/list results.',
276
358
  parameters: T.Object({
277
359
  repo: T.String({ description: 'Repository name' }),
278
360
  entityType: T.String({ description: 'Entity type' }),
@@ -286,9 +368,9 @@ export function createGraphTools(workspaceManager, gitUser) {
286
368
  count: related.length,
287
369
  related: related.map(r => ({
288
370
  repo: r.repoName,
289
- id: r.id,
290
- type: r.entityType,
291
- data: r.data,
371
+ entityId: r.id,
372
+ entityType: r.entityType,
373
+ data: cleanData(r.data),
292
374
  })),
293
375
  });
294
376
  }
@@ -304,7 +386,7 @@ export function createGraphTools(workspaceManager, gitUser) {
304
386
  {
305
387
  name: 'get_backlinks',
306
388
  label: 'Get Backlinks',
307
- description: 'Get entities that link to a given entity (cross-repo supported)',
389
+ description: 'Get entities that link to a given entity (cross-repo supported). Pass repo, entityType, entityId from search/list results.',
308
390
  parameters: T.Object({
309
391
  repo: T.String({ description: 'Repository name' }),
310
392
  entityType: T.String({ description: 'Entity type' }),
@@ -318,9 +400,9 @@ export function createGraphTools(workspaceManager, gitUser) {
318
400
  count: backlinks.length,
319
401
  backlinks: backlinks.map(r => ({
320
402
  repo: r.repoName,
321
- id: r.id,
322
- type: r.entityType,
323
- data: r.data,
403
+ entityId: r.id,
404
+ entityType: r.entityType,
405
+ data: cleanData(r.data),
324
406
  })),
325
407
  });
326
408
  }
@@ -587,6 +669,72 @@ export function createGraphTools(workspaceManager, gitUser) {
587
669
  }
588
670
  },
589
671
  },
672
+ // Find orphan entities
673
+ {
674
+ name: 'find_orphans',
675
+ label: 'Find Orphans',
676
+ description: 'Find entities with zero inbound wikilink references. Optionally tombstone them to exclude from future syncs.',
677
+ parameters: T.Object({
678
+ entityTypes: T.Optional(T.Array(T.String(), { description: 'Entity types to check (e.g. ["person", "client"])' })),
679
+ minAgeDays: T.Optional(T.Number({ description: 'Only flag entities older than N days' })),
680
+ repos: T.Optional(T.Array(T.String(), { description: 'Repo names to scan (default: all)' })),
681
+ tombstone: T.Optional(T.Boolean({ description: 'Add orphans to sync-state tombstones' })),
682
+ }),
683
+ execute: async (toolCallId, params) => {
684
+ try {
685
+ const result = findOrphans(workspaceManager, {
686
+ entityTypes: params.entityTypes,
687
+ minAgeDays: params.minAgeDays,
688
+ repos: params.repos,
689
+ });
690
+ // Tombstone if requested
691
+ if (params.tombstone && workspacePath && result.orphans.length > 0) {
692
+ const syncState = new SyncStateManager(workspacePath);
693
+ for (const orphan of result.orphans) {
694
+ syncState.addTombstone(orphan.entityId);
695
+ }
696
+ }
697
+ // Group by type for summary
698
+ const byType = {};
699
+ for (const o of result.orphans) {
700
+ byType[o.entityType] = (byType[o.entityType] || 0) + 1;
701
+ }
702
+ return wrapToolResult({
703
+ success: true,
704
+ totalScanned: result.totalScanned,
705
+ totalOrphans: result.totalOrphans,
706
+ tombstoned: params.tombstone ? result.totalOrphans : 0,
707
+ byType,
708
+ orphans: result.orphans.slice(0, 50), // limit response size
709
+ });
710
+ }
711
+ catch (error) {
712
+ return wrapToolResult({
713
+ success: false,
714
+ error: error instanceof Error ? error.message : 'Unknown error',
715
+ });
716
+ }
717
+ },
718
+ },
719
+ // Highlight entities in graph view
720
+ {
721
+ name: 'highlight_entities',
722
+ label: 'Highlight Entities',
723
+ description: 'Highlight specific entities in the graph view. Pass entity IDs to highlight them (dimming all others). Pass an empty array to clear highlights.',
724
+ parameters: T.Object({
725
+ entityIds: T.Array(T.String(), { description: 'Entity IDs to highlight in the graph' }),
726
+ }),
727
+ execute: async (_toolCallId, params) => {
728
+ onHighlight?.(params.entityIds);
729
+ const count = params.entityIds.length;
730
+ return wrapToolResult({
731
+ highlighted: count,
732
+ message: count > 0
733
+ ? `Highlighted ${count} entities in the graph.`
734
+ : 'Cleared graph highlights.',
735
+ });
736
+ },
737
+ },
590
738
  ];
591
739
  }
592
740
  //# sourceMappingURL=graph-tools.js.map