@anchrd/intel 0.59.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 (364) hide show
  1. package/README.md +496 -0
  2. package/bin/intel.mjs +134 -0
  3. package/dist/adapters/cloudflare/cloudflare-flow-workflow.d.ts +42 -0
  4. package/dist/adapters/cloudflare/cloudflare-flow-workflow.js +89 -0
  5. package/dist/adapters/cloudflare/cloudflare.d.ts +29 -0
  6. package/dist/adapters/cloudflare/cloudflare.js +416 -0
  7. package/dist/adapters/cloudflare/cloudflare.types.d.ts +31 -0
  8. package/dist/adapters/cloudflare/cloudflare.types.js +1 -0
  9. package/dist/adapters/content/content.d.ts +3 -0
  10. package/dist/adapters/content/content.js +128 -0
  11. package/dist/adapters/content/content.types.d.ts +38 -0
  12. package/dist/adapters/content/content.types.js +1 -0
  13. package/dist/adapters/db/db-audit.d.ts +62 -0
  14. package/dist/adapters/db/db-audit.js +150 -0
  15. package/dist/adapters/db/db-boards.d.ts +6 -0
  16. package/dist/adapters/db/db-boards.js +324 -0
  17. package/dist/adapters/db/db-feed.d.ts +30 -0
  18. package/dist/adapters/db/db-feed.js +276 -0
  19. package/dist/adapters/db/db-flows.d.ts +42 -0
  20. package/dist/adapters/db/db-flows.js +1311 -0
  21. package/dist/adapters/db/db-grants.d.ts +133 -0
  22. package/dist/adapters/db/db-grants.js +269 -0
  23. package/dist/adapters/db/db-indexing.d.ts +3 -0
  24. package/dist/adapters/db/db-indexing.js +200 -0
  25. package/dist/adapters/db/db-oauth.d.ts +3 -0
  26. package/dist/adapters/db/db-oauth.js +26 -0
  27. package/dist/adapters/db/db-prompts.d.ts +46 -0
  28. package/dist/adapters/db/db-prompts.js +144 -0
  29. package/dist/adapters/db/db.d.ts +6 -0
  30. package/dist/adapters/db/db.js +1687 -0
  31. package/dist/adapters/db/db.types.d.ts +16 -0
  32. package/dist/adapters/db/db.types.js +1 -0
  33. package/dist/adapters/document-converter/document-converter.d.ts +2 -0
  34. package/dist/adapters/document-converter/document-converter.js +26 -0
  35. package/dist/adapters/document-converter/document-converter.types.d.ts +17 -0
  36. package/dist/adapters/document-converter/document-converter.types.js +1 -0
  37. package/dist/adapters/flow-runtime/flow-runtime.d.ts +3 -0
  38. package/dist/adapters/flow-runtime/flow-runtime.js +22 -0
  39. package/dist/adapters/flow-runtime/flow-runtime.types.d.ts +19 -0
  40. package/dist/adapters/flow-runtime/flow-runtime.types.js +1 -0
  41. package/dist/adapters/index-queue/index-queue.d.ts +10 -0
  42. package/dist/adapters/index-queue/index-queue.js +12 -0
  43. package/dist/adapters/index-queue/index-queue.types.d.ts +11 -0
  44. package/dist/adapters/index-queue/index-queue.types.js +1 -0
  45. package/dist/adapters/json-schema/json-schema.d.ts +2 -0
  46. package/dist/adapters/json-schema/json-schema.js +77 -0
  47. package/dist/adapters/openid/openid.d.ts +5 -0
  48. package/dist/adapters/openid/openid.js +301 -0
  49. package/dist/adapters/portal-tokens/portal-tokens.d.ts +8 -0
  50. package/dist/adapters/portal-tokens/portal-tokens.js +79 -0
  51. package/dist/adapters/remote-tools/remote-tools.d.ts +5 -0
  52. package/dist/adapters/remote-tools/remote-tools.js +129 -0
  53. package/dist/adapters/semantic-index/semantic-index.d.ts +2 -0
  54. package/dist/adapters/semantic-index/semantic-index.js +139 -0
  55. package/dist/adapters/semantic-index/semantic-index.types.d.ts +56 -0
  56. package/dist/adapters/semantic-index/semantic-index.types.js +1 -0
  57. package/dist/adapters/session-cookie/session-cookie.d.ts +5 -0
  58. package/dist/adapters/session-cookie/session-cookie.js +87 -0
  59. package/dist/adapters/tool-source-policy/tool-source-policy.d.ts +1 -0
  60. package/dist/adapters/tool-source-policy/tool-source-policy.js +22 -0
  61. package/dist/audit/audit.d.ts +2 -0
  62. package/dist/audit/audit.js +87 -0
  63. package/dist/audit/audit.types.d.ts +23 -0
  64. package/dist/audit/audit.types.js +1 -0
  65. package/dist/auth/auth.d.ts +2 -0
  66. package/dist/auth/auth.js +284 -0
  67. package/dist/auth/auth.types.d.ts +108 -0
  68. package/dist/auth/auth.types.js +1 -0
  69. package/dist/boards/boards.d.ts +44 -0
  70. package/dist/boards/boards.js +447 -0
  71. package/dist/boards/boards.types.d.ts +117 -0
  72. package/dist/boards/boards.types.js +1 -0
  73. package/dist/build/build.d.ts +2 -0
  74. package/dist/build/build.js +192 -0
  75. package/dist/build/build.types.d.ts +17 -0
  76. package/dist/build/build.types.js +1 -0
  77. package/dist/bundle/bundle.d.ts +4 -0
  78. package/dist/bundle/bundle.js +1194 -0
  79. package/dist/bundle/bundle.types.d.ts +33 -0
  80. package/dist/bundle/bundle.types.js +1 -0
  81. package/dist/cli/cli.d.ts +4 -0
  82. package/dist/cli/cli.js +262 -0
  83. package/dist/cli/cli.types.d.ts +14 -0
  84. package/dist/cli/cli.types.js +1 -0
  85. package/dist/contract/audit.d.ts +50 -0
  86. package/dist/contract/audit.js +72 -0
  87. package/dist/contract/board.d.ts +150 -0
  88. package/dist/contract/board.js +262 -0
  89. package/dist/contract/bundle.d.ts +147 -0
  90. package/dist/contract/bundle.js +139 -0
  91. package/dist/contract/contract.d.ts +112 -0
  92. package/dist/contract/contract.js +143 -0
  93. package/dist/contract/feed.d.ts +126 -0
  94. package/dist/contract/feed.js +149 -0
  95. package/dist/contract/flow-run.d.ts +346 -0
  96. package/dist/contract/flow-run.js +194 -0
  97. package/dist/contract/flow.d.ts +1057 -0
  98. package/dist/contract/flow.js +552 -0
  99. package/dist/contract/node.d.ts +551 -0
  100. package/dist/contract/node.js +456 -0
  101. package/dist/contract/share.d.ts +216 -0
  102. package/dist/contract/share.js +134 -0
  103. package/dist/contract/table.d.ts +171 -0
  104. package/dist/contract/table.js +117 -0
  105. package/dist/contract/tool.d.ts +122 -0
  106. package/dist/contract/tool.js +172 -0
  107. package/dist/feed/feed.d.ts +2 -0
  108. package/dist/feed/feed.js +77 -0
  109. package/dist/feed/feed.types.d.ts +23 -0
  110. package/dist/feed/feed.types.js +1 -0
  111. package/dist/flows/flows.d.ts +41 -0
  112. package/dist/flows/flows.js +2216 -0
  113. package/dist/flows/flows.types.d.ts +339 -0
  114. package/dist/flows/flows.types.js +1 -0
  115. package/dist/http/http.d.ts +9 -0
  116. package/dist/http/http.js +874 -0
  117. package/dist/http/http.types.d.ts +22 -0
  118. package/dist/http/http.types.js +1 -0
  119. package/dist/indexing/indexing.d.ts +6 -0
  120. package/dist/indexing/indexing.js +239 -0
  121. package/dist/indexing/indexing.types.d.ts +11 -0
  122. package/dist/indexing/indexing.types.js +1 -0
  123. package/dist/intel/intel.d.ts +3 -0
  124. package/dist/intel/intel.js +194 -0
  125. package/dist/intel/intel.types.d.ts +24 -0
  126. package/dist/intel/intel.types.js +1 -0
  127. package/dist/mcp/mcp.d.ts +2 -0
  128. package/dist/mcp/mcp.js +1292 -0
  129. package/dist/mcp/mcp.types.d.ts +25 -0
  130. package/dist/mcp/mcp.types.js +1 -0
  131. package/dist/nodes/document-links/document-links.d.ts +20 -0
  132. package/dist/nodes/document-links/document-links.js +57 -0
  133. package/dist/nodes/nodes.d.ts +2 -0
  134. package/dist/nodes/nodes.js +1667 -0
  135. package/dist/nodes/nodes.types.d.ts +511 -0
  136. package/dist/nodes/nodes.types.js +1 -0
  137. package/dist/prepare/prepare.d.ts +4 -0
  138. package/dist/prepare/prepare.js +16 -0
  139. package/dist/prepare/prepare.types.d.ts +9 -0
  140. package/dist/prepare/prepare.types.js +1 -0
  141. package/dist/prompts/prompts.d.ts +2 -0
  142. package/dist/prompts/prompts.js +65 -0
  143. package/dist/prompts/prompts.types.d.ts +71 -0
  144. package/dist/prompts/prompts.types.js +1 -0
  145. package/dist/shared/callers/callers.d.ts +28 -0
  146. package/dist/shared/callers/callers.js +30 -0
  147. package/dist/shared/csv/csv.d.ts +13 -0
  148. package/dist/shared/csv/csv.js +85 -0
  149. package/dist/shared/document-text/document-text.d.ts +21 -0
  150. package/dist/shared/document-text/document-text.js +31 -0
  151. package/dist/shared/gate-authorization/gate-authorization.d.ts +5 -0
  152. package/dist/shared/gate-authorization/gate-authorization.js +26 -0
  153. package/dist/shared/grant-expiry/grant-expiry.d.ts +19 -0
  154. package/dist/shared/grant-expiry/grant-expiry.js +26 -0
  155. package/dist/shared/intel-error/intel-error.d.ts +22 -0
  156. package/dist/shared/intel-error/intel-error.js +27 -0
  157. package/dist/shared/plain-title/plain-title.d.ts +16 -0
  158. package/dist/shared/plain-title/plain-title.js +45 -0
  159. package/dist/shared/problem-details/problem-details.d.ts +30 -0
  160. package/dist/shared/problem-details/problem-details.js +18 -0
  161. package/dist/shared/report-unexpected-error/report-unexpected-error.d.ts +1 -0
  162. package/dist/shared/report-unexpected-error/report-unexpected-error.js +37 -0
  163. package/dist/shared/safe-return-path/safe-return-path.d.ts +2 -0
  164. package/dist/shared/safe-return-path/safe-return-path.js +11 -0
  165. package/dist/shared/sha256/sha256.d.ts +2 -0
  166. package/dist/shared/sha256/sha256.js +14 -0
  167. package/dist/tools/tool-servers/tool-servers.d.ts +46 -0
  168. package/dist/tools/tool-servers/tool-servers.js +177 -0
  169. package/dist/tools/tools.d.ts +2 -0
  170. package/dist/tools/tools.js +207 -0
  171. package/dist/tools/tools.types.d.ts +56 -0
  172. package/dist/tools/tools.types.js +1 -0
  173. package/examples/branding/favicon.svg +5 -0
  174. package/examples/branding/logo.svg +5 -0
  175. package/examples/branding/theme.css +16 -0
  176. package/examples/dev.vars.example +7 -0
  177. package/examples/intel.json +9 -0
  178. package/migrations/0000_intel_foundation.sql +203 -0
  179. package/migrations/0001_portal_native_tools.sql +21 -0
  180. package/migrations/0002_flows_in_the_knowledge_tree.sql +34 -0
  181. package/migrations/0003_folder_permissions.sql +211 -0
  182. package/migrations/0004_subflow_runs.sql +14 -0
  183. package/migrations/0005_flow_node_cleanup.sql +28 -0
  184. package/migrations/0005_tables_in_the_knowledge_tree.sql +68 -0
  185. package/migrations/0006_links_are_written_in_the_text.sql +20 -0
  186. package/migrations/0007_no_node_waits.sql +69 -0
  187. package/migrations/0008_three_layers.sql +130 -0
  188. package/migrations/0009_no_context_policy.sql +48 -0
  189. package/migrations/0010_no_run_waits_a_year.sql +27 -0
  190. package/migrations/0011_one_name_for_the_tree.sql +53 -0
  191. package/migrations/0012_table_snapshots.sql +29 -0
  192. package/migrations/0017_a_vector_per_card.sql +38 -0
  193. package/migrations/0018_no_context_policy_at_last.sql +97 -0
  194. package/migrations/0019_one_name_for_the_grants.sql +52 -0
  195. package/migrations/0020_cascade_purge_replay.sql +11 -0
  196. package/migrations/0021_a_flow_carries_its_own_grant.sql +44 -0
  197. package/migrations/0022_a_cursor_over_the_journal.sql +14 -0
  198. package/migrations/0023_a_board_and_its_tasks.sql +116 -0
  199. package/migrations/0024_the_archive_is_a_column.sql +33 -0
  200. package/migrations/0025_archiving_takes_the_subtree.sql +29 -0
  201. package/migrations/0026_one_feed_over_two_kinds.sql +23 -0
  202. package/migrations/0027_the_runs_of_every_flow.sql +27 -0
  203. package/migrations/0028_a_prompt_name_over_two_kinds.sql +70 -0
  204. package/package.json +118 -0
  205. package/src/contract/CLAUDE.md +152 -0
  206. package/src/contract/README.md +102 -0
  207. package/src/contract/audit.ts +85 -0
  208. package/src/contract/board.ts +306 -0
  209. package/src/contract/bundle.ts +157 -0
  210. package/src/contract/contract.ts +161 -0
  211. package/src/contract/feed.ts +165 -0
  212. package/src/contract/flow-run.ts +241 -0
  213. package/src/contract/flow.ts +675 -0
  214. package/src/contract/node.ts +583 -0
  215. package/src/contract/share.ts +196 -0
  216. package/src/contract/table.ts +178 -0
  217. package/src/contract/tool.ts +202 -0
  218. package/ui/README.md +110 -0
  219. package/ui/components.json +21 -0
  220. package/ui/index.html +13 -0
  221. package/ui/package.json +11 -0
  222. package/ui/scripts/lint-tokens.mjs +187 -0
  223. package/ui/src/access-summary/access-summary.tsx +385 -0
  224. package/ui/src/app/action-slot/action-slot.tsx +27 -0
  225. package/ui/src/app/app-sidebar/app-sidebar.tsx +71 -0
  226. package/ui/src/app/app-tree/app-tree.tsx +1175 -0
  227. package/ui/src/app/app.tsx +87 -0
  228. package/ui/src/app/header-search/header-search.tsx +294 -0
  229. package/ui/src/app/reindex-dialog/reindex-dialog.tsx +79 -0
  230. package/ui/src/app/settings-dialog/settings-dialog.tsx +135 -0
  231. package/ui/src/app/sidebar-preferences/sidebar-preferences.ts +68 -0
  232. package/ui/src/app/sidebar-preferences/sidebar-preferences.types.ts +15 -0
  233. package/ui/src/app/sidebar-resize-handle/sidebar-resize-handle.tsx +86 -0
  234. package/ui/src/app/tree-expansion/tree-expansion.ts +107 -0
  235. package/ui/src/app/tree-expansion/tree-expansion.types.ts +31 -0
  236. package/ui/src/app/tree-move/tree-move.tsx +427 -0
  237. package/ui/src/app/tree-reveal/tree-reveal.ts +64 -0
  238. package/ui/src/app/tree-reveal/tree-reveal.types.ts +16 -0
  239. package/ui/src/app/user-footer/user-footer.tsx +188 -0
  240. package/ui/src/app/view-menu/view-menu.tsx +115 -0
  241. package/ui/src/app-root/app-root.tsx +109 -0
  242. package/ui/src/app-root/app-root.types.ts +27 -0
  243. package/ui/src/archive/archive.tsx +417 -0
  244. package/ui/src/attachment-detail/attachment-detail.ts +52 -0
  245. package/ui/src/attachment-viewer/attachment-viewer.tsx +166 -0
  246. package/ui/src/blocknote-view/blocknote-view.tsx +30 -0
  247. package/ui/src/board/board-assignee/board-assignee-picker.tsx +132 -0
  248. package/ui/src/board/board-assignee/board-assignee.ts +48 -0
  249. package/ui/src/board/board-assignee/board-assignee.tsx +75 -0
  250. package/ui/src/board/board-chip/board-chip.tsx +46 -0
  251. package/ui/src/board/board-crumbs/board-crumbs.ts +56 -0
  252. package/ui/src/board/board-crumbs/board-crumbs.tsx +111 -0
  253. package/ui/src/board/board-data/board-data.ts +195 -0
  254. package/ui/src/board/board-data/board-data.types.ts +38 -0
  255. package/ui/src/board/board-dates/board-dates.ts +40 -0
  256. package/ui/src/board/board-dates/board-dates.tsx +105 -0
  257. package/ui/src/board/board-kanban/board-kanban.ts +162 -0
  258. package/ui/src/board/board-kanban/board-kanban.tsx +680 -0
  259. package/ui/src/board/board-open-task/board-open-task.ts +32 -0
  260. package/ui/src/board/board-panel/board-panel.tsx +259 -0
  261. package/ui/src/board/board-settings/board-settings.tsx +226 -0
  262. package/ui/src/board/board-status/board-status.tsx +60 -0
  263. package/ui/src/board/board-stripes/board-stripes.ts +128 -0
  264. package/ui/src/board/board-table/board-table.ts +53 -0
  265. package/ui/src/board/board-table/board-table.tsx +610 -0
  266. package/ui/src/board/board-task/board-task.ts +108 -0
  267. package/ui/src/board/board-task/board-task.tsx +335 -0
  268. package/ui/src/board/board-title-row/board-title-row.tsx +66 -0
  269. package/ui/src/branding/branding.tsx +17 -0
  270. package/ui/src/branding/custom-logo.ts +1 -0
  271. package/ui/src/branding/favicon.default.svg +5 -0
  272. package/ui/src/branding/favicon.svg +5 -0
  273. package/ui/src/components/ui/avatar.tsx +39 -0
  274. package/ui/src/components/ui/button.tsx +64 -0
  275. package/ui/src/components/ui/collapsible.tsx +20 -0
  276. package/ui/src/components/ui/command.tsx +160 -0
  277. package/ui/src/components/ui/dialog.tsx +143 -0
  278. package/ui/src/components/ui/dropdown-menu.tsx +187 -0
  279. package/ui/src/components/ui/input.tsx +21 -0
  280. package/ui/src/components/ui/popover.tsx +41 -0
  281. package/ui/src/components/ui/select.tsx +163 -0
  282. package/ui/src/components/ui/separator.tsx +26 -0
  283. package/ui/src/components/ui/sheet.tsx +136 -0
  284. package/ui/src/components/ui/sidebar.tsx +693 -0
  285. package/ui/src/components/ui/skeleton.tsx +13 -0
  286. package/ui/src/components/ui/switch.tsx +25 -0
  287. package/ui/src/components/ui/table.tsx +82 -0
  288. package/ui/src/components/ui/tabs.tsx +52 -0
  289. package/ui/src/components/ui/tooltip.tsx +51 -0
  290. package/ui/src/data/intel-data-provider/intel-data-provider.ts +685 -0
  291. package/ui/src/data/intel-data-provider/intel-data-provider.types.ts +266 -0
  292. package/ui/src/data/query-client.ts +18 -0
  293. package/ui/src/data/request-refusal/refusal-notice.tsx +36 -0
  294. package/ui/src/data/request-refusal/request-refusal.ts +51 -0
  295. package/ui/src/data/sign-in/sign-in.ts +97 -0
  296. package/ui/src/data/sign-in/sign-in.types.ts +15 -0
  297. package/ui/src/document-link/document-link.tsx +114 -0
  298. package/ui/src/document-markdown/document-markdown.ts +195 -0
  299. package/ui/src/editor-schema/editor-schema.ts +23 -0
  300. package/ui/src/entry-picker/entry-picker.tsx +238 -0
  301. package/ui/src/feed/feed.tsx +344 -0
  302. package/ui/src/file-preview/file-preview-view.tsx +496 -0
  303. package/ui/src/file-preview/file-preview.tsx +28 -0
  304. package/ui/src/file-preview/pdf-file-preview.tsx +5 -0
  305. package/ui/src/file-preview/presentation-file-preview.tsx +21 -0
  306. package/ui/src/file-preview/spreadsheet-file-preview.tsx +5 -0
  307. package/ui/src/file-preview/word-file-preview.tsx +5 -0
  308. package/ui/src/flow-runs/flow-runs.tsx +238 -0
  309. package/ui/src/flows/flows.tsx +1646 -0
  310. package/ui/src/flows/node-icon/node-icon.ts +34 -0
  311. package/ui/src/flows/node-palette/node-palette.tsx +214 -0
  312. package/ui/src/flows/node-palette/node-palette.types.ts +15 -0
  313. package/ui/src/folder-contents/folder-contents.tsx +321 -0
  314. package/ui/src/folder-index/folder-index.ts +55 -0
  315. package/ui/src/frontmatter/frontmatter.tsx +193 -0
  316. package/ui/src/graph-pane/graph-pane.tsx +53 -0
  317. package/ui/src/hooks/use-mobile.ts +19 -0
  318. package/ui/src/i18n/custom.json +4 -0
  319. package/ui/src/i18n/de.json +609 -0
  320. package/ui/src/i18n/en.json +609 -0
  321. package/ui/src/i18n/es.json +609 -0
  322. package/ui/src/i18n/i18n-context.tsx +65 -0
  323. package/ui/src/i18n/i18n-languages/i18n-languages.ts +83 -0
  324. package/ui/src/i18n/i18n.ts +32 -0
  325. package/ui/src/i18n/i18n.types.ts +49 -0
  326. package/ui/src/kind-icon.ts +97 -0
  327. package/ui/src/lib/utils.ts +6 -0
  328. package/ui/src/main.tsx +68 -0
  329. package/ui/src/modal/modal.tsx +53 -0
  330. package/ui/src/node-details/node-details.tsx +545 -0
  331. package/ui/src/node-editor/node-editor.tsx +304 -0
  332. package/ui/src/node-graph/graph-notice.tsx +21 -0
  333. package/ui/src/node-graph/node-graph.ts +214 -0
  334. package/ui/src/node-graph/node-graph.tsx +295 -0
  335. package/ui/src/node-import/node-import.tsx +418 -0
  336. package/ui/src/node-save-error.ts +46 -0
  337. package/ui/src/node-source/node-source.tsx +128 -0
  338. package/ui/src/node-table/node-table.tsx +107 -0
  339. package/ui/src/nodes/nodes.tsx +240 -0
  340. package/ui/src/rename-resource/rename-resource.ts +80 -0
  341. package/ui/src/resolved-names/resolved-names.tsx +67 -0
  342. package/ui/src/resource-error.ts +33 -0
  343. package/ui/src/resource-menu/resource-menu.tsx +1156 -0
  344. package/ui/src/router/router-context.ts +6 -0
  345. package/ui/src/router/router.tsx +67 -0
  346. package/ui/src/router/router.types.ts +8 -0
  347. package/ui/src/router/selection-search.ts +88 -0
  348. package/ui/src/save-button/save-button.tsx +94 -0
  349. package/ui/src/section-hint/section-hint.tsx +40 -0
  350. package/ui/src/sign-in-refused/sign-in-refused.tsx +35 -0
  351. package/ui/src/styles.css +189 -0
  352. package/ui/src/table-columns/table-columns.tsx +379 -0
  353. package/ui/src/theme/custom.css +1 -0
  354. package/ui/src/theme/theme-context.tsx +89 -0
  355. package/ui/src/theme/theme.ts +70 -0
  356. package/ui/src/time/relative-time.tsx +41 -0
  357. package/ui/src/time/time-context.tsx +78 -0
  358. package/ui/src/time/time.ts +165 -0
  359. package/ui/src/title-row/title-row.tsx +185 -0
  360. package/ui/src/tools/tools.tsx +546 -0
  361. package/ui/src/user-name/user-name.ts +61 -0
  362. package/ui/src/verbatim/verbatim.tsx +68 -0
  363. package/ui/tsconfig.json +17 -0
  364. package/ui/vite.config.ts +129 -0
