@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.
- package/README.md +496 -0
- package/bin/intel.mjs +134 -0
- package/dist/adapters/cloudflare/cloudflare-flow-workflow.d.ts +42 -0
- package/dist/adapters/cloudflare/cloudflare-flow-workflow.js +89 -0
- package/dist/adapters/cloudflare/cloudflare.d.ts +29 -0
- package/dist/adapters/cloudflare/cloudflare.js +416 -0
- package/dist/adapters/cloudflare/cloudflare.types.d.ts +31 -0
- package/dist/adapters/cloudflare/cloudflare.types.js +1 -0
- package/dist/adapters/content/content.d.ts +3 -0
- package/dist/adapters/content/content.js +128 -0
- package/dist/adapters/content/content.types.d.ts +38 -0
- package/dist/adapters/content/content.types.js +1 -0
- package/dist/adapters/db/db-audit.d.ts +62 -0
- package/dist/adapters/db/db-audit.js +150 -0
- package/dist/adapters/db/db-boards.d.ts +6 -0
- package/dist/adapters/db/db-boards.js +324 -0
- package/dist/adapters/db/db-feed.d.ts +30 -0
- package/dist/adapters/db/db-feed.js +276 -0
- package/dist/adapters/db/db-flows.d.ts +42 -0
- package/dist/adapters/db/db-flows.js +1311 -0
- package/dist/adapters/db/db-grants.d.ts +133 -0
- package/dist/adapters/db/db-grants.js +269 -0
- package/dist/adapters/db/db-indexing.d.ts +3 -0
- package/dist/adapters/db/db-indexing.js +200 -0
- package/dist/adapters/db/db-oauth.d.ts +3 -0
- package/dist/adapters/db/db-oauth.js +26 -0
- package/dist/adapters/db/db-prompts.d.ts +46 -0
- package/dist/adapters/db/db-prompts.js +144 -0
- package/dist/adapters/db/db.d.ts +6 -0
- package/dist/adapters/db/db.js +1687 -0
- package/dist/adapters/db/db.types.d.ts +16 -0
- package/dist/adapters/db/db.types.js +1 -0
- package/dist/adapters/document-converter/document-converter.d.ts +2 -0
- package/dist/adapters/document-converter/document-converter.js +26 -0
- package/dist/adapters/document-converter/document-converter.types.d.ts +17 -0
- package/dist/adapters/document-converter/document-converter.types.js +1 -0
- package/dist/adapters/flow-runtime/flow-runtime.d.ts +3 -0
- package/dist/adapters/flow-runtime/flow-runtime.js +22 -0
- package/dist/adapters/flow-runtime/flow-runtime.types.d.ts +19 -0
- package/dist/adapters/flow-runtime/flow-runtime.types.js +1 -0
- package/dist/adapters/index-queue/index-queue.d.ts +10 -0
- package/dist/adapters/index-queue/index-queue.js +12 -0
- package/dist/adapters/index-queue/index-queue.types.d.ts +11 -0
- package/dist/adapters/index-queue/index-queue.types.js +1 -0
- package/dist/adapters/json-schema/json-schema.d.ts +2 -0
- package/dist/adapters/json-schema/json-schema.js +77 -0
- package/dist/adapters/openid/openid.d.ts +5 -0
- package/dist/adapters/openid/openid.js +301 -0
- package/dist/adapters/portal-tokens/portal-tokens.d.ts +8 -0
- package/dist/adapters/portal-tokens/portal-tokens.js +79 -0
- package/dist/adapters/remote-tools/remote-tools.d.ts +5 -0
- package/dist/adapters/remote-tools/remote-tools.js +129 -0
- package/dist/adapters/semantic-index/semantic-index.d.ts +2 -0
- package/dist/adapters/semantic-index/semantic-index.js +139 -0
- package/dist/adapters/semantic-index/semantic-index.types.d.ts +56 -0
- package/dist/adapters/semantic-index/semantic-index.types.js +1 -0
- package/dist/adapters/session-cookie/session-cookie.d.ts +5 -0
- package/dist/adapters/session-cookie/session-cookie.js +87 -0
- package/dist/adapters/tool-source-policy/tool-source-policy.d.ts +1 -0
- package/dist/adapters/tool-source-policy/tool-source-policy.js +22 -0
- package/dist/audit/audit.d.ts +2 -0
- package/dist/audit/audit.js +87 -0
- package/dist/audit/audit.types.d.ts +23 -0
- package/dist/audit/audit.types.js +1 -0
- package/dist/auth/auth.d.ts +2 -0
- package/dist/auth/auth.js +284 -0
- package/dist/auth/auth.types.d.ts +108 -0
- package/dist/auth/auth.types.js +1 -0
- package/dist/boards/boards.d.ts +44 -0
- package/dist/boards/boards.js +447 -0
- package/dist/boards/boards.types.d.ts +117 -0
- package/dist/boards/boards.types.js +1 -0
- package/dist/build/build.d.ts +2 -0
- package/dist/build/build.js +192 -0
- package/dist/build/build.types.d.ts +17 -0
- package/dist/build/build.types.js +1 -0
- package/dist/bundle/bundle.d.ts +4 -0
- package/dist/bundle/bundle.js +1194 -0
- package/dist/bundle/bundle.types.d.ts +33 -0
- package/dist/bundle/bundle.types.js +1 -0
- package/dist/cli/cli.d.ts +4 -0
- package/dist/cli/cli.js +262 -0
- package/dist/cli/cli.types.d.ts +14 -0
- package/dist/cli/cli.types.js +1 -0
- package/dist/contract/audit.d.ts +50 -0
- package/dist/contract/audit.js +72 -0
- package/dist/contract/board.d.ts +150 -0
- package/dist/contract/board.js +262 -0
- package/dist/contract/bundle.d.ts +147 -0
- package/dist/contract/bundle.js +139 -0
- package/dist/contract/contract.d.ts +112 -0
- package/dist/contract/contract.js +143 -0
- package/dist/contract/feed.d.ts +126 -0
- package/dist/contract/feed.js +149 -0
- package/dist/contract/flow-run.d.ts +346 -0
- package/dist/contract/flow-run.js +194 -0
- package/dist/contract/flow.d.ts +1057 -0
- package/dist/contract/flow.js +552 -0
- package/dist/contract/node.d.ts +551 -0
- package/dist/contract/node.js +456 -0
- package/dist/contract/share.d.ts +216 -0
- package/dist/contract/share.js +134 -0
- package/dist/contract/table.d.ts +171 -0
- package/dist/contract/table.js +117 -0
- package/dist/contract/tool.d.ts +122 -0
- package/dist/contract/tool.js +172 -0
- package/dist/feed/feed.d.ts +2 -0
- package/dist/feed/feed.js +77 -0
- package/dist/feed/feed.types.d.ts +23 -0
- package/dist/feed/feed.types.js +1 -0
- package/dist/flows/flows.d.ts +41 -0
- package/dist/flows/flows.js +2216 -0
- package/dist/flows/flows.types.d.ts +339 -0
- package/dist/flows/flows.types.js +1 -0
- package/dist/http/http.d.ts +9 -0
- package/dist/http/http.js +874 -0
- package/dist/http/http.types.d.ts +22 -0
- package/dist/http/http.types.js +1 -0
- package/dist/indexing/indexing.d.ts +6 -0
- package/dist/indexing/indexing.js +239 -0
- package/dist/indexing/indexing.types.d.ts +11 -0
- package/dist/indexing/indexing.types.js +1 -0
- package/dist/intel/intel.d.ts +3 -0
- package/dist/intel/intel.js +194 -0
- package/dist/intel/intel.types.d.ts +24 -0
- package/dist/intel/intel.types.js +1 -0
- package/dist/mcp/mcp.d.ts +2 -0
- package/dist/mcp/mcp.js +1292 -0
- package/dist/mcp/mcp.types.d.ts +25 -0
- package/dist/mcp/mcp.types.js +1 -0
- package/dist/nodes/document-links/document-links.d.ts +20 -0
- package/dist/nodes/document-links/document-links.js +57 -0
- package/dist/nodes/nodes.d.ts +2 -0
- package/dist/nodes/nodes.js +1667 -0
- package/dist/nodes/nodes.types.d.ts +511 -0
- package/dist/nodes/nodes.types.js +1 -0
- package/dist/prepare/prepare.d.ts +4 -0
- package/dist/prepare/prepare.js +16 -0
- package/dist/prepare/prepare.types.d.ts +9 -0
- package/dist/prepare/prepare.types.js +1 -0
- package/dist/prompts/prompts.d.ts +2 -0
- package/dist/prompts/prompts.js +65 -0
- package/dist/prompts/prompts.types.d.ts +71 -0
- package/dist/prompts/prompts.types.js +1 -0
- package/dist/shared/callers/callers.d.ts +28 -0
- package/dist/shared/callers/callers.js +30 -0
- package/dist/shared/csv/csv.d.ts +13 -0
- package/dist/shared/csv/csv.js +85 -0
- package/dist/shared/document-text/document-text.d.ts +21 -0
- package/dist/shared/document-text/document-text.js +31 -0
- package/dist/shared/gate-authorization/gate-authorization.d.ts +5 -0
- package/dist/shared/gate-authorization/gate-authorization.js +26 -0
- package/dist/shared/grant-expiry/grant-expiry.d.ts +19 -0
- package/dist/shared/grant-expiry/grant-expiry.js +26 -0
- package/dist/shared/intel-error/intel-error.d.ts +22 -0
- package/dist/shared/intel-error/intel-error.js +27 -0
- package/dist/shared/plain-title/plain-title.d.ts +16 -0
- package/dist/shared/plain-title/plain-title.js +45 -0
- package/dist/shared/problem-details/problem-details.d.ts +30 -0
- package/dist/shared/problem-details/problem-details.js +18 -0
- package/dist/shared/report-unexpected-error/report-unexpected-error.d.ts +1 -0
- package/dist/shared/report-unexpected-error/report-unexpected-error.js +37 -0
- package/dist/shared/safe-return-path/safe-return-path.d.ts +2 -0
- package/dist/shared/safe-return-path/safe-return-path.js +11 -0
- package/dist/shared/sha256/sha256.d.ts +2 -0
- package/dist/shared/sha256/sha256.js +14 -0
- package/dist/tools/tool-servers/tool-servers.d.ts +46 -0
- package/dist/tools/tool-servers/tool-servers.js +177 -0
- package/dist/tools/tools.d.ts +2 -0
- package/dist/tools/tools.js +207 -0
- package/dist/tools/tools.types.d.ts +56 -0
- package/dist/tools/tools.types.js +1 -0
- package/examples/branding/favicon.svg +5 -0
- package/examples/branding/logo.svg +5 -0
- package/examples/branding/theme.css +16 -0
- package/examples/dev.vars.example +7 -0
- package/examples/intel.json +9 -0
- package/migrations/0000_intel_foundation.sql +203 -0
- package/migrations/0001_portal_native_tools.sql +21 -0
- package/migrations/0002_flows_in_the_knowledge_tree.sql +34 -0
- package/migrations/0003_folder_permissions.sql +211 -0
- package/migrations/0004_subflow_runs.sql +14 -0
- package/migrations/0005_flow_node_cleanup.sql +28 -0
- package/migrations/0005_tables_in_the_knowledge_tree.sql +68 -0
- package/migrations/0006_links_are_written_in_the_text.sql +20 -0
- package/migrations/0007_no_node_waits.sql +69 -0
- package/migrations/0008_three_layers.sql +130 -0
- package/migrations/0009_no_context_policy.sql +48 -0
- package/migrations/0010_no_run_waits_a_year.sql +27 -0
- package/migrations/0011_one_name_for_the_tree.sql +53 -0
- package/migrations/0012_table_snapshots.sql +29 -0
- package/migrations/0017_a_vector_per_card.sql +38 -0
- package/migrations/0018_no_context_policy_at_last.sql +97 -0
- package/migrations/0019_one_name_for_the_grants.sql +52 -0
- package/migrations/0020_cascade_purge_replay.sql +11 -0
- package/migrations/0021_a_flow_carries_its_own_grant.sql +44 -0
- package/migrations/0022_a_cursor_over_the_journal.sql +14 -0
- package/migrations/0023_a_board_and_its_tasks.sql +116 -0
- package/migrations/0024_the_archive_is_a_column.sql +33 -0
- package/migrations/0025_archiving_takes_the_subtree.sql +29 -0
- package/migrations/0026_one_feed_over_two_kinds.sql +23 -0
- package/migrations/0027_the_runs_of_every_flow.sql +27 -0
- package/migrations/0028_a_prompt_name_over_two_kinds.sql +70 -0
- package/package.json +118 -0
- package/src/contract/CLAUDE.md +152 -0
- package/src/contract/README.md +102 -0
- package/src/contract/audit.ts +85 -0
- package/src/contract/board.ts +306 -0
- package/src/contract/bundle.ts +157 -0
- package/src/contract/contract.ts +161 -0
- package/src/contract/feed.ts +165 -0
- package/src/contract/flow-run.ts +241 -0
- package/src/contract/flow.ts +675 -0
- package/src/contract/node.ts +583 -0
- package/src/contract/share.ts +196 -0
- package/src/contract/table.ts +178 -0
- package/src/contract/tool.ts +202 -0
- package/ui/README.md +110 -0
- package/ui/components.json +21 -0
- package/ui/index.html +13 -0
- package/ui/package.json +11 -0
- package/ui/scripts/lint-tokens.mjs +187 -0
- package/ui/src/access-summary/access-summary.tsx +385 -0
- package/ui/src/app/action-slot/action-slot.tsx +27 -0
- package/ui/src/app/app-sidebar/app-sidebar.tsx +71 -0
- package/ui/src/app/app-tree/app-tree.tsx +1175 -0
- package/ui/src/app/app.tsx +87 -0
- package/ui/src/app/header-search/header-search.tsx +294 -0
- package/ui/src/app/reindex-dialog/reindex-dialog.tsx +79 -0
- package/ui/src/app/settings-dialog/settings-dialog.tsx +135 -0
- package/ui/src/app/sidebar-preferences/sidebar-preferences.ts +68 -0
- package/ui/src/app/sidebar-preferences/sidebar-preferences.types.ts +15 -0
- package/ui/src/app/sidebar-resize-handle/sidebar-resize-handle.tsx +86 -0
- package/ui/src/app/tree-expansion/tree-expansion.ts +107 -0
- package/ui/src/app/tree-expansion/tree-expansion.types.ts +31 -0
- package/ui/src/app/tree-move/tree-move.tsx +427 -0
- package/ui/src/app/tree-reveal/tree-reveal.ts +64 -0
- package/ui/src/app/tree-reveal/tree-reveal.types.ts +16 -0
- package/ui/src/app/user-footer/user-footer.tsx +188 -0
- package/ui/src/app/view-menu/view-menu.tsx +115 -0
- package/ui/src/app-root/app-root.tsx +109 -0
- package/ui/src/app-root/app-root.types.ts +27 -0
- package/ui/src/archive/archive.tsx +417 -0
- package/ui/src/attachment-detail/attachment-detail.ts +52 -0
- package/ui/src/attachment-viewer/attachment-viewer.tsx +166 -0
- package/ui/src/blocknote-view/blocknote-view.tsx +30 -0
- package/ui/src/board/board-assignee/board-assignee-picker.tsx +132 -0
- package/ui/src/board/board-assignee/board-assignee.ts +48 -0
- package/ui/src/board/board-assignee/board-assignee.tsx +75 -0
- package/ui/src/board/board-chip/board-chip.tsx +46 -0
- package/ui/src/board/board-crumbs/board-crumbs.ts +56 -0
- package/ui/src/board/board-crumbs/board-crumbs.tsx +111 -0
- package/ui/src/board/board-data/board-data.ts +195 -0
- package/ui/src/board/board-data/board-data.types.ts +38 -0
- package/ui/src/board/board-dates/board-dates.ts +40 -0
- package/ui/src/board/board-dates/board-dates.tsx +105 -0
- package/ui/src/board/board-kanban/board-kanban.ts +162 -0
- package/ui/src/board/board-kanban/board-kanban.tsx +680 -0
- package/ui/src/board/board-open-task/board-open-task.ts +32 -0
- package/ui/src/board/board-panel/board-panel.tsx +259 -0
- package/ui/src/board/board-settings/board-settings.tsx +226 -0
- package/ui/src/board/board-status/board-status.tsx +60 -0
- package/ui/src/board/board-stripes/board-stripes.ts +128 -0
- package/ui/src/board/board-table/board-table.ts +53 -0
- package/ui/src/board/board-table/board-table.tsx +610 -0
- package/ui/src/board/board-task/board-task.ts +108 -0
- package/ui/src/board/board-task/board-task.tsx +335 -0
- package/ui/src/board/board-title-row/board-title-row.tsx +66 -0
- package/ui/src/branding/branding.tsx +17 -0
- package/ui/src/branding/custom-logo.ts +1 -0
- package/ui/src/branding/favicon.default.svg +5 -0
- package/ui/src/branding/favicon.svg +5 -0
- package/ui/src/components/ui/avatar.tsx +39 -0
- package/ui/src/components/ui/button.tsx +64 -0
- package/ui/src/components/ui/collapsible.tsx +20 -0
- package/ui/src/components/ui/command.tsx +160 -0
- package/ui/src/components/ui/dialog.tsx +143 -0
- package/ui/src/components/ui/dropdown-menu.tsx +187 -0
- package/ui/src/components/ui/input.tsx +21 -0
- package/ui/src/components/ui/popover.tsx +41 -0
- package/ui/src/components/ui/select.tsx +163 -0
- package/ui/src/components/ui/separator.tsx +26 -0
- package/ui/src/components/ui/sheet.tsx +136 -0
- package/ui/src/components/ui/sidebar.tsx +693 -0
- package/ui/src/components/ui/skeleton.tsx +13 -0
- package/ui/src/components/ui/switch.tsx +25 -0
- package/ui/src/components/ui/table.tsx +82 -0
- package/ui/src/components/ui/tabs.tsx +52 -0
- package/ui/src/components/ui/tooltip.tsx +51 -0
- package/ui/src/data/intel-data-provider/intel-data-provider.ts +685 -0
- package/ui/src/data/intel-data-provider/intel-data-provider.types.ts +266 -0
- package/ui/src/data/query-client.ts +18 -0
- package/ui/src/data/request-refusal/refusal-notice.tsx +36 -0
- package/ui/src/data/request-refusal/request-refusal.ts +51 -0
- package/ui/src/data/sign-in/sign-in.ts +97 -0
- package/ui/src/data/sign-in/sign-in.types.ts +15 -0
- package/ui/src/document-link/document-link.tsx +114 -0
- package/ui/src/document-markdown/document-markdown.ts +195 -0
- package/ui/src/editor-schema/editor-schema.ts +23 -0
- package/ui/src/entry-picker/entry-picker.tsx +238 -0
- package/ui/src/feed/feed.tsx +344 -0
- package/ui/src/file-preview/file-preview-view.tsx +496 -0
- package/ui/src/file-preview/file-preview.tsx +28 -0
- package/ui/src/file-preview/pdf-file-preview.tsx +5 -0
- package/ui/src/file-preview/presentation-file-preview.tsx +21 -0
- package/ui/src/file-preview/spreadsheet-file-preview.tsx +5 -0
- package/ui/src/file-preview/word-file-preview.tsx +5 -0
- package/ui/src/flow-runs/flow-runs.tsx +238 -0
- package/ui/src/flows/flows.tsx +1646 -0
- package/ui/src/flows/node-icon/node-icon.ts +34 -0
- package/ui/src/flows/node-palette/node-palette.tsx +214 -0
- package/ui/src/flows/node-palette/node-palette.types.ts +15 -0
- package/ui/src/folder-contents/folder-contents.tsx +321 -0
- package/ui/src/folder-index/folder-index.ts +55 -0
- package/ui/src/frontmatter/frontmatter.tsx +193 -0
- package/ui/src/graph-pane/graph-pane.tsx +53 -0
- package/ui/src/hooks/use-mobile.ts +19 -0
- package/ui/src/i18n/custom.json +4 -0
- package/ui/src/i18n/de.json +609 -0
- package/ui/src/i18n/en.json +609 -0
- package/ui/src/i18n/es.json +609 -0
- package/ui/src/i18n/i18n-context.tsx +65 -0
- package/ui/src/i18n/i18n-languages/i18n-languages.ts +83 -0
- package/ui/src/i18n/i18n.ts +32 -0
- package/ui/src/i18n/i18n.types.ts +49 -0
- package/ui/src/kind-icon.ts +97 -0
- package/ui/src/lib/utils.ts +6 -0
- package/ui/src/main.tsx +68 -0
- package/ui/src/modal/modal.tsx +53 -0
- package/ui/src/node-details/node-details.tsx +545 -0
- package/ui/src/node-editor/node-editor.tsx +304 -0
- package/ui/src/node-graph/graph-notice.tsx +21 -0
- package/ui/src/node-graph/node-graph.ts +214 -0
- package/ui/src/node-graph/node-graph.tsx +295 -0
- package/ui/src/node-import/node-import.tsx +418 -0
- package/ui/src/node-save-error.ts +46 -0
- package/ui/src/node-source/node-source.tsx +128 -0
- package/ui/src/node-table/node-table.tsx +107 -0
- package/ui/src/nodes/nodes.tsx +240 -0
- package/ui/src/rename-resource/rename-resource.ts +80 -0
- package/ui/src/resolved-names/resolved-names.tsx +67 -0
- package/ui/src/resource-error.ts +33 -0
- package/ui/src/resource-menu/resource-menu.tsx +1156 -0
- package/ui/src/router/router-context.ts +6 -0
- package/ui/src/router/router.tsx +67 -0
- package/ui/src/router/router.types.ts +8 -0
- package/ui/src/router/selection-search.ts +88 -0
- package/ui/src/save-button/save-button.tsx +94 -0
- package/ui/src/section-hint/section-hint.tsx +40 -0
- package/ui/src/sign-in-refused/sign-in-refused.tsx +35 -0
- package/ui/src/styles.css +189 -0
- package/ui/src/table-columns/table-columns.tsx +379 -0
- package/ui/src/theme/custom.css +1 -0
- package/ui/src/theme/theme-context.tsx +89 -0
- package/ui/src/theme/theme.ts +70 -0
- package/ui/src/time/relative-time.tsx +41 -0
- package/ui/src/time/time-context.tsx +78 -0
- package/ui/src/time/time.ts +165 -0
- package/ui/src/title-row/title-row.tsx +185 -0
- package/ui/src/tools/tools.tsx +546 -0
- package/ui/src/user-name/user-name.ts +61 -0
- package/ui/src/verbatim/verbatim.tsx +68 -0
- package/ui/tsconfig.json +17 -0
- package/ui/vite.config.ts +129 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE knowledge_nodes (
|
|
4
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
5
|
+
parent_id TEXT REFERENCES knowledge_nodes(id),
|
|
6
|
+
kind TEXT NOT NULL CHECK (kind IN ('folder', 'document', 'attachment')),
|
|
7
|
+
title TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 240),
|
|
8
|
+
description TEXT CHECK (description IS NULL OR length(description) <= 2000),
|
|
9
|
+
context_policy TEXT NOT NULL CHECK (context_policy IN ('pinned', 'relevant', 'explicit')),
|
|
10
|
+
owner_id TEXT NOT NULL,
|
|
11
|
+
current_version_id TEXT,
|
|
12
|
+
created_at TEXT NOT NULL,
|
|
13
|
+
updated_at TEXT NOT NULL,
|
|
14
|
+
archived_at TEXT
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX knowledge_nodes_parent_idx ON knowledge_nodes(parent_id, archived_at, title);
|
|
18
|
+
CREATE INDEX knowledge_nodes_owner_idx ON knowledge_nodes(owner_id, archived_at);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE knowledge_versions (
|
|
21
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
22
|
+
node_id TEXT NOT NULL REFERENCES knowledge_nodes(id),
|
|
23
|
+
sequence INTEGER NOT NULL CHECK (sequence > 0),
|
|
24
|
+
content_key TEXT NOT NULL UNIQUE,
|
|
25
|
+
media_type TEXT NOT NULL,
|
|
26
|
+
content_hash TEXT NOT NULL CHECK (length(content_hash) = 64),
|
|
27
|
+
size INTEGER NOT NULL CHECK (size >= 0),
|
|
28
|
+
created_by TEXT NOT NULL,
|
|
29
|
+
created_at TEXT NOT NULL,
|
|
30
|
+
UNIQUE (node_id, sequence)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE INDEX knowledge_versions_node_idx ON knowledge_versions(node_id, sequence DESC);
|
|
34
|
+
|
|
35
|
+
CREATE TABLE knowledge_links (
|
|
36
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
37
|
+
source_node_id TEXT NOT NULL REFERENCES knowledge_nodes(id) ON DELETE CASCADE,
|
|
38
|
+
target_node_id TEXT NOT NULL REFERENCES knowledge_nodes(id) ON DELETE CASCADE,
|
|
39
|
+
relation TEXT NOT NULL CHECK (relation IN ('references', 'related', 'depends_on', 'implements')),
|
|
40
|
+
label TEXT CHECK (label IS NULL OR length(label) BETWEEN 1 AND 120),
|
|
41
|
+
created_by TEXT NOT NULL,
|
|
42
|
+
created_at TEXT NOT NULL,
|
|
43
|
+
CHECK (source_node_id <> target_node_id),
|
|
44
|
+
UNIQUE (source_node_id, target_node_id, relation)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
CREATE INDEX knowledge_links_source_idx ON knowledge_links(source_node_id, created_at);
|
|
48
|
+
CREATE INDEX knowledge_links_target_idx ON knowledge_links(target_node_id, created_at);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE knowledge_index_state (
|
|
51
|
+
version_id TEXT PRIMARY KEY NOT NULL REFERENCES knowledge_versions(id),
|
|
52
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'indexed', 'error')),
|
|
53
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
54
|
+
last_error TEXT,
|
|
55
|
+
updated_at TEXT NOT NULL
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE INDEX knowledge_index_state_status_idx ON knowledge_index_state(status, updated_at);
|
|
59
|
+
|
|
60
|
+
CREATE TABLE resource_grants (
|
|
61
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
62
|
+
resource_type TEXT NOT NULL CHECK (resource_type IN ('knowledge', 'flow', 'tool-source')),
|
|
63
|
+
resource_id TEXT NOT NULL,
|
|
64
|
+
principal_type TEXT NOT NULL CHECK (principal_type IN ('user', 'email', 'organization')),
|
|
65
|
+
principal_id TEXT NOT NULL,
|
|
66
|
+
role TEXT NOT NULL CHECK (role IN ('viewer', 'commenter', 'editor', 'manager')),
|
|
67
|
+
expires_at TEXT,
|
|
68
|
+
created_by TEXT NOT NULL,
|
|
69
|
+
created_at TEXT NOT NULL,
|
|
70
|
+
UNIQUE (resource_type, resource_id, principal_type, principal_id)
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
CREATE INDEX resource_grants_principal_idx ON resource_grants(
|
|
74
|
+
principal_type,
|
|
75
|
+
principal_id,
|
|
76
|
+
resource_type,
|
|
77
|
+
expires_at
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
CREATE TABLE idempotency_keys (
|
|
81
|
+
actor_id TEXT NOT NULL,
|
|
82
|
+
operation TEXT NOT NULL,
|
|
83
|
+
idempotency_key TEXT NOT NULL,
|
|
84
|
+
resource_id TEXT NOT NULL,
|
|
85
|
+
created_at TEXT NOT NULL,
|
|
86
|
+
PRIMARY KEY (actor_id, operation, idempotency_key)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
CREATE INDEX idempotency_keys_created_idx ON idempotency_keys(created_at);
|
|
90
|
+
|
|
91
|
+
CREATE TABLE audit_events (
|
|
92
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
93
|
+
actor_id TEXT NOT NULL,
|
|
94
|
+
action TEXT NOT NULL,
|
|
95
|
+
resource_type TEXT NOT NULL,
|
|
96
|
+
resource_id TEXT NOT NULL,
|
|
97
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
98
|
+
occurred_at TEXT NOT NULL
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
CREATE INDEX audit_events_resource_idx ON audit_events(resource_type, resource_id, occurred_at DESC);
|
|
102
|
+
CREATE INDEX audit_events_actor_idx ON audit_events(actor_id, occurred_at DESC);
|
|
103
|
+
|
|
104
|
+
CREATE TABLE oauth_clients (
|
|
105
|
+
issuer TEXT NOT NULL,
|
|
106
|
+
redirect_uri TEXT NOT NULL,
|
|
107
|
+
client_id TEXT NOT NULL,
|
|
108
|
+
created_at TEXT NOT NULL,
|
|
109
|
+
PRIMARY KEY (issuer, redirect_uri)
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
CREATE TABLE tool_sources (
|
|
113
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
114
|
+
name TEXT NOT NULL,
|
|
115
|
+
url TEXT NOT NULL UNIQUE,
|
|
116
|
+
connection_handle TEXT NOT NULL,
|
|
117
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
|
118
|
+
created_by TEXT NOT NULL,
|
|
119
|
+
created_at TEXT NOT NULL,
|
|
120
|
+
updated_at TEXT NOT NULL,
|
|
121
|
+
last_discovered_at TEXT
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
CREATE TABLE tool_catalog (
|
|
125
|
+
source_id TEXT NOT NULL REFERENCES tool_sources(id) ON DELETE CASCADE,
|
|
126
|
+
name TEXT NOT NULL,
|
|
127
|
+
title TEXT,
|
|
128
|
+
description TEXT,
|
|
129
|
+
input_schema_json TEXT NOT NULL,
|
|
130
|
+
output_schema_json TEXT,
|
|
131
|
+
annotations_json TEXT NOT NULL,
|
|
132
|
+
fingerprint TEXT NOT NULL,
|
|
133
|
+
discovered_at TEXT NOT NULL,
|
|
134
|
+
PRIMARY KEY (source_id, name)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
CREATE INDEX tool_catalog_title_idx ON tool_catalog(source_id, title, name);
|
|
138
|
+
|
|
139
|
+
CREATE TABLE flows (
|
|
140
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
141
|
+
title TEXT NOT NULL,
|
|
142
|
+
description TEXT,
|
|
143
|
+
owner_id TEXT NOT NULL,
|
|
144
|
+
current_version_id TEXT,
|
|
145
|
+
published_version_id TEXT,
|
|
146
|
+
created_at TEXT NOT NULL,
|
|
147
|
+
updated_at TEXT NOT NULL,
|
|
148
|
+
archived_at TEXT
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
CREATE INDEX flows_owner_idx ON flows(owner_id, archived_at, updated_at DESC);
|
|
152
|
+
|
|
153
|
+
CREATE TABLE flow_versions (
|
|
154
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
155
|
+
flow_id TEXT NOT NULL REFERENCES flows(id),
|
|
156
|
+
sequence INTEGER NOT NULL CHECK (sequence > 0),
|
|
157
|
+
graph_json TEXT NOT NULL,
|
|
158
|
+
created_by TEXT NOT NULL,
|
|
159
|
+
created_at TEXT NOT NULL,
|
|
160
|
+
UNIQUE (flow_id, sequence)
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
CREATE INDEX flow_versions_flow_idx ON flow_versions(flow_id, sequence DESC);
|
|
164
|
+
|
|
165
|
+
CREATE TABLE flow_runs (
|
|
166
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
167
|
+
flow_id TEXT NOT NULL REFERENCES flows(id),
|
|
168
|
+
version_id TEXT NOT NULL REFERENCES flow_versions(id),
|
|
169
|
+
status TEXT NOT NULL CHECK (status IN ('queued', 'running', 'waiting', 'completed', 'failed', 'cancelled')),
|
|
170
|
+
current_node_id TEXT,
|
|
171
|
+
input_json TEXT NOT NULL,
|
|
172
|
+
output_json TEXT,
|
|
173
|
+
error TEXT,
|
|
174
|
+
initiated_by TEXT NOT NULL,
|
|
175
|
+
created_at TEXT NOT NULL,
|
|
176
|
+
updated_at TEXT NOT NULL,
|
|
177
|
+
completed_at TEXT,
|
|
178
|
+
transition_id TEXT
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
CREATE INDEX flow_runs_flow_idx ON flow_runs(flow_id, created_at DESC);
|
|
182
|
+
CREATE INDEX flow_runs_status_idx ON flow_runs(status, updated_at);
|
|
183
|
+
|
|
184
|
+
CREATE TABLE flow_run_steps (
|
|
185
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
186
|
+
run_id TEXT NOT NULL REFERENCES flow_runs(id),
|
|
187
|
+
node_id TEXT NOT NULL,
|
|
188
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('completed', 'failed')),
|
|
189
|
+
branch TEXT,
|
|
190
|
+
output_json TEXT,
|
|
191
|
+
error TEXT,
|
|
192
|
+
completed_by TEXT NOT NULL,
|
|
193
|
+
completed_at TEXT NOT NULL,
|
|
194
|
+
UNIQUE (run_id, node_id)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
CREATE VIRTUAL TABLE knowledge_fts USING fts5(
|
|
198
|
+
version_id UNINDEXED,
|
|
199
|
+
node_id UNINDEXED,
|
|
200
|
+
title,
|
|
201
|
+
content,
|
|
202
|
+
tokenize = 'unicode61 remove_diacritics 2'
|
|
203
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-- ADR-0003: the Cloudflare MCP portal owns tool discovery, tool permissions and provider
|
|
2
|
+
-- credentials. Intel no longer registers sources, mirrors a catalog or grants access to tools.
|
|
3
|
+
-- 0.1.x shipped these tables, so they are dropped explicitly rather than removed from 0000.
|
|
4
|
+
|
|
5
|
+
DROP INDEX IF EXISTS tool_catalog_title_idx;
|
|
6
|
+
DROP TABLE IF EXISTS tool_catalog;
|
|
7
|
+
DROP TABLE IF EXISTS tool_sources;
|
|
8
|
+
|
|
9
|
+
-- Grants for a resource type that no longer exists would otherwise linger and keep matching the
|
|
10
|
+
-- ACL predicate shape used by knowledge and flows. The CHECK constraint still lists 'tool-source';
|
|
11
|
+
-- rebuilding the table to drop one unused enum value is not worth the migration risk.
|
|
12
|
+
DELETE FROM resource_grants WHERE resource_type = 'tool-source';
|
|
13
|
+
|
|
14
|
+
-- The only tool-related secret Intel stores: the per-user access token for its own portal
|
|
15
|
+
-- endpoint, sealed with the INTEL_SESSION_SECRET-derived key. No provider credential reaches D1.
|
|
16
|
+
CREATE TABLE portal_tokens (
|
|
17
|
+
user_id TEXT PRIMARY KEY NOT NULL,
|
|
18
|
+
sealed TEXT NOT NULL,
|
|
19
|
+
expires_at TEXT NOT NULL,
|
|
20
|
+
updated_at TEXT NOT NULL
|
|
21
|
+
);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- ADR-0004: Knowledge and Flows share one folder tree. A flow gains `parent_id` into the existing
|
|
2
|
+
-- `knowledge_nodes` tree; the contents stay two tables, because versions, the R2 body and the
|
|
3
|
+
-- Vectorize entry belong to the document while the graph, runs and approvals belong to the flow.
|
|
4
|
+
|
|
5
|
+
-- SQLite only accepts an added REFERENCES column when its default is NULL, which is exactly what an
|
|
6
|
+
-- unfiled flow needs: `NULL` is the root of the same tree Knowledge uses.
|
|
7
|
+
ALTER TABLE flows ADD COLUMN parent_id TEXT REFERENCES knowledge_nodes(id);
|
|
8
|
+
|
|
9
|
+
CREATE INDEX flows_parent_idx ON flows(parent_id, archived_at, title);
|
|
10
|
+
|
|
11
|
+
-- Existing flows land in a defined folder rather than scattered across the root. One folder per
|
|
12
|
+
-- owner, with a derived ID so a re-run finds the same row: the narrow reading of an ambiguous case,
|
|
13
|
+
-- as the ADR requires. A single shared folder would have to belong to someone, and its owner would
|
|
14
|
+
-- gain sight of everyone else's flows — a migration must never widen access.
|
|
15
|
+
INSERT INTO knowledge_nodes (
|
|
16
|
+
id, parent_id, kind, title, description, context_policy, owner_id,
|
|
17
|
+
current_version_id, created_at, updated_at, archived_at
|
|
18
|
+
)
|
|
19
|
+
SELECT
|
|
20
|
+
'folder-flows-' || flow.owner_id,
|
|
21
|
+
NULL,
|
|
22
|
+
'folder',
|
|
23
|
+
'Flows',
|
|
24
|
+
'Flows that existed before Knowledge and Flows shared one tree.',
|
|
25
|
+
'explicit',
|
|
26
|
+
flow.owner_id,
|
|
27
|
+
NULL,
|
|
28
|
+
'2026-08-01T00:00:00.000Z',
|
|
29
|
+
'2026-08-01T00:00:00.000Z',
|
|
30
|
+
NULL
|
|
31
|
+
FROM flows flow
|
|
32
|
+
GROUP BY flow.owner_id;
|
|
33
|
+
|
|
34
|
+
UPDATE flows SET parent_id = 'folder-flows-' || owner_id WHERE parent_id IS NULL;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
-- ADR-0004 §2: a grant sits on a node of the shared tree and applies to everything beneath it, and
|
|
2
|
+
-- the verbs `read` / `write` / `execute` / `share` are granted independently. `role` could not carry
|
|
3
|
+
-- that: it is a ladder (viewer < editor < manager), and the case the ADR is built around — /crm is
|
|
4
|
+
-- readable for sales and executable only for billing — is not a rung on it.
|
|
5
|
+
--
|
|
6
|
+
-- `resource_grants` is deliberately left in place and untouched. The previous version of the Worker
|
|
7
|
+
-- reads it and keeps answering correctly until it is replaced; nothing in this version reads it any
|
|
8
|
+
-- more. Once no old Worker is left, the table holds only history and can be dropped.
|
|
9
|
+
|
|
10
|
+
CREATE TABLE tree_grants (
|
|
11
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
12
|
+
-- Any node of the shared tree, not only a folder: a grant that was migrated from a document has
|
|
13
|
+
-- to stay exactly where it was. Moving it up to the parent folder would hand its principal the
|
|
14
|
+
-- folder's other contents as well, and a migration must never widen access. A grant on a leaf is
|
|
15
|
+
-- simply a subtree of one.
|
|
16
|
+
node_id TEXT NOT NULL REFERENCES knowledge_nodes(id),
|
|
17
|
+
principal_type TEXT NOT NULL CHECK (principal_type IN ('user', 'email', 'organization')),
|
|
18
|
+
principal_id TEXT NOT NULL,
|
|
19
|
+
verb TEXT NOT NULL CHECK (verb IN ('read', 'write', 'execute', 'share')),
|
|
20
|
+
expires_at TEXT,
|
|
21
|
+
created_by TEXT NOT NULL,
|
|
22
|
+
created_at TEXT NOT NULL,
|
|
23
|
+
-- The verb belongs in the key. Without it one principal could hold only one verb per node, which
|
|
24
|
+
-- is the ladder again under a new name.
|
|
25
|
+
UNIQUE (node_id, principal_type, principal_id, verb)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX tree_grants_principal_idx ON tree_grants(
|
|
29
|
+
principal_type,
|
|
30
|
+
principal_id,
|
|
31
|
+
verb,
|
|
32
|
+
expires_at
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
CREATE INDEX tree_grants_node_idx ON tree_grants(node_id, verb);
|
|
36
|
+
|
|
37
|
+
-- `principal_type` and `principal_id` are carried over verbatim, and that is a decision rather than
|
|
38
|
+
-- laziness. Both resolvers read a principal the same way: a user by ID, an email folded to lower
|
|
39
|
+
-- case on both sides, and the whole organization as the literal `*` that `setGrant` has always
|
|
40
|
+
-- written. Rewriting any of them here would be a migration changing who a grant means.
|
|
41
|
+
--
|
|
42
|
+
-- The one case worth naming is an `organization` row whose `principal_id` is not `*`. Nothing in
|
|
43
|
+
-- Intel writes such a row, but a repair or an import could have. It is copied as it stands, so it
|
|
44
|
+
-- matches nobody and the access is gone; normalizing it to `*` would turn a row of unknown scope
|
|
45
|
+
-- into a grant for everyone. Narrow is a lost grant somebody notices, wide is access nobody sees.
|
|
46
|
+
|
|
47
|
+
-- A flow grant has no folder to move to that would be honest. Its own parent folder holds other
|
|
48
|
+
-- things, so putting the grant there would show the principal everything else in that folder. The
|
|
49
|
+
-- narrow reading is a folder that contains exactly this one flow: the flow moves into it, the grant
|
|
50
|
+
-- lands on it, and nothing else is inside. The ID is derived from the flow so a re-run finds the
|
|
51
|
+
-- same row, the same way 0002 derived one folder per owner.
|
|
52
|
+
INSERT OR IGNORE INTO knowledge_nodes (
|
|
53
|
+
id, parent_id, kind, title, description, context_policy, owner_id,
|
|
54
|
+
current_version_id, created_at, updated_at, archived_at
|
|
55
|
+
)
|
|
56
|
+
SELECT
|
|
57
|
+
'folder-flow-' || flow.id,
|
|
58
|
+
flow.parent_id,
|
|
59
|
+
'folder',
|
|
60
|
+
flow.title,
|
|
61
|
+
'Holds one flow that was shared on its own before shares moved to the folder.',
|
|
62
|
+
'explicit',
|
|
63
|
+
flow.owner_id,
|
|
64
|
+
NULL,
|
|
65
|
+
'2026-08-01T00:00:00.000Z',
|
|
66
|
+
'2026-08-01T00:00:00.000Z',
|
|
67
|
+
NULL
|
|
68
|
+
FROM flows flow
|
|
69
|
+
WHERE EXISTS (
|
|
70
|
+
SELECT 1 FROM resource_grants grant_row
|
|
71
|
+
WHERE grant_row.resource_type = 'flow' AND grant_row.resource_id = flow.id
|
|
72
|
+
)
|
|
73
|
+
AND flow.parent_id IS NOT 'folder-flow-' || flow.id;
|
|
74
|
+
|
|
75
|
+
UPDATE flows SET parent_id = 'folder-flow-' || id
|
|
76
|
+
WHERE EXISTS (
|
|
77
|
+
SELECT 1 FROM resource_grants grant_row
|
|
78
|
+
WHERE grant_row.resource_type = 'flow' AND grant_row.resource_id = flows.id
|
|
79
|
+
)
|
|
80
|
+
AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || flows.id);
|
|
81
|
+
|
|
82
|
+
-- Seeing a flow and starting it were the same permission until now: any flow grant plus the Gate
|
|
83
|
+
-- `flows/run` capability could start a run. Splitting the two without carrying `execute` over would
|
|
84
|
+
-- quietly take away something people have today, so every migrated flow grant keeps it.
|
|
85
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
86
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
87
|
+
)
|
|
88
|
+
SELECT
|
|
89
|
+
grant_row.id || ':read',
|
|
90
|
+
'folder-flow-' || grant_row.resource_id,
|
|
91
|
+
grant_row.principal_type,
|
|
92
|
+
grant_row.principal_id,
|
|
93
|
+
'read',
|
|
94
|
+
grant_row.expires_at,
|
|
95
|
+
grant_row.created_by,
|
|
96
|
+
grant_row.created_at
|
|
97
|
+
FROM resource_grants grant_row
|
|
98
|
+
WHERE grant_row.resource_type = 'flow'
|
|
99
|
+
AND EXISTS (
|
|
100
|
+
SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
104
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
105
|
+
)
|
|
106
|
+
SELECT
|
|
107
|
+
grant_row.id || ':execute',
|
|
108
|
+
'folder-flow-' || grant_row.resource_id,
|
|
109
|
+
grant_row.principal_type,
|
|
110
|
+
grant_row.principal_id,
|
|
111
|
+
'execute',
|
|
112
|
+
grant_row.expires_at,
|
|
113
|
+
grant_row.created_by,
|
|
114
|
+
grant_row.created_at
|
|
115
|
+
FROM resource_grants grant_row
|
|
116
|
+
WHERE grant_row.resource_type = 'flow'
|
|
117
|
+
AND EXISTS (
|
|
118
|
+
SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
122
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
123
|
+
)
|
|
124
|
+
SELECT
|
|
125
|
+
grant_row.id || ':write',
|
|
126
|
+
'folder-flow-' || grant_row.resource_id,
|
|
127
|
+
grant_row.principal_type,
|
|
128
|
+
grant_row.principal_id,
|
|
129
|
+
'write',
|
|
130
|
+
grant_row.expires_at,
|
|
131
|
+
grant_row.created_by,
|
|
132
|
+
grant_row.created_at
|
|
133
|
+
FROM resource_grants grant_row
|
|
134
|
+
WHERE grant_row.resource_type = 'flow'
|
|
135
|
+
AND grant_row.role IN ('editor', 'manager')
|
|
136
|
+
AND EXISTS (
|
|
137
|
+
SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
141
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
142
|
+
)
|
|
143
|
+
SELECT
|
|
144
|
+
grant_row.id || ':share',
|
|
145
|
+
'folder-flow-' || grant_row.resource_id,
|
|
146
|
+
grant_row.principal_type,
|
|
147
|
+
grant_row.principal_id,
|
|
148
|
+
'share',
|
|
149
|
+
grant_row.expires_at,
|
|
150
|
+
grant_row.created_by,
|
|
151
|
+
grant_row.created_at
|
|
152
|
+
FROM resource_grants grant_row
|
|
153
|
+
WHERE grant_row.resource_type = 'flow'
|
|
154
|
+
AND grant_row.role = 'manager'
|
|
155
|
+
AND EXISTS (
|
|
156
|
+
SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
-- Knowledge grants stay on the node they were set on and keep exactly the verbs their role implied.
|
|
160
|
+
-- `execute` is not among them for any role: a Knowledge grant never allowed anyone to start a run,
|
|
161
|
+
-- and handing it out here would be the wide reading of an unambiguous case. `commenter` has no verb
|
|
162
|
+
-- of its own yet, so it maps to `read` — the least it could have meant.
|
|
163
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
164
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
165
|
+
)
|
|
166
|
+
SELECT
|
|
167
|
+
grant_row.id || ':read',
|
|
168
|
+
grant_row.resource_id,
|
|
169
|
+
grant_row.principal_type,
|
|
170
|
+
grant_row.principal_id,
|
|
171
|
+
'read',
|
|
172
|
+
grant_row.expires_at,
|
|
173
|
+
grant_row.created_by,
|
|
174
|
+
grant_row.created_at
|
|
175
|
+
FROM resource_grants grant_row
|
|
176
|
+
WHERE grant_row.resource_type = 'knowledge'
|
|
177
|
+
AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = grant_row.resource_id);
|
|
178
|
+
|
|
179
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
180
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
181
|
+
)
|
|
182
|
+
SELECT
|
|
183
|
+
grant_row.id || ':write',
|
|
184
|
+
grant_row.resource_id,
|
|
185
|
+
grant_row.principal_type,
|
|
186
|
+
grant_row.principal_id,
|
|
187
|
+
'write',
|
|
188
|
+
grant_row.expires_at,
|
|
189
|
+
grant_row.created_by,
|
|
190
|
+
grant_row.created_at
|
|
191
|
+
FROM resource_grants grant_row
|
|
192
|
+
WHERE grant_row.resource_type = 'knowledge'
|
|
193
|
+
AND grant_row.role IN ('editor', 'manager')
|
|
194
|
+
AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = grant_row.resource_id);
|
|
195
|
+
|
|
196
|
+
INSERT OR IGNORE INTO tree_grants (
|
|
197
|
+
id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
|
|
198
|
+
)
|
|
199
|
+
SELECT
|
|
200
|
+
grant_row.id || ':share',
|
|
201
|
+
grant_row.resource_id,
|
|
202
|
+
grant_row.principal_type,
|
|
203
|
+
grant_row.principal_id,
|
|
204
|
+
'share',
|
|
205
|
+
grant_row.expires_at,
|
|
206
|
+
grant_row.created_by,
|
|
207
|
+
grant_row.created_at
|
|
208
|
+
FROM resource_grants grant_row
|
|
209
|
+
WHERE grant_row.resource_type = 'knowledge'
|
|
210
|
+
AND grant_row.role = 'manager'
|
|
211
|
+
AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = grant_row.resource_id);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- ADR-0004 §3/§4: a flow may call another flow. The called flow gets a run of its own — its own
|
|
2
|
+
-- immutable version, its own steps, its own authorization against the user — and these two columns
|
|
3
|
+
-- are the only thing that ties it back to the step that called it.
|
|
4
|
+
--
|
|
5
|
+
-- A single run row that "descends into" the callee was the alternative. It would have had to carry
|
|
6
|
+
-- two versions at once, and the step history would no longer say which graph a node belonged to.
|
|
7
|
+
|
|
8
|
+
ALTER TABLE flow_runs ADD COLUMN parent_run_id TEXT REFERENCES flow_runs(id);
|
|
9
|
+
ALTER TABLE flow_runs ADD COLUMN parent_node_id TEXT;
|
|
10
|
+
|
|
11
|
+
-- One call site starts at most one run: the index is unique so a retried start cannot leave two
|
|
12
|
+
-- results behind for the same step, with nothing to say which one flows back.
|
|
13
|
+
CREATE UNIQUE INDEX flow_runs_call_site_idx ON flow_runs(parent_run_id, parent_node_id)
|
|
14
|
+
WHERE parent_run_id IS NOT NULL;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-- #39. Two fields leave the flow graph, so the graphs already in the table are rewritten to match
|
|
2
|
+
-- the contract that will read them. Both are removals of things that never did anything, which is
|
|
3
|
+
-- why the rewrite can be unconditional rather than a decision per flow.
|
|
4
|
+
--
|
|
5
|
+
-- `description` on a node: a node has a title, and what it should do stands in the instruction. Two
|
|
6
|
+
-- free texts beside each other were both kept half up to date.
|
|
7
|
+
--
|
|
8
|
+
-- A trigger's mode: `webhook` and `schedule` triggered nothing and, after the decision in #32, never
|
|
9
|
+
-- will — a flow is carried out by an external agent that brings its own schedule. `manual` is the
|
|
10
|
+
-- honest reading of every trigger that is stored today, because manual is what all of them did.
|
|
11
|
+
--
|
|
12
|
+
-- ⚠️ Written as one pass over the node array rather than a targeted UPDATE: `json_remove` is a no-op
|
|
13
|
+
-- where the key is absent, so re-running this changes nothing. Only `flow_versions` holds a graph.
|
|
14
|
+
UPDATE flow_versions
|
|
15
|
+
SET graph_json = json_set(
|
|
16
|
+
graph_json,
|
|
17
|
+
'$.nodes',
|
|
18
|
+
(
|
|
19
|
+
SELECT json_group_array(
|
|
20
|
+
CASE
|
|
21
|
+
WHEN json_extract(node.value, '$.kind') = 'trigger'
|
|
22
|
+
THEN json_set(json_remove(node.value, '$.description'), '$.configuration', json_object('mode', 'manual'))
|
|
23
|
+
ELSE json_remove(node.value, '$.description')
|
|
24
|
+
END
|
|
25
|
+
)
|
|
26
|
+
FROM json_each(flow_versions.graph_json, '$.nodes') AS node
|
|
27
|
+
)
|
|
28
|
+
);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
-- #40: a fourth kind in the shared tree — `table`. It is a node like the other three: same
|
|
2
|
+
-- `parent_id`, same folder grants, same immutable `knowledge_versions` rows, same R2 body
|
|
3
|
+
-- (ADR-0004 §1). Nothing here creates a second content model; only the CHECK has to learn the word.
|
|
4
|
+
--
|
|
5
|
+
-- SQLite cannot alter a CHECK constraint, so the table is rebuilt. The rebuild is written the long
|
|
6
|
+
-- way round, and both detours are here because the short way was tried and D1 rolled it back. The
|
|
7
|
+
-- table this migration leaves behind is the same one either way — same columns, same constraints,
|
|
8
|
+
-- same indexes — so an installation that already applied this file keeps exactly what it has.
|
|
9
|
+
--
|
|
10
|
+
-- ⚠️ First detour: the new table is created under the final name rather than built beside the old
|
|
11
|
+
-- one and renamed over it. `DROP TABLE` on a parent runs an implicit `DELETE FROM` first, so the
|
|
12
|
+
-- moment the old `knowledge_nodes` goes, every row of `knowledge_versions`, `tree_grants` and
|
|
13
|
+
-- `flows` pointing at a node is a foreign-key violation. `defer_foreign_keys` postpones the
|
|
14
|
+
-- complaint to COMMIT but does not withdraw it, and `ALTER TABLE ... RENAME` does not settle it
|
|
15
|
+
-- either: a rename puts the name back, not the rows. Only inserting the nodes again, under the name
|
|
16
|
+
-- the children have referenced all along, does. On an empty database none of this is visible —
|
|
17
|
+
-- nothing points at anything — which is precisely how the first version passed a green test suite
|
|
18
|
+
-- and then failed against the first database that had content in it.
|
|
19
|
+
--
|
|
20
|
+
-- ⚠️ Second detour: `knowledge_links` is the only child of `knowledge_nodes` declared ON DELETE
|
|
21
|
+
-- CASCADE, so that same implicit delete does not merely flag its rows, it removes them — the
|
|
22
|
+
-- migration would have committed with every relationship between two documents quietly gone. The
|
|
23
|
+
-- rows are carried out of the way first and put back afterwards. That is a rescue, not a decision
|
|
24
|
+
-- about the data: nothing is dropped, rewritten or reinterpreted here.
|
|
25
|
+
PRAGMA defer_foreign_keys = TRUE;
|
|
26
|
+
|
|
27
|
+
-- Plain holding tables on purpose: no keys, no CHECKs, no foreign keys, and the column set taken
|
|
28
|
+
-- from whatever the live table has. Anything enforced here would only be enforced a second time on
|
|
29
|
+
-- the way back in, and a holding table that can reject a row is a holding table that can lose one.
|
|
30
|
+
CREATE TABLE knowledge_nodes_carry AS SELECT * FROM knowledge_nodes;
|
|
31
|
+
CREATE TABLE knowledge_links_carry AS SELECT * FROM knowledge_links;
|
|
32
|
+
|
|
33
|
+
DROP TABLE knowledge_nodes;
|
|
34
|
+
|
|
35
|
+
CREATE TABLE knowledge_nodes (
|
|
36
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
37
|
+
parent_id TEXT REFERENCES knowledge_nodes(id),
|
|
38
|
+
kind TEXT NOT NULL CHECK (kind IN ('folder', 'document', 'attachment', 'table')),
|
|
39
|
+
title TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 240),
|
|
40
|
+
description TEXT CHECK (description IS NULL OR length(description) <= 2000),
|
|
41
|
+
context_policy TEXT NOT NULL CHECK (context_policy IN ('pinned', 'relevant', 'explicit')),
|
|
42
|
+
owner_id TEXT NOT NULL,
|
|
43
|
+
current_version_id TEXT,
|
|
44
|
+
created_at TEXT NOT NULL,
|
|
45
|
+
updated_at TEXT NOT NULL,
|
|
46
|
+
archived_at TEXT
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
INSERT INTO knowledge_nodes (
|
|
50
|
+
id, parent_id, kind, title, description, context_policy, owner_id,
|
|
51
|
+
current_version_id, created_at, updated_at, archived_at
|
|
52
|
+
)
|
|
53
|
+
SELECT
|
|
54
|
+
id, parent_id, kind, title, description, context_policy, owner_id,
|
|
55
|
+
current_version_id, created_at, updated_at, archived_at
|
|
56
|
+
FROM knowledge_nodes_carry;
|
|
57
|
+
|
|
58
|
+
-- `OR IGNORE` because whether the cascade above actually fired is SQLite's business, not this
|
|
59
|
+
-- migration's: if it did, this puts the rows back; if it did not, each one is already present under
|
|
60
|
+
-- the same primary key and this is a no-op. Either way `knowledge_links` ends up holding exactly
|
|
61
|
+
-- what it held before, which is the only outcome this statement is permitted to have.
|
|
62
|
+
INSERT OR IGNORE INTO knowledge_links SELECT * FROM knowledge_links_carry;
|
|
63
|
+
|
|
64
|
+
DROP TABLE knowledge_nodes_carry;
|
|
65
|
+
DROP TABLE knowledge_links_carry;
|
|
66
|
+
|
|
67
|
+
CREATE INDEX knowledge_nodes_parent_idx ON knowledge_nodes(parent_id, archived_at, title);
|
|
68
|
+
CREATE INDEX knowledge_nodes_owner_idx ON knowledge_nodes(owner_id, archived_at);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- #41: a relationship between two documents is written where it is meant — in the text — and the
|
|
2
|
+
-- dialog that used to create one is gone. Saving a document now rewrites the links it contains.
|
|
3
|
+
--
|
|
4
|
+
-- That rewrite must not touch the links people made in the dialog before there was another way, so
|
|
5
|
+
-- every link learns where it came from. Existing rows are `manual`: they are history, they stay
|
|
6
|
+
-- readable as outgoing links and as backlinks, and nothing writes another one.
|
|
7
|
+
--
|
|
8
|
+
-- Deliberately not a migration of the data. Rewriting the old `relation` values into one kind, or
|
|
9
|
+
-- deleting the rows outright, would throw away a distinction somebody chose on purpose; keeping the
|
|
10
|
+
-- column costs nothing and keeps every existing relationship exactly as it was.
|
|
11
|
+
--
|
|
12
|
+
-- SQLite cannot add a CHECK with ALTER TABLE, so the constraint on this column lives in the
|
|
13
|
+
-- contract (`KnowledgeLinkOrigin`) and in the one repository method that writes it. There is no
|
|
14
|
+
-- table rebuild for it: `knowledge_links` is the target of no foreign key, but it is the source of
|
|
15
|
+
-- two, and a rebuild would be a lot of risk for a constraint the only writer already enforces.
|
|
16
|
+
ALTER TABLE knowledge_links ADD COLUMN origin TEXT NOT NULL DEFAULT 'manual';
|
|
17
|
+
|
|
18
|
+
-- The reconciliation on save reads and deletes by source and origin, and the backlink list reads by
|
|
19
|
+
-- target; both existing indexes stay useful, and this one keeps the delete off a table scan.
|
|
20
|
+
CREATE INDEX knowledge_links_origin_idx ON knowledge_links(source_node_id, origin);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
-- #73. The approval node leaves the contract, so the graphs already stored are rewritten to match
|
|
2
|
+
-- the schema that will read them. Without this an `approval` node makes `FlowGraph.parse` throw in
|
|
3
|
+
-- `db-flows.ts`, and the flow cannot be opened at all — not even to repair it. A removal that locks
|
|
4
|
+
-- people out of their own flows is worse than the node it removes.
|
|
5
|
+
--
|
|
6
|
+
-- ⚠️ Rewritten to a `condition`, not deleted. The node has two outgoing branches, and deleting it
|
|
7
|
+
-- would leave two edges pointing nowhere and a graph that fails `compileFlow` for a second reason.
|
|
8
|
+
-- A condition is the honest replacement: it branches the same way, and the question the approval
|
|
9
|
+
-- asked — "may this go ahead?" — is one the agent carrying out the run can answer. The prompt is
|
|
10
|
+
-- carried over into the instruction rather than dropped, so the author still reads what was meant.
|
|
11
|
+
-- `timeout` disappears with the waiting it configured (D24).
|
|
12
|
+
--
|
|
13
|
+
-- ⚠️ The branch handles are rewritten with it: an approval branched on `approved`/`rejected`, a
|
|
14
|
+
-- condition on `yes`/`no`. Left alone, `completeStep` would look for a handle that no edge carries
|
|
15
|
+
-- and every run through that node would answer 400.
|
|
16
|
+
--
|
|
17
|
+
-- ⚠️ One pass over the arrays rather than targeted updates, for the same reason as 0005: re-running
|
|
18
|
+
-- must change nothing. A graph with no approval node is written back identical to itself.
|
|
19
|
+
UPDATE flow_versions
|
|
20
|
+
SET graph_json = json_set(
|
|
21
|
+
json_set(
|
|
22
|
+
graph_json,
|
|
23
|
+
'$.nodes',
|
|
24
|
+
(
|
|
25
|
+
SELECT json_group_array(
|
|
26
|
+
CASE
|
|
27
|
+
WHEN json_extract(node.value, '$.kind') = 'approval'
|
|
28
|
+
THEN json_set(
|
|
29
|
+
json_set(node.value, '$.kind', 'condition'),
|
|
30
|
+
'$.configuration',
|
|
31
|
+
json_object(
|
|
32
|
+
'mode', 'semantic',
|
|
33
|
+
'instruction', json_extract(node.value, '$.configuration.prompt')
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
ELSE node.value
|
|
37
|
+
END
|
|
38
|
+
)
|
|
39
|
+
FROM json_each(flow_versions.graph_json, '$.nodes') AS node
|
|
40
|
+
)
|
|
41
|
+
),
|
|
42
|
+
'$.edges',
|
|
43
|
+
(
|
|
44
|
+
SELECT json_group_array(
|
|
45
|
+
CASE json_extract(edge.value, '$.sourceHandle')
|
|
46
|
+
WHEN 'approved' THEN json_set(edge.value, '$.sourceHandle', 'yes')
|
|
47
|
+
WHEN 'rejected' THEN json_set(edge.value, '$.sourceHandle', 'no')
|
|
48
|
+
ELSE edge.value
|
|
49
|
+
END
|
|
50
|
+
)
|
|
51
|
+
FROM json_each(flow_versions.graph_json, '$.edges') AS edge
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
WHERE EXISTS (
|
|
55
|
+
SELECT 1 FROM json_each(flow_versions.graph_json, '$.nodes') AS node
|
|
56
|
+
WHERE json_extract(node.value, '$.kind') = 'approval'
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
-- `waiting` was written for the approval node and never set by anything: the two places that tested
|
|
60
|
+
-- for it only ever saw `running`. It leaves `FlowRunStatus`, so a row carrying it would become a
|
|
61
|
+
-- status the contract cannot parse. There should be none — this makes that true rather than hoped.
|
|
62
|
+
--
|
|
63
|
+
-- The column's CHECK constraint still allows the value, deliberately: changing it means rebuilding
|
|
64
|
+
-- the table in D1 for a value nothing writes.
|
|
65
|
+
UPDATE flow_runs
|
|
66
|
+
SET status = 'failed',
|
|
67
|
+
error = 'Flow run was waiting for an approval that no longer exists',
|
|
68
|
+
completed_at = COALESCE(completed_at, updated_at)
|
|
69
|
+
WHERE status = 'waiting';
|