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