@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,6 @@
1
+ import { useRouter } from "@tanstack/react-router";
2
+ import type { RouterContext } from "./router.types.ts";
3
+
4
+ export function useIntelRouterContext(): RouterContext {
5
+ return useRouter().options.context as RouterContext;
6
+ }
@@ -0,0 +1,67 @@
1
+ import {
2
+ createRootRouteWithContext,
3
+ createRoute,
4
+ createRouter,
5
+ lazyRouteComponent,
6
+ Navigate,
7
+ } from "@tanstack/react-router";
8
+ import { App } from "@/app/app.tsx";
9
+ import type { RouterContext } from "./router.types.ts";
10
+ import { selectionSearch } from "./selection-search.ts";
11
+
12
+ const rootRoute = createRootRouteWithContext<RouterContext>()({ component: App });
13
+ const redirectRoute = createRoute({
14
+ getParentRoute: () => rootRoute,
15
+ path: "/",
16
+ // The feed shows what just happened, and that is a better start than a pane asking somebody
17
+ // to pick a document first (#813).
18
+ component: () => <Navigate to="/feed" replace />,
19
+ });
20
+ const nodesRoute = createRoute({
21
+ getParentRoute: () => rootRoute,
22
+ path: "/nodes",
23
+ validateSearch: selectionSearch,
24
+ component: lazyRouteComponent(() => import("@/nodes/nodes.tsx"), "Nodes"),
25
+ });
26
+ const flowsRoute = createRoute({
27
+ getParentRoute: () => rootRoute,
28
+ path: "/flows",
29
+ validateSearch: selectionSearch,
30
+ component: lazyRouteComponent(() => import("@/flows/flows.tsx"), "Flows"),
31
+ });
32
+ const feedRoute = createRoute({
33
+ getParentRoute: () => rootRoute,
34
+ path: "/feed",
35
+ component: lazyRouteComponent(() => import("@/feed/feed.tsx"), "Feed"),
36
+ });
37
+
38
+ const archiveRoute = createRoute({
39
+ getParentRoute: () => rootRoute,
40
+ path: "/archive",
41
+ validateSearch: selectionSearch,
42
+ component: lazyRouteComponent(() => import("@/archive/archive.tsx"), "Archive"),
43
+ });
44
+ const toolsRoute = createRoute({
45
+ getParentRoute: () => rootRoute,
46
+ path: "/tools",
47
+ validateSearch: selectionSearch,
48
+ component: lazyRouteComponent(() => import("@/tools/tools.tsx"), "Tools"),
49
+ });
50
+ const routeTree = rootRoute.addChildren([
51
+ redirectRoute,
52
+ nodesRoute,
53
+ flowsRoute,
54
+ toolsRoute,
55
+ feedRoute,
56
+ archiveRoute,
57
+ ]);
58
+
59
+ export function createIntelRouter(context: RouterContext) {
60
+ return createRouter({ routeTree, context });
61
+ }
62
+
63
+ declare module "@tanstack/react-router" {
64
+ interface Register {
65
+ router: ReturnType<typeof createIntelRouter>;
66
+ }
67
+ }
@@ -0,0 +1,8 @@
1
+ import type { IntelDataProvider } from "@/data/intel-data-provider/intel-data-provider.types.ts";
2
+
3
+ // ⚠️ No `i18n` here, and it must not come back (#227). The router context is static: an instance
4
+ // travelling in it can never change, which is why the language was unswitchable before. Text comes
5
+ // from `useI18n()` and from nowhere else — two ways to the same string are two states that drift.
6
+ export interface RouterContext {
7
+ data: IntelDataProvider;
8
+ }
@@ -0,0 +1,88 @@
1
+ // The ways one selected level can be shown, across every surface that has more than one (#818).
2
+ //
3
+ // ⚠️ A surface's FIRST view is its default and rides as the absence of the parameter — `editor` for
4
+ // a document, a folder and a flow, `kanban` for a board. That is what keeps a plain link meaning
5
+ // the editor, as it has since #35, and it is what lets one parameter serve surfaces whose defaults
6
+ // differ: the address says what is NOT the default, and nothing else.
7
+ export const IntelViews = ["editor", "graph", "runs", "kanban", "table", "code"] as const;
8
+ export type IntelView = (typeof IntelViews)[number];
9
+
10
+ // The values the parameter can carry: every view that is nobody's default. Writing them out rather
11
+ // than deriving them from the defaults is deliberate — this list is what the router validates
12
+ // against, and a validator that reads a second list to decide is a validator with two truths.
13
+ const IntelViewParams = ["graph", "runs", "table", "code"] as const;
14
+ export type IntelViewParam = (typeof IntelViewParams)[number];
15
+
16
+ function viewParam(value: unknown): IntelViewParam | null {
17
+ return IntelViewParams.includes(value as IntelViewParam) ? (value as IntelViewParam) : null;
18
+ }
19
+
20
+ export type SelectionSearch = Record<string, unknown> & {
21
+ select?: string;
22
+ view?: IntelViewParam;
23
+ /**
24
+ * The card of the selected board that is open, by its node id.
25
+ *
26
+ * ⚠️ **Beside `select`, not instead of it.** A task is not a level of the tree the sidebar can
27
+ * select; it is something shown INSIDE the board that is selected. Carrying it as `select` would
28
+ * make the tree try to reveal a node it does not draw, and the back button would leave the board.
29
+ */
30
+ task?: string;
31
+ };
32
+
33
+ // One search parameter carries "open this one" into an area: the header search names a hit, the
34
+ // screen for that area selects it. Keeping it in the URL is what makes a hit reachable with Enter
35
+ // alone — the dialog never reaches into a screen's own state.
36
+ //
37
+ // `view` is the second: which way the selected level is shown — the editor, the relation graph
38
+ // (#19), or the runs of the selected flow (#35). It sits in the URL for the same reason `select`
39
+ // does: what someone is looking at should survive a reload and be linkable.
40
+ //
41
+ // ⚠️ Unknown parameters are passed through rather than dropped. The portal's connect flow returns
42
+ // to `/tools` with its own marker, and a validator that kept only what it knows would delete it.
43
+ export function selectionSearch(search: Record<string, unknown>): SelectionSearch {
44
+ const { select, view, task, ...rest } = search;
45
+ const withSelect =
46
+ typeof select === "string" && select.length > 0 ? { ...rest, select } : { ...rest };
47
+ const withTask =
48
+ typeof task === "string" && task.length > 0 ? { ...withSelect, task } : withSelect;
49
+ const named = viewParam(view);
50
+ return named === null ? withTask : { ...withTask, view: named };
51
+ }
52
+
53
+ // Screens are lazy route components with no route object at hand, so they read the parameter off
54
+ // the location instead of off a typed route.
55
+ export function selectedFrom(search: unknown): string | null {
56
+ const select = (search as { select?: unknown } | null)?.select;
57
+ return typeof select === "string" && select.length > 0 ? select : null;
58
+ }
59
+
60
+ // What the address NAMES, or null when it names nothing. Null is not "the editor": which view a
61
+ // surface falls back to is the surface's own answer, and `viewOf` below is where it is given.
62
+ export function viewFrom(search: unknown): IntelViewParam | null {
63
+ return viewParam((search as { view?: unknown } | null)?.view);
64
+ }
65
+
66
+ /**
67
+ * The view a surface is showing: what the address names, if that surface even has it, and otherwise
68
+ * its default — the first entry of `views`.
69
+ *
70
+ * ⚠️ The fallback is what keeps a foreign parameter from emptying a screen. `?view=graph` on a
71
+ * board names a view a board does not have; read literally it would draw neither the kanban nor the
72
+ * table. It is answered as "the board's default" instead, which is also what a reader following
73
+ * such a link expects to see.
74
+ */
75
+ export function viewOf(search: unknown, views: readonly IntelView[]): IntelView {
76
+ const named = viewFrom(search);
77
+ const fallback = views[0] ?? "editor";
78
+ return named !== null && views.includes(named) ? named : fallback;
79
+ }
80
+
81
+ export function graphViewFrom(search: unknown): boolean {
82
+ return viewFrom(search) === "graph";
83
+ }
84
+
85
+ export function openTaskFrom(search: unknown): string | null {
86
+ const task = (search as { task?: unknown } | null)?.task;
87
+ return typeof task === "string" && task.length > 0 ? task : null;
88
+ }
@@ -0,0 +1,94 @@
1
+ import { useBlocker } from "@tanstack/react-router";
2
+ import { Save } from "lucide-react";
3
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
4
+ import { useI18n } from "@/i18n/i18n-context.tsx";
5
+ import { Modal } from "@/modal/modal.tsx";
6
+
7
+ /**
8
+ * Saving, in the title line beside the name of the thing being saved (#24).
9
+ *
10
+ * ⚠️ Unsaved is a state that must survive colour blindness, so it is never carried by colour alone.
11
+ * The button only exists while there is work to save; it fills, grows a dot and spells the word
12
+ * out. Three signals at once, of which two are readable without seeing any colour at all.
13
+ *
14
+ * ⚠️ The accessible name names the state as well. A screen reader gets neither the fill nor the
15
+ * dot, and saving in progress must not sound like another available action. The visible word stays
16
+ * a prefix of the name, so speech input still reaches the button by what it reads.
17
+ */
18
+ export function SaveButton({
19
+ dirty,
20
+ saving,
21
+ onSave,
22
+ }: {
23
+ dirty: boolean;
24
+ saving: boolean;
25
+ onSave(): void;
26
+ }) {
27
+ const i18n = useI18n();
28
+ if (!dirty && !saving) return null;
29
+ const label = i18n.t(saving ? "common.saving" : "common.saveDirty");
30
+ return (
31
+ <TooltipProvider delayDuration={300}>
32
+ <Tooltip>
33
+ {/* The wrapper remains the trigger while saving, when the button is deliberately disabled. */}
34
+ <TooltipTrigger asChild>
35
+ <span className="inline-flex">
36
+ <button
37
+ type="button"
38
+ disabled={saving}
39
+ onClick={onSave}
40
+ aria-label={label}
41
+ data-dirty={dirty}
42
+ className="inline-flex h-8 items-center gap-2 rounded-md bg-primary px-2.5 text-sm font-medium text-primary-foreground outline-none hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-70"
43
+ >
44
+ <span aria-hidden="true" className="size-1.5 shrink-0 rounded-full bg-current" />
45
+ <Save aria-hidden="true" className="size-4 shrink-0" />
46
+ <span>{saving ? i18n.t("common.saving") : i18n.t("common.save")}</span>
47
+ </button>
48
+ </span>
49
+ </TooltipTrigger>
50
+ <TooltipContent>{label}</TooltipContent>
51
+ </Tooltip>
52
+ </TooltipProvider>
53
+ );
54
+ }
55
+
56
+ /**
57
+ * The state, said out loud at the moment it would otherwise be lost.
58
+ *
59
+ * ⚠️ Without this the button is the only carrier of "not saved yet", and the one person who needs
60
+ * that answer is the one who has already looked away — clicking the next document in the tree is a
61
+ * plain navigation, and the editor would unmount with the work in it. `enableBeforeUnload` covers
62
+ * the other exit, the one the router never sees: closing the tab or reloading.
63
+ */
64
+ export function UnsavedChangesGuard({ dirty }: { dirty: boolean }) {
65
+ const i18n = useI18n();
66
+ const blocker = useBlocker({
67
+ shouldBlockFn: () => true,
68
+ disabled: !dirty,
69
+ enableBeforeUnload: () => dirty,
70
+ withResolver: true,
71
+ });
72
+ if (blocker.status !== "blocked") return null;
73
+ return (
74
+ <Modal title={i18n.t("common.unsavedTitle")} close={blocker.reset}>
75
+ <p className="text-sm text-muted-foreground">{i18n.t("common.unsavedBody")}</p>
76
+ <div className="mt-5 flex gap-2">
77
+ <button
78
+ type="button"
79
+ onClick={blocker.reset}
80
+ className="flex-1 rounded-md border px-4 py-2 text-sm font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring"
81
+ >
82
+ {i18n.t("common.unsavedStay")}
83
+ </button>
84
+ <button
85
+ type="button"
86
+ onClick={blocker.proceed}
87
+ className="flex-1 rounded-md bg-destructive px-4 py-2 text-sm font-medium text-destructive-foreground outline-none hover:bg-destructive/90 focus-visible:ring-2 focus-visible:ring-ring"
88
+ >
89
+ {i18n.t("common.unsavedLeave")}
90
+ </button>
91
+ </div>
92
+ </Modal>
93
+ );
94
+ }
@@ -0,0 +1,40 @@
1
+ import { Info } from "lucide-react";
2
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
3
+
4
+ /**
5
+ * An explanation behind an ⓘ, beside the thing it explains (#204, shared since #249).
6
+ *
7
+ * It exists for the sentence that answers "what IS this" — read once, then furniture. Not for the
8
+ * sentence you need WHILE you type: a reference read while writing must not be behind a hover, so
9
+ * something like a field's format ("five fields: minute, hour, …") stays a visible paragraph.
10
+ * That is the dividing line: *what is this* may hide, *how do I write this* may not.
11
+ *
12
+ * ⚠️ The hint is the trigger's accessible NAME, not only the tooltip's content: Radix describes the
13
+ * trigger by the content only while it is open, and a listener who tabs past a nameless icon button
14
+ * would never learn there is anything behind it.
15
+ *
16
+ * ⚠️ A real `<button>`, not a bare icon or a `<span>` with a hover style. A tooltip that only opens
17
+ * on hover cannot be opened at all on a touch device, and an element that is not focusable is one
18
+ * the keyboard walks straight past.
19
+ *
20
+ * ⚠️ It does NOT replace a field's description. Where this sits beside a form control, the control
21
+ * keeps its own `aria-describedby` pointing at an `sr-only` copy of the same words — the tooltip's
22
+ * content is in the accessibility tree only while it is open, so a field that gave up its
23
+ * description for one would quietly have lost it (#249).
24
+ */
25
+ export function SectionHint({ hint }: { hint: string }) {
26
+ return (
27
+ <TooltipProvider delayDuration={300}>
28
+ <Tooltip>
29
+ <TooltipTrigger
30
+ type="button"
31
+ aria-label={hint}
32
+ className="rounded-full text-muted-foreground outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring"
33
+ >
34
+ <Info aria-hidden="true" className="size-3.5" />
35
+ </TooltipTrigger>
36
+ <TooltipContent className="max-w-xs">{hint}</TooltipContent>
37
+ </Tooltip>
38
+ </TooltipProvider>
39
+ );
40
+ }
@@ -0,0 +1,35 @@
1
+ import { ShieldAlert } from "lucide-react";
2
+ import { useI18n } from "@/i18n/i18n-context.tsx";
3
+
4
+ /**
5
+ * What stands on the screen when signing in worked and the surface still says no (#118).
6
+ *
7
+ * ⚠️ It exists because the honest alternative is worse. "Not signed in" would be a lie — Gate did
8
+ * sign the person in — and it is the lie that sends them back to the login they just came from,
9
+ * which is the loop. This names the state instead: signed in, credential refused, here is what it
10
+ * is usually.
11
+ *
12
+ * ⚠️ No automatic retry, and the button reloads rather than going to the login. Whatever refused
13
+ * the credential a second ago will refuse it again, and a page that keeps trying by itself is the
14
+ * behaviour being fixed. Retrying is the reader's decision, and it costs them one click.
15
+ */
16
+ export function SignInRefused() {
17
+ const i18n = useI18n();
18
+ return (
19
+ <div role="alert" className="grid min-h-dvh place-items-center bg-background p-8">
20
+ <div className="max-w-prose text-center">
21
+ <ShieldAlert aria-hidden="true" className="mx-auto mb-4 size-8 text-muted-foreground" />
22
+ <h1 className="text-lg font-medium text-foreground">{i18n.t("signIn.refusedTitle")}</h1>
23
+ <p className="mt-2 text-sm text-muted-foreground">{i18n.t("signIn.refusedBody")}</p>
24
+ <p className="mt-4 text-sm text-muted-foreground">{i18n.t("signIn.refusedLikely")}</p>
25
+ <button
26
+ type="button"
27
+ onClick={() => window.location.reload()}
28
+ className="mt-6 rounded-md border px-4 py-2 text-sm font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring"
29
+ >
30
+ {i18n.t("signIn.refusedRetry")}
31
+ </button>
32
+ </div>
33
+ </div>
34
+ );
35
+ }
@@ -0,0 +1,189 @@
1
+ @import "tailwindcss";
2
+ @import "@blocknote/core/fonts/inter.css";
3
+ @import "@blocknote/shadcn/style.css";
4
+ @import "@xyflow/react/dist/style.css";
5
+ @source "../node_modules/@blocknote/shadcn";
6
+
7
+ @custom-variant dark (&:is(.dark *));
8
+
9
+ /* The default theme is gate's, token for token: an achromatic base whose primary is black rather
10
+ than Intel's former blue (hue 265). Every value here is a default — `theme/custom.css` is loaded
11
+ after this file and a customer theme overrides any of them without touching a component. */
12
+ :root {
13
+ --radius: 0.625rem;
14
+ --background: oklch(1 0 0);
15
+ --foreground: oklch(0.145 0 0);
16
+ --card: oklch(1 0 0);
17
+ --card-foreground: oklch(0.145 0 0);
18
+ --popover: oklch(1 0 0);
19
+ --popover-foreground: oklch(0.145 0 0);
20
+ --primary: oklch(0.205 0 0);
21
+ --primary-foreground: oklch(0.985 0 0);
22
+ --secondary: oklch(0.97 0 0);
23
+ --secondary-foreground: oklch(0.205 0 0);
24
+ --muted: oklch(0.97 0 0);
25
+ --muted-foreground: oklch(0.556 0 0);
26
+ --accent: oklch(0.97 0 0);
27
+ --accent-foreground: oklch(0.205 0 0);
28
+ --destructive: oklch(0.577 0.245 27.325);
29
+ --destructive-foreground: oklch(0.985 0 0);
30
+ --border: oklch(0.922 0 0);
31
+ --input: oklch(0.922 0 0);
32
+ --ring: oklch(0.708 0 0);
33
+ --sidebar: oklch(0.985 0 0);
34
+ --sidebar-foreground: oklch(0.145 0 0);
35
+ --sidebar-primary: oklch(0.205 0 0);
36
+ --sidebar-primary-foreground: oklch(0.985 0 0);
37
+ --sidebar-accent: oklch(0.97 0 0);
38
+ --sidebar-accent-foreground: oklch(0.205 0 0);
39
+ --sidebar-border: oklch(0.922 0 0);
40
+ --sidebar-ring: oklch(0.708 0 0);
41
+ /* The board's status ramp (anchrd/intel#286). These are the only tokens in Intel that carry hue
42
+ on purpose, and the reason is that they are the only ones asked to tell things APART: a month
43
+ grid of achromatic dots codes nothing, and neither does a graph whose blocked node looks like
44
+ its neighbour.
45
+
46
+ ⚠️ **A step belongs to a FAMILY, not to a status and not to a depth.** Every card descending
47
+ from the same root task takes the same step, whatever column it sits in and however deep it
48
+ hangs — that is what lets somebody see that the card in `Backlog` belongs to the one in
49
+ `In progress`. Depth is carried by the NUMBER of stripes, never by the hue: two channels for
50
+ two questions.
51
+
52
+ ⚠️ **Six, and then they repeat.** Two families sharing a step is not a fault. At twenty root
53
+ tasks every other answer is a palette nobody can tell apart, and a colour that cannot be told
54
+ apart says less than none.
55
+
56
+ ⚠️ Colour is never the only channel. Every card that carries stripes also names its level and
57
+ where its parent sits, in text, so a reader who does not see the difference reads it instead. */
58
+ --board-family-1: oklch(0.58 0.02 260);
59
+ --board-family-2: oklch(0.55 0.16 255);
60
+ --board-family-3: oklch(0.65 0.15 65);
61
+ --board-family-4: oklch(0.55 0.14 150);
62
+ --board-family-5: oklch(0.53 0.18 305);
63
+ --board-family-6: oklch(0.56 0.15 20);
64
+ }
65
+
66
+ .dark {
67
+ --background: oklch(0.145 0 0);
68
+ --foreground: oklch(0.985 0 0);
69
+ --card: oklch(0.205 0 0);
70
+ --card-foreground: oklch(0.985 0 0);
71
+ --popover: oklch(0.205 0 0);
72
+ --popover-foreground: oklch(0.985 0 0);
73
+ --primary: oklch(0.922 0 0);
74
+ --primary-foreground: oklch(0.205 0 0);
75
+ --secondary: oklch(0.269 0 0);
76
+ --secondary-foreground: oklch(0.985 0 0);
77
+ --muted: oklch(0.269 0 0);
78
+ --muted-foreground: oklch(0.708 0 0);
79
+ --accent: oklch(0.269 0 0);
80
+ --accent-foreground: oklch(0.985 0 0);
81
+ --destructive: oklch(0.704 0.191 22.216);
82
+ --destructive-foreground: oklch(0.985 0 0);
83
+ --border: oklch(1 0 0 / 10%);
84
+ --input: oklch(1 0 0 / 15%);
85
+ --ring: oklch(0.556 0 0);
86
+ --sidebar: oklch(0.205 0 0);
87
+ --sidebar-foreground: oklch(0.985 0 0);
88
+ --sidebar-primary: oklch(0.922 0 0);
89
+ --sidebar-primary-foreground: oklch(0.205 0 0);
90
+ --sidebar-accent: oklch(0.269 0 0);
91
+ --sidebar-accent-foreground: oklch(0.985 0 0);
92
+ --sidebar-border: oklch(1 0 0 / 10%);
93
+ --sidebar-ring: oklch(0.556 0 0);
94
+ /* The same six steps, lifted for a dark surface. Same hues, same order — a board must not change
95
+ which colour a column has when the reader switches the appearance. */
96
+ --board-family-1: oklch(0.72 0.02 260);
97
+ --board-family-2: oklch(0.7 0.14 255);
98
+ --board-family-3: oklch(0.78 0.13 65);
99
+ --board-family-4: oklch(0.72 0.13 150);
100
+ --board-family-5: oklch(0.7 0.16 305);
101
+ --board-family-6: oklch(0.71 0.14 20);
102
+ }
103
+
104
+ @theme inline {
105
+ --radius-sm: calc(var(--radius) - 4px);
106
+ --radius-md: calc(var(--radius) - 2px);
107
+ --radius-lg: var(--radius);
108
+ --radius-xl: calc(var(--radius) + 4px);
109
+ --color-background: var(--background);
110
+ --color-foreground: var(--foreground);
111
+ --color-card: var(--card);
112
+ --color-card-foreground: var(--card-foreground);
113
+ --color-popover: var(--popover);
114
+ --color-popover-foreground: var(--popover-foreground);
115
+ --color-primary: var(--primary);
116
+ --color-primary-foreground: var(--primary-foreground);
117
+ --color-secondary: var(--secondary);
118
+ --color-secondary-foreground: var(--secondary-foreground);
119
+ --color-muted: var(--muted);
120
+ --color-muted-foreground: var(--muted-foreground);
121
+ --color-accent: var(--accent);
122
+ --color-accent-foreground: var(--accent-foreground);
123
+ --color-destructive: var(--destructive);
124
+ --color-destructive-foreground: var(--destructive-foreground);
125
+ --color-border: var(--border);
126
+ --color-input: var(--input);
127
+ --color-ring: var(--ring);
128
+ --color-sidebar: var(--sidebar);
129
+ --color-sidebar-foreground: var(--sidebar-foreground);
130
+ --color-sidebar-primary: var(--sidebar-primary);
131
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
132
+ --color-sidebar-accent: var(--sidebar-accent);
133
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
134
+ --color-sidebar-border: var(--sidebar-border);
135
+ --color-sidebar-ring: var(--sidebar-ring);
136
+ --color-board-family-1: var(--board-family-1);
137
+ --color-board-family-2: var(--board-family-2);
138
+ --color-board-family-3: var(--board-family-3);
139
+ --color-board-family-4: var(--board-family-4);
140
+ --color-board-family-5: var(--board-family-5);
141
+ --color-board-family-6: var(--board-family-6);
142
+ }
143
+
144
+ @layer base {
145
+ * {
146
+ @apply border-border outline-ring/50;
147
+ }
148
+ body {
149
+ @apply bg-background text-foreground;
150
+ }
151
+ }
152
+
153
+ /* `colorMode` on `<ReactFlow>` decides which of the library's two palettes it paints from; these
154
+ decide what the palette is made of. They are React Flow's own theming variables — its documented
155
+ extension point, set on its root class, not overrides hung on the internal class names of its
156
+ controls — so an installation with its own theme colours the canvas, the grid, the zoom buttons
157
+ and the overview map along with everything else. The radial relation graph needs none of this: it
158
+ is plain SVG, and its colours are semantic tokens read straight off the elements (#825). */
159
+ .react-flow {
160
+ --xy-background-color: var(--background);
161
+ --xy-background-pattern-color: var(--border);
162
+ --xy-controls-button-background-color: var(--card);
163
+ --xy-controls-button-background-color-hover: var(--accent);
164
+ --xy-controls-button-color: var(--card-foreground);
165
+ --xy-controls-button-color-hover: var(--accent-foreground);
166
+ --xy-controls-button-border-color: var(--border);
167
+ --xy-minimap-background-color: var(--card);
168
+ /* The nodes have to read as nodes against the map's own background rather than as one white
169
+ block, so they take the token that is defined to contrast with it. */
170
+ --xy-minimap-node-background-color: var(--muted-foreground);
171
+ /* The veil over everything outside the viewport: a token, thinned, because opaque would hide the
172
+ part of the graph the map exists to show. */
173
+ --xy-minimap-mask-background-color: color-mix(in oklab, var(--muted) 70%, transparent);
174
+ }
175
+
176
+ /* A context edge is not a step in the order of work (#37), so it is drawn as material rather than as
177
+ procedure: dashed, thinner, and in the muted token instead of the edge colour. The dash pattern is
178
+ set on the edge itself; the colour belongs here, with the rest of the canvas theming, so an
179
+ installation's own tokens reach it too. */
180
+ .react-flow .intel-context-edge .react-flow__edge-path {
181
+ stroke: var(--muted-foreground);
182
+ stroke-width: 1.5;
183
+ }
184
+
185
+ /* The start node in the overview map (#39). Nothing is written there, so the only thing that can
186
+ carry "this is where it begins" that far out is the colour. */
187
+ .react-flow__minimap-node.intel-minimap-start {
188
+ fill: var(--primary);
189
+ }