@@ -0,0 +1,511 @@
1
+ import type { SemanticIndex } from "../adapters/semantic-index/semantic-index.types.js";
2
+ import type { Flow, FlowVersion } from "../contract/flow.js";
3
+ import type { ArchiveNodeInput, CreateNodeInput, ListNodesInput, Node, NodeAttachment, NodeCitation, NodeDocument, NodeGraph, NodeGraphInput, NodeKind, NodeLink, NodeTable, NodeVersion, ResolveNodeLinksInput, ResolveNodeLinksResult, SaveAttachmentBytesInput, SaveAttachmentInput, SaveNodeVersionInput, SearchInput, UpdateNodeInput } from "../contract/node.js";
4
+ import type { ResourceGrant, ResourceGrantList, ResourceVerb, RevokeGrantInput, ShareInput, ShareResult } from "../contract/share.js";
5
+ import type { AppendTableRowsInput, AppendTableRowsResult, DefineTableInput, DeleteTableRowsInput, DeleteTableRowsResult, RedefineTableInput, UpdateTableRowsInput, UpdateTableRowsResult } from "../contract/table.js";
6
+ import type { PromptNameHolder } from "../prompts/prompts.types.js";
7
+ export interface Actor {
8
+ id: string;
9
+ email: string;
10
+ isAdmin?: boolean;
11
+ }
12
+ export interface NewNode {
13
+ node: Node;
14
+ actorId: string;
15
+ idempotencyKey: string;
16
+ auditId: string;
17
+ }
18
+ export interface NewNodeVersion {
19
+ version: NodeVersion;
20
+ actorId: string;
21
+ baseVersionId: string | null;
22
+ idempotencyKey: string;
23
+ auditId: string;
24
+ }
25
+ export interface NewTableVersion {
26
+ version: Omit<NodeVersion, "sequence">;
27
+ actorId: string;
28
+ idempotencyKey: string;
29
+ auditId: string;
30
+ }
31
+ export type SnapshotOperation = "node.table_update" | "node.table_delete" | "node.table_redefine";
32
+ /**
33
+ * One version that replaces the readable state, written only against the state it replaces.
34
+ *
35
+ * ⚠️ With `sequence` and with `baseVersionId`, unlike the table append. A snapshot replaces what is
36
+ * read, so it has to know which state it replaces — the same optimistic concurrency the document
37
+ * save uses, enforced in the same statement that inserts the row (#135).
38
+ *
39
+ */
40
+ export interface NewSnapshotVersion {
41
+ version: NodeVersion;
42
+ actorId: string;
43
+ baseVersionId: string | null;
44
+ operation: SnapshotOperation;
45
+ metadata: Record<string, unknown>;
46
+ idempotencyKey: string;
47
+ auditId: string;
48
+ }
49
+ export interface NodeRepository {
50
+ listVisible(actor: Actor, input: ListNodesInput): Promise<{
51
+ items: Node[];
52
+ withChildren: string[];
53
+ }>;
54
+ listVisibleBounded(actor: Actor, input: {
55
+ parentId: string | null;
56
+ limit: number;
57
+ }): Promise<BoundedChildren>;
58
+ getVisible(actor: Actor, nodeId: string): Promise<Node | null>;
59
+ listVisibleSubtree(actor: Actor, rootId: string | null): Promise<SubtreeNode[]>;
60
+ listVisibleAttachments(actor: Actor, input: {
61
+ limit: number;
62
+ after: string | null;
63
+ }): Promise<Node[]>;
64
+ can(actor: Actor, nodeId: string, verb: ResourceVerb): Promise<boolean>;
65
+ findIdempotentNode(actorId: string, operation: "node.create" | "node.save" | "node.append" | "node.update" | "node.archive" | "node.share" | "node.revoke" | SnapshotOperation, idempotencyKey: string): Promise<string | null>;
66
+ findIdempotentRevocation(actorId: string, idempotencyKey: string): Promise<boolean | null>;
67
+ findSnapshotMetadata(actorId: string, operation: SnapshotOperation, idempotencyKey: string): Promise<Record<string, unknown> | null>;
68
+ insertNode(input: NewNode): Promise<Node>;
69
+ getVersion(versionId: string): Promise<NodeVersion | null>;
70
+ appendVersion(input: NewNodeVersion): Promise<"saved" | "conflict">;
71
+ appendTableVersion(input: NewTableVersion): Promise<NodeVersion>;
72
+ appendSnapshotVersion(input: NewSnapshotVersion): Promise<"saved" | "conflict">;
73
+ listVersionContentKeys(nodeId: string): Promise<string[]>;
74
+ tableHeaderContentKey(nodeId: string): Promise<string | null>;
75
+ listVersions(nodeId: string): Promise<NodeVersion[]>;
76
+ updateNode(input: {
77
+ node: Node;
78
+ baseUpdatedAt: string;
79
+ actorId: string;
80
+ idempotencyKey: string;
81
+ auditId: string;
82
+ }): Promise<"cycle" | "conflict" | "prompt_name_taken" | Node>;
83
+ /**
84
+ * Who holds a slash command name, for the sentence a refused rename gets (#775). `title` is
85
+ * `null` when the holder exists but this actor may not see it — the name is taken either way, and
86
+ * which document it is stays behind the same wall every other read stands behind.
87
+ */
88
+ promptNameHolder(actor: Actor, name: string): Promise<PromptNameHolder | null>;
89
+ archiveNode(input: {
90
+ nodeId: string;
91
+ baseUpdatedAt: string;
92
+ archivedAt: string | null;
93
+ operationId: string;
94
+ updatedAt: string;
95
+ actorId: string;
96
+ idempotencyKey: string;
97
+ auditId: string;
98
+ }): Promise<"conflict" | Node>;
99
+ versionIdsInSubtree(nodeId: string): Promise<string[]>;
100
+ parentArchivedAt(nodeId: string): Promise<{
101
+ archivedAt: string | null;
102
+ kind: string;
103
+ } | null>;
104
+ hasAnyChild(nodeId: string): Promise<boolean>;
105
+ listVectorKeys(nodeId: string): Promise<string[]>;
106
+ countInboundLinks(nodeId: string): Promise<number>;
107
+ inspectPurgeTree(nodeId: string): Promise<{
108
+ nodeIds: string[];
109
+ named: Array<{
110
+ id: string;
111
+ kind: string;
112
+ title: string;
113
+ }>;
114
+ flowIds: string[];
115
+ contentKeys: string[];
116
+ vectorKeys: Array<{
117
+ nodeId: string;
118
+ keys: string[];
119
+ }>;
120
+ counts: Record<string, number>;
121
+ }>;
122
+ findPurgeReplay(actorId: string, idempotencyKey: string): Promise<{
123
+ title: string;
124
+ contentKeys: string[];
125
+ } | null>;
126
+ completePurgeReplay(actorId: string, idempotencyKey: string, completedAt: string): Promise<void>;
127
+ purgeNode(input: {
128
+ nodeId: string;
129
+ actorId: string;
130
+ auditId: string;
131
+ occurredAt: string;
132
+ metadata: Record<string, unknown>;
133
+ idempotencyKey: string;
134
+ }): Promise<"missing" | {
135
+ contentKeys: string[];
136
+ }>;
137
+ listGrants(resourceId: string): Promise<ResourceGrant[]>;
138
+ listEffectiveAccess(resourceId: string): Promise<{
139
+ ownerIds: string[];
140
+ items: ResourceGrant[];
141
+ }>;
142
+ organizationExecuteReaches(nodeId: string, exceptGrantId: string): Promise<boolean>;
143
+ listLinksVisible(actor: Actor, nodeId: string): Promise<NodeLink[]>;
144
+ resolveVisibleTitles(actor: Actor, nodeIds: string[]): Promise<Array<{
145
+ nodeId: string;
146
+ title: string;
147
+ }>>;
148
+ replaceTextLinks(input: {
149
+ sourceNodeId: string;
150
+ links: Array<{
151
+ id: string;
152
+ targetNodeId: string;
153
+ }>;
154
+ actorId: string;
155
+ auditId: string;
156
+ occurredAt: string;
157
+ }): Promise<void>;
158
+ graphVisible(actor: Actor, input: NodeGraphInput): Promise<NodeGraph>;
159
+ setGrant(input: {
160
+ grant: ResourceGrant;
161
+ actorId: string;
162
+ idempotencyKey: string;
163
+ auditId: string;
164
+ }): Promise<ResourceGrant>;
165
+ revokeGrant(input: {
166
+ resourceId: string;
167
+ grantId: string;
168
+ actorId: string;
169
+ idempotencyKey: string;
170
+ auditId: string;
171
+ occurredAt: string;
172
+ }): Promise<boolean>;
173
+ searchVisible(actor: Actor, input: SearchInput): Promise<NodeCitation[]>;
174
+ /**
175
+ * `scopeId` cuts the candidates to one folder subtree, which is how the semantic half of a scoped
176
+ * search is narrowed (#126): the vector index answers over everything and this join is where the
177
+ * subtree — a relation in D1, not a value on a vector — is applied. The ACL still applies too.
178
+ *
179
+ * ⚠️ One entry per node, and it names WHICH chunk answered (anchrd/intel#301). The passage a
180
+ * searcher is shown is then that card rather than whichever one happens to be first in the board;
181
+ * a node whose winning chunk has no `node_vectors` row — every vector written before #301 — falls
182
+ * back on the first full-text passage, which is exactly what this returned before.
183
+ */
184
+ hydrateVisibleCitations(actor: Actor, hits: Array<{
185
+ nodeId: string;
186
+ chunkKey: string;
187
+ }>, scopeId?: string): Promise<NodeCitation[]>;
188
+ invalidateVectors(): Promise<void>;
189
+ listCurrentVersionIds(input: {
190
+ after: string | null;
191
+ limit: number;
192
+ }): Promise<string[]>;
193
+ importTree(input: ImportTreeInput): Promise<"created" | "replayed">;
194
+ findImportReplay(actorId: string, idempotencyKey: string): Promise<Record<string, unknown> | null>;
195
+ }
196
+ export interface ImportedLink {
197
+ id: string;
198
+ sourceNodeId: string;
199
+ targetNodeId: string;
200
+ }
201
+ /**
202
+ * Everything one bundle import creates, as one write (#137).
203
+ *
204
+ * ⚠️ The whole point of this shape is the atomicity: every row lands in one `db.batch`, which D1
205
+ * runs as one transaction, so a partial import cannot exist — either the whole subtree stands or
206
+ * nothing does. The R2 objects behind `versions` are written before and deleted again by the
207
+ * caller when the batch refuses.
208
+ *
209
+ * `nodes` must come parents before children: the tree's foreign key checks each row as it lands.
210
+ */
211
+ export interface ImportTreeInput {
212
+ nodes: Node[];
213
+ versions: NodeVersion[];
214
+ links: ImportedLink[];
215
+ flows: Flow[];
216
+ flowVersions: FlowVersion[];
217
+ actorId: string;
218
+ idempotencyKey: string;
219
+ auditId: string;
220
+ auditResourceId: string;
221
+ metadata: Record<string, unknown>;
222
+ occurredAt: string;
223
+ }
224
+ export interface ContentStore {
225
+ get(key: string): Promise<string | null>;
226
+ getBytes(key: string): Promise<ArrayBuffer | null>;
227
+ getStream(key: string): Promise<ReadableStream<Uint8Array> | null>;
228
+ put(key: string, content: string, mediaType: string): Promise<void>;
229
+ putBytes(key: string, content: ArrayBuffer, mediaType: string): Promise<void>;
230
+ /**
231
+ * One object written from a stream, without the bytes ever standing complete in memory (#821).
232
+ *
233
+ * ⚠️ `size` is not a hint, it is the contract with the caller: exactly that many bytes are
234
+ * expected, and a body that carries more or fewer fails instead of storing a truncated object
235
+ * under a name that claims to be the file. That is what makes a lying `content-length` a refusal
236
+ * rather than a corrupt attachment.
237
+ *
238
+ * ⚠️ It answers with the hash BECAUSE it streams. Nothing downstream can compute one afterwards
239
+ * without reading the object back in whole, which is the memory this method exists to avoid, so
240
+ * the digest is taken as the bytes pass. It is the same hex SHA-256 `hash` produces, and a
241
+ * version written through either door is comparable with the other.
242
+ */
243
+ putStream(key: string, content: ReadableStream<Uint8Array>, mediaType: string, size: number): Promise<{
244
+ size: number;
245
+ hash: string;
246
+ }>;
247
+ delete(key: string): Promise<void>;
248
+ }
249
+ export interface NodeAttachmentBody {
250
+ attachment: NodeAttachment;
251
+ body: ReadableStream<Uint8Array>;
252
+ }
253
+ export interface NodesDeps {
254
+ repository: NodeRepository;
255
+ /**
256
+ * Files a freshly created `task` node on the board it was created under (#648).
257
+ *
258
+ * ⚠️ Optional on purpose, and the optionality is the decision rather than a convenience: the node
259
+ * service is the one path every node takes, including in the CLI and the bundle importer, and
260
+ * neither of those has a board half of the world. A required port would make "create a node" fail
261
+ * where boards are not wired — and the answer to a missing board is that a task keeps its node
262
+ * and gets filed later, never that the node is refused.
263
+ */
264
+ attachToBoard?(actor: Actor, taskId: string, boardId: string, occurredAt: string): Promise<void>;
265
+ /**
266
+ * Which board a task belongs to (#669).
267
+ *
268
+ * ⚠️ Needed since a task may sit under another task: the destination of a move is then not the
269
+ * board itself, and "does this card change boards" cannot be answered from the node row alone.
270
+ *
271
+ * Optional for the same reason as `attachToBoard` — the CLI and the bundle importer have no
272
+ * board half. ⚠️ **Where it is absent, filing a task UNDER a task is refused** rather than
273
+ * allowed unchecked: the rule it would skip is the one that keeps a card from silently changing
274
+ * boards.
275
+ */
276
+ boardOfTask?(actor: Actor, taskId: string): Promise<string | null>;
277
+ content: ContentStore;
278
+ id(): string;
279
+ now(): Date;
280
+ externalFlowCallers(actor: Actor, folderId: string): Promise<{
281
+ visible: string[];
282
+ hidden: number;
283
+ }>;
284
+ flowNodeReferences(actor: Actor, folderId: string): Promise<string[]>;
285
+ /**
286
+ * Published flows that use THIS node as a step (#457).
287
+ *
288
+ * ⚠️ Not the same question as `externalFlowCallers`, and the difference cost a refusal that never
289
+ * fired: that one asks who calls a FLOW filed inside a folder (`kind: "subflow"`,
290
+ * `configuration.flowId`). A flow reads a NODE through a tree-link step (`configuration
291
+ * .resourceId`) — a different graph shape entirely, and the one a deletion breaks at run time, in
292
+ * front of somebody who did not order it.
293
+ */
294
+ flowsUsingNode(actor: Actor, nodeId: string): Promise<{
295
+ visible: string[];
296
+ hidden: number;
297
+ }>;
298
+ /**
299
+ * The handles of the MCP servers this actor reaches through the portal right now (D30).
300
+ *
301
+ * ⚠️ Injected as a live question, never as a stored list. Delegating a server is only allowed to
302
+ * somebody who has it themselves, and "has it" can only be answered by asking the portal at the
303
+ * moment of the save — a mirrored table here would be the permission mirror ADR-0003 removed.
304
+ */
305
+ toolServers(actor: Actor): Promise<string[]>;
306
+ hash(content: string | Uint8Array): Promise<string>;
307
+ indexing: {
308
+ enqueue(versionId: string): Promise<void>;
309
+ };
310
+ semantic?: SemanticIndex | undefined;
311
+ }
312
+ export type FolderAccess = "ok" | "missing" | "not-a-folder" | "forbidden";
313
+ export interface SubtreeNode {
314
+ node: Node;
315
+ version: {
316
+ id: string;
317
+ mediaType: string;
318
+ contentKey: string;
319
+ } | null;
320
+ }
321
+ export interface BoundedChildren {
322
+ items: Node[];
323
+ total: number;
324
+ }
325
+ export interface NodeService {
326
+ list(actor: Actor, input: ListNodesInput): Promise<{
327
+ items: Node[];
328
+ withChildren: string[];
329
+ }>;
330
+ /**
331
+ * One level of the tree as this actor may see it, bounded: at most `limit` current children, and
332
+ * `total` for how many there are. Its caller is the relation graph, which draws a bounded picture
333
+ * and must not read a folder of a thousand documents to do it (#30).
334
+ *
335
+ * ⚠️ `total` counts what passed the visibility predicate and nothing else, or the size a picture
336
+ * reports would become a way of learning that something is filed here.
337
+ */
338
+ childrenBounded(actor: Actor, input: {
339
+ parentId: string | null;
340
+ limit: number;
341
+ }): Promise<BoundedChildren>;
342
+ get(actor: Actor, nodeId: string): Promise<NodeDocument>;
343
+ getVersion(actor: Actor, nodeId: string, versionId: string): Promise<NodeDocument>;
344
+ folderAccess(actor: Actor, folderId: string): Promise<FolderAccess>;
345
+ create(actor: Actor, input: CreateNodeInput): Promise<Node>;
346
+ save(actor: Actor, input: SaveNodeVersionInput): Promise<NodeDocument>;
347
+ saveAttachment(actor: Actor, input: SaveAttachmentInput): Promise<NodeDocument>;
348
+ /**
349
+ * The same act as `saveAttachment`, with the bytes arriving as a stream instead of as base64
350
+ * (#821). It is what the browser uses, and the only door a 50 MB file fits through.
351
+ *
352
+ * ⚠️ Every check happens BEFORE the body is touched — visible, an attachment, writable, and the
353
+ * base version still current. A refusal must not cost 50 MB of transfer, and an unauthorized
354
+ * caller must not learn the difference between "no such node" and "not yours" by how long the
355
+ * upload ran.
356
+ */
357
+ saveAttachmentBytes(actor: Actor, input: SaveAttachmentBytesInput, body: ReadableStream<Uint8Array>): Promise<NodeDocument>;
358
+ getTable(actor: Actor, nodeId: string): Promise<NodeTable>;
359
+ defineTable(actor: Actor, input: DefineTableInput): Promise<NodeTable>;
360
+ appendTableRows(actor: Actor, input: AppendTableRowsInput): Promise<AppendTableRowsResult>;
361
+ updateTableRows(actor: Actor, input: UpdateTableRowsInput): Promise<UpdateTableRowsResult>;
362
+ deleteTableRows(actor: Actor, input: DeleteTableRowsInput): Promise<DeleteTableRowsResult>;
363
+ redefineTable(actor: Actor, input: RedefineTableInput): Promise<NodeTable>;
364
+ getAttachment(actor: Actor, nodeId: string): Promise<NodeAttachment>;
365
+ readAttachment(actor: Actor, nodeId: string): Promise<NodeAttachmentBody>;
366
+ listAttachments(actor: Actor, input: {
367
+ limit: number;
368
+ after: string | null;
369
+ }): Promise<{
370
+ items: Node[];
371
+ nextCursor: string | null;
372
+ }>;
373
+ listVersions(actor: Actor, nodeId: string): Promise<{
374
+ items: NodeVersion[];
375
+ }>;
376
+ update(actor: Actor, input: UpdateNodeInput): Promise<Node>;
377
+ /**
378
+ * Archiving and restoring, for every kind — and for an agent, its Gate Application with it (#182).
379
+ *
380
+ * ⚠️ The Gate call comes FIRST and the node row second. An archived agent whose principal is
381
+ * still live is exactly the access nobody can see any more, so that state must not be reachable
382
+ * by a write that half succeeded; the opposite order can only leave a live agent whose principal
383
+ * is off, which stops working loudly and is repaired by repeating the call.
384
+ */
385
+ archive(actor: Actor, input: ArchiveNodeInput): Promise<Node>;
386
+ purge(actor: Actor, input: {
387
+ nodeId: string;
388
+ idempotencyKey: string;
389
+ }): Promise<{
390
+ purged: true;
391
+ title: string;
392
+ }>;
393
+ purgePreview(actor: Actor, input: {
394
+ nodeId: string;
395
+ }): Promise<{
396
+ inboundLinks: number;
397
+ totalItems: number;
398
+ items: Array<{
399
+ id: string;
400
+ kind: NodeKind;
401
+ title: string;
402
+ }>;
403
+ }>;
404
+ listGrants(actor: Actor, resourceId: string): Promise<ResourceGrantList>;
405
+ listEffectiveAccess(actor: Actor, resourceId: string): Promise<import("../contract/share.js").ResourceAccessList>;
406
+ listLinks(actor: Actor, nodeId: string): Promise<{
407
+ items: NodeLink[];
408
+ }>;
409
+ resolveLinks(actor: Actor, input: ResolveNodeLinksInput): Promise<ResolveNodeLinksResult>;
410
+ graph(actor: Actor, input: NodeGraphInput): Promise<NodeGraph>;
411
+ visibleNode(actor: Actor, nodeId: string): Promise<Node | null>;
412
+ share(actor: Actor, input: ShareInput): Promise<ShareResult>;
413
+ revokeGrant(actor: Actor, input: RevokeGrantInput): Promise<{
414
+ revoked: boolean;
415
+ }>;
416
+ search(actor: Actor, input: SearchInput): Promise<{
417
+ items: NodeCitation[];
418
+ }>;
419
+ reindex(actor: Actor): Promise<{
420
+ queued: number;
421
+ }>;
422
+ }
423
+ export interface NodeIndexTarget {
424
+ nodeId: string;
425
+ versionId: string;
426
+ title: string;
427
+ /**
428
+ * What a person wrote about the node, and it IS indexed (#816).
429
+ *
430
+ * In the full-text row it joins the `content` column beside the title, because it is a sentence
431
+ * about the node rather than a name: `content` is what the query weights at 1.0 and cuts its
432
+ * snippet from, while `title` is weighted at 4.0. In the vector index it goes exactly where the
433
+ * title goes — into the embedded text of the chunk that means the whole node, and nowhere else.
434
+ *
435
+ * ⚠️ Until #816 this comment promised the same thing and the code did none of it: the field was
436
+ * read out of D1, carried here, and then read by nobody. A comment that says the opposite of the
437
+ * code is worse than none, because it is written into on the strength of a search that cannot
438
+ * find it.
439
+ */
440
+ description: string | null;
441
+ contentKeys: string[];
442
+ mediaType: string;
443
+ /**
444
+ * How many bytes the current version carries (#821).
445
+ *
446
+ * ⚠️ It exists so that the indexer can decide about a file WITHOUT reading it. An attachment is
447
+ * read into memory whole and handed to the converter as a blob beside it; at 50 MB that is the
448
+ * isolate's whole budget, and the pass would die at a limit rather than answer. For a table this
449
+ * is the newest segment alone, which is no answer about the table as a whole — the ceiling below
450
+ * is an attachment rule and nothing reads this field for another kind.
451
+ */
452
+ size: number;
453
+ kind: Exclude<NodeKind, "folder">;
454
+ updatedAt: string;
455
+ }
456
+ /**
457
+ * One passage of a node, as the full-text index holds it.
458
+ *
459
+ * ⚠️ A list, and every kind left after #390 puts exactly one in it. It stays a list because the
460
+ * chunked shape is what `node_fts` and `node_vectors` are built around (#285, anchrd/intel#301) —
461
+ * the one thing that would have to be rebuilt to unpick it.
462
+ *
463
+ * `title` is what the passage is called rather than what the node is called: for a task it is the
464
+ * task's own title, which is the text the FTS table weights highest.
465
+ */
466
+ export interface IndexChunk {
467
+ /**
468
+ * What this passage is called inside its node (anchrd/intel#301).
469
+ *
470
+ * `""` for a node that is one passage, which since #390 is every kind. The full-text index does
471
+ * not store it; the vector index is NAMED by it, and that is why it stays: the name written
472
+ * before anchrd/intel#301 is the bare node id, so nothing an installation already holds has to be
473
+ * renamed or embedded again.
474
+ */
475
+ key: string;
476
+ title: string;
477
+ text: string;
478
+ }
479
+ /**
480
+ * What the vector index holds for one chunk of one node (anchrd/intel#301).
481
+ *
482
+ * `fingerprint` is over the exact text that was embedded, so the next pass can tell an untouched
483
+ * card from a changed one without asking Vectorize — whose writes are asynchronous and would answer
484
+ * about the save before last. `passage` is what a searcher is shown when this vector is the hit.
485
+ */
486
+ export interface NodeVectorRecord {
487
+ chunkKey: string;
488
+ fingerprint: string;
489
+ passage: string;
490
+ }
491
+ export interface NodeIndexRepository {
492
+ getTarget(versionId: string): Promise<NodeIndexTarget | null>;
493
+ /**
494
+ * The node behind this version when the reason `getTarget` refused it is that the node has been
495
+ * ARCHIVED — and null for every other reason (anchrd/intel#348).
496
+ *
497
+ * ⚠️ The distinction is the whole method. `getTarget` answers null for two very different
498
+ * situations: the node is archived, or this version has been superseded by a later save. The
499
+ * first one means "take this node out of the vector index"; the second is a queue message that
500
+ * arrived late — the ordinary case, because Cloudflare Queues deliver at least once — and acting
501
+ * on it would delete the vectors of a node that is perfectly alive. So this asks for the archived
502
+ * case by name and never infers it from an absence.
503
+ */
504
+ archivedNodeId(versionId: string): Promise<string | null>;
505
+ replace(target: NodeIndexTarget, chunks: IndexChunk[]): Promise<void>;
506
+ listVectors(nodeId: string): Promise<NodeVectorRecord[]>;
507
+ replaceVectors(target: NodeIndexTarget, records: NodeVectorRecord[]): Promise<void>;
508
+ deleteVectors(nodeId: string): Promise<void>;
509
+ markIndexed(versionId: string, occurredAt: string): Promise<void>;
510
+ markError(versionId: string, message: string, occurredAt: string): Promise<void>;
511
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { PrepareDeps } from "./prepare.types.js";
2
+ export declare function createPrepare(deps: PrepareDeps): {
3
+ prepare(): Promise<number>;
4
+ };
@@ -0,0 +1,16 @@
1
+ export function createPrepare(deps) {
2
+ return {
3
+ async prepare() {
4
+ const location = await deps.resolveMigrations();
5
+ if (!location) {
6
+ deps.log("Error: @anchrd/intel migrations were not found.");
7
+ return 1;
8
+ }
9
+ const temporaryOutDir = `${location.outDir}.tmp`;
10
+ await deps.copyDir(location.dir, temporaryOutDir);
11
+ await deps.replaceDir(temporaryOutDir, location.outDir);
12
+ deps.log(`Intel migrations copied to ${location.outDir}.`);
13
+ return 0;
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,9 @@
1
+ export interface PrepareDeps {
2
+ resolveMigrations(): Promise<{
3
+ dir: string;
4
+ outDir: string;
5
+ } | null>;
6
+ copyDir(from: string, to: string): Promise<void>;
7
+ replaceDir(from: string, to: string): Promise<void>;
8
+ log(message: string): void;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { Prompts, PromptsDeps } from "./prompts.types.js";
2
+ export declare function createPrompts(deps: PromptsDeps): Prompts;
@@ -0,0 +1,65 @@
1
+ import { documentText } from "../shared/document-text/document-text.js";
2
+ import { IntelError } from "../shared/intel-error/intel-error.js";
3
+ /**
4
+ * What a client is handed when it opens the command of a FLOW.
5
+ *
6
+ * ⚠️ **This text starts nothing, and that is the point** (D24: the agent acts, Intel does not).
7
+ * `prompts/get` is a read — a model asked for the wording of a command, not for the command to
8
+ * happen. Returning instructions rather than performing them keeps the one property that makes
9
+ * Intel safe to point a model at: nothing in this package moves because something was READ.
10
+ *
11
+ * ⚠️ It names the `flowId` rather than the prompt name, because the name is not what the next call
12
+ * takes. A model handed "run the flow `crm-outreach`" has to translate that back into an id, and
13
+ * the translation is exactly the step it gets wrong — `flow_run_start` takes an id and refuses a
14
+ * name with a message about the id being unknown.
15
+ */
16
+ function flowInstruction(entry) {
17
+ const description = entry.description === null ? "" : `\n\n${entry.description}`;
18
+ return `Start the Intel flow "${entry.title}" by calling \`flow_run_start\` with \`flowId: "${entry.targetId}"\`. Do not describe the flow instead of starting it, and do not invent a different id: this one is the flow the command \`/${entry.name}\` stands for.${description}`;
19
+ }
20
+ export function createPrompts(deps) {
21
+ return {
22
+ async list(actor) {
23
+ return await deps.repository.listOffered(actor);
24
+ },
25
+ async get(actor, name) {
26
+ const entry = await deps.repository.findOffered(actor, name);
27
+ /**
28
+ * ⚠️ **One refusal for "no such command" and for "not yours to see", and it says the first.**
29
+ * `findOffered` searches the catalogue as this actor sees it, so a document offered under
30
+ * this name inside a folder they may not read is simply absent from it. Two different
31
+ * messages here would make the refusal a way of asking whether a command exists — the same
32
+ * reading of the tree ADR-0004 §3 refuses everywhere else.
33
+ */
34
+ if (entry === null) {
35
+ throw new IntelError(404, "prompt_not_found", "No command by that name is offered to you. `prompts/list` names the ones that are.");
36
+ }
37
+ if (entry.kind === "flow")
38
+ return { entry, text: flowInstruction(entry) };
39
+ const document = await deps.readDocument(actor, entry.targetId);
40
+ /**
41
+ * ⚠️ **A document with no version yet is an EMPTY command, not a failure.** Somebody offered a
42
+ * document they have not written in; the honest answer is the empty instruction they have.
43
+ */
44
+ if (document.version === null || document.content === null)
45
+ return { entry, text: "" };
46
+ /**
47
+ * ⚠️ **What a document node stores is not its text.** The editor writes a BlockNote payload,
48
+ * and handing that on gives a model a JSON blob where its instruction should be — for
49
+ * practically every document written in the app. `documentText` is the same extraction the
50
+ * search index runs, out of the same function, so the words a model is given and the words
51
+ * somebody can search for cannot drift apart.
52
+ */
53
+ const text = documentText(document.version.mediaType, document.content);
54
+ /**
55
+ * ⚠️ And an unreadable payload is REFUSED rather than passed on raw. Half a JSON document as
56
+ * an instruction is the failure this whole finding is about, one step further along: the
57
+ * model would act on it rather than report it.
58
+ */
59
+ if (text === null) {
60
+ throw new IntelError(422, "prompt_unreadable", `The document behind /${entry.name} is not stored in a form this command can be read from. Open it once and save it, or offer a document written in the editor.`);
61
+ }
62
+ return { entry, text };
63
+ },
64
+ };
65
+ }