@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,143 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const IntelId = z.string().min(1).max(128);
|
|
3
|
+
export const IsoDateTime = z.iso.datetime({ offset: true });
|
|
4
|
+
// ⚠️ One described primitive rather than the same sentence on twenty-odd fields (#398). The word
|
|
5
|
+
// `idempotencyKey` means exactly the same thing everywhere it appears, and a reader who learns it
|
|
6
|
+
// once at `node_create` should not have to re-read it at `flow_publish`. Twenty copies of one
|
|
7
|
+
// sentence is also twenty places for it to drift, and `tools/list` would carry every copy.
|
|
8
|
+
//
|
|
9
|
+
// The description says what the caller has to DO, because that is the part a model gets wrong: it
|
|
10
|
+
// invents a fresh key on the retry and creates the thing twice.
|
|
11
|
+
export const IdempotencyKey = z
|
|
12
|
+
.string()
|
|
13
|
+
.min(8)
|
|
14
|
+
.max(200)
|
|
15
|
+
.describe("A caller-chosen key that makes this call safe to retry: repeating the same key returns the first result instead of doing the work twice. Reuse the SAME key when retrying one attempt, and a new one for a genuinely new call.");
|
|
16
|
+
/**
|
|
17
|
+
* The short name a document or a published flow is offered under as a slash command (#775).
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ One described primitive rather than the same sentence in two files, for the reason
|
|
20
|
+
* `IdempotencyKey` above gives: a document and a flow take the same kind of name out of the same
|
|
21
|
+
* catalogue, and a copy would be a second place for one sentence to drift. It sits here rather than
|
|
22
|
+
* in `node.ts` because `flow.ts` states it too, and this is the file both may read.
|
|
23
|
+
*
|
|
24
|
+
* ⚠️ The refusal spells the GRAMMAR, not the verdict. Zod's own `Invalid` tells a caller who sent
|
|
25
|
+
* `CRM Outreach` that something was wrong and not what would have worked, and the one thing they
|
|
26
|
+
* need is that the answer is `crm-outreach`.
|
|
27
|
+
*
|
|
28
|
+
* ⚠️ Uniqueness is NOT in this schema and cannot be: it is a question about the whole installation,
|
|
29
|
+
* across documents and flows at once, and it is answered where the write happens. A name another
|
|
30
|
+
* node or flow already holds is refused by name there, never quietly turned into a second one.
|
|
31
|
+
*/
|
|
32
|
+
export const PromptName = z
|
|
33
|
+
.string()
|
|
34
|
+
.regex(/^[a-z0-9-]{1,40}$/, {
|
|
35
|
+
error: "A prompt name is 1 to 40 characters of lowercase letters, digits and hyphens, and nothing else: `crm-outreach`.",
|
|
36
|
+
})
|
|
37
|
+
.describe("The slash command this is offered under, written without the leading slash: `crm-outreach` reaches a client as `/crm-outreach`. Lowercase letters, digits and hyphens only, and unique over every document and flow in the installation — a name one of them already holds is refused and names its holder, never silently changed into another one.");
|
|
38
|
+
/**
|
|
39
|
+
* The version a write is made against, in the one form every writer of versioned content takes it.
|
|
40
|
+
*
|
|
41
|
+
* ⚠️ It lived beside the two node writers until #459 and moved here when the flow graph became the
|
|
42
|
+
* third — the point at which the repository stops copying and names the thing. It could not simply
|
|
43
|
+
* be imported: `flow.ts` may not depend on `node.ts` (the graph is `table → node`, `flow-run →
|
|
44
|
+
* flow`, and everything → here), and a copy would have been a second place for one sentence to
|
|
45
|
+
* drift, which is exactly what `IdempotencyKey` above exists to avoid.
|
|
46
|
+
*
|
|
47
|
+
* ⚠️ Nullable and required are not the same thing, and here they stand together (#437). `null` is
|
|
48
|
+
* how something that has no version yet is addressed, and it is the only way to write its first
|
|
49
|
+
* content; leaving the field out says nothing at all and is refused. Whoever leaves it out is
|
|
50
|
+
* almost always holding a node or a flow created one call earlier, and the plain type error they
|
|
51
|
+
* used to get — "expected string, received undefined" — reads as "this field must be an id", about
|
|
52
|
+
* a field that cannot have one yet. Both refusals therefore name both ways instead.
|
|
53
|
+
*
|
|
54
|
+
* ⚠️ It stays required once a version exists, and that is what it is for: a mismatch is answered
|
|
55
|
+
* with a `409` rather than by overwriting somebody else's newer version. Making it `optional()` to
|
|
56
|
+
* smooth the first write is the repair that breaks the guard — an absent field would then have to
|
|
57
|
+
* mean "there is none", and the forgetful caller silently replaces the newest one.
|
|
58
|
+
*
|
|
59
|
+
* ⚠️ The bounds remain `IntelId`'s. The repeated `min(1)` adds no rule — it only puts the sentence
|
|
60
|
+
* on the second value that gets tried after `undefined`, the empty string.
|
|
61
|
+
*
|
|
62
|
+
* ⚠️ The sentence says what the field TAKES, not what the caller did wrong. It answers a wrong type
|
|
63
|
+
* as well as an absent field, and "is required" would be false about the first — which would be
|
|
64
|
+
* this same ticket one corner further on. A value that is merely too long keeps Zod's own `Too
|
|
65
|
+
* big`: that one is already a true statement about what was sent.
|
|
66
|
+
*
|
|
67
|
+
* ⚠️ The JSON Schema it produces is the one `IntelId.nullable()` produced — an `anyOf` of the
|
|
68
|
+
* bounded string and `null`, still `required` — so nothing on the MCP surface moves when a field
|
|
69
|
+
* changes over to it.
|
|
70
|
+
*/
|
|
71
|
+
export function baseVersion(rule) {
|
|
72
|
+
return z.union([IntelId.min(1, { error: rule }), z.null()], { error: rule });
|
|
73
|
+
}
|
|
74
|
+
// The languages whose UI catalog ships inside the surface. They live here rather than only in the UI
|
|
75
|
+
// because `intel build` has to know them: a built-in language may be chosen as `ui.defaultLanguage`
|
|
76
|
+
// without the customer listing a copy under `ui.languages` that would rot at every UI update.
|
|
77
|
+
//
|
|
78
|
+
// ⚠️ The list is a claim about the contents of packages/intel/ui/src/i18n and cannot be checked here.
|
|
79
|
+
// `i18n.unit.ts` compares it against the catalogs actually built in; a language listed here without
|
|
80
|
+
// a file gives a red run there instead of a UI that starts on a catalog which does not exist.
|
|
81
|
+
export const UI_LANGUAGES = ["en", "de", "es"];
|
|
82
|
+
/**
|
|
83
|
+
* A set of things the reader is only partly entitled to see: the ones they may see BY NAME, the
|
|
84
|
+
* rest as a NUMBER (ADR-0004 §3). Never the titles of the rest, in any field, ever — a warning or a
|
|
85
|
+
* refusal must not become a way of reading the tree.
|
|
86
|
+
*
|
|
87
|
+
* ⚠️ It lives here rather than in `share.ts` because two domains state it: a grant says what it
|
|
88
|
+
* does not reach (`UnreadableNodes`), and a refusal says who is still calling in
|
|
89
|
+
* (`ProblemDetails.callers`, #448). `contract.ts` may not import from `share.ts` — the graph
|
|
90
|
+
* between these files has to stay acyclic — and a copy would be a second place for one rule to
|
|
91
|
+
* drift, which is what `IdempotencyKey` and `baseVersion` above exist against.
|
|
92
|
+
*/
|
|
93
|
+
export const NamedOrCounted = z.strictObject({
|
|
94
|
+
titles: z.array(z.string().min(1).max(240)),
|
|
95
|
+
hidden: z.number().int().nonnegative(),
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* ⚠️ `callers` is the one member here that is not about every problem, and it is deliberate (#448).
|
|
99
|
+
* RFC 9457 allows extension members for exactly this: `folder_execute_in_use` refuses to narrow a
|
|
100
|
+
* library folder while flows from outside still call into it, and the CALLERS are the only thing
|
|
101
|
+
* that makes the refusal actionable. They used to exist only inside `detail` — an English sentence
|
|
102
|
+
* built on the server — so a German or Spanish surface could do nothing but print it verbatim, and
|
|
103
|
+
* no surface could shorten it or link the titles.
|
|
104
|
+
*
|
|
105
|
+
* The split is the point: the server decides WHAT is named and what is only counted, because that
|
|
106
|
+
* is an authorization answer nobody else can give; the surface decides how the sentence READS,
|
|
107
|
+
* because that is a language answer no server can give.
|
|
108
|
+
*
|
|
109
|
+
* `detail` keeps its sentence rather than emptying out — MCP hands a model prose and has nothing to
|
|
110
|
+
* formulate with, and an empty `detail` beside a new field would be the worst of the three states.
|
|
111
|
+
* It is absent on every other problem, so a reader must not treat its presence as guaranteed.
|
|
112
|
+
*/
|
|
113
|
+
export const ProblemDetails = z.strictObject({
|
|
114
|
+
type: z.string(),
|
|
115
|
+
status: z.number().int().min(400).max(599),
|
|
116
|
+
title: z.string(),
|
|
117
|
+
detail: z.string().optional(),
|
|
118
|
+
instance: z.string().optional(),
|
|
119
|
+
code: z.string().optional(),
|
|
120
|
+
callers: NamedOrCounted.optional(),
|
|
121
|
+
});
|
|
122
|
+
// Who the caller is, as Gate resolved it from the bearer: no token, and no capability list.
|
|
123
|
+
//
|
|
124
|
+
// ⚠️ `isAdmin` is the one exception, and it is a DRAWING instruction rather than a permission
|
|
125
|
+
// (#416). MCP hides what a caller may not do by never registering the tool, so a model never sees a
|
|
126
|
+
// door it cannot open; the browser has no equivalent and would have to offer an admin action to
|
|
127
|
+
// everybody and answer with a 403. One boolean is what the shell needs to not do that.
|
|
128
|
+
//
|
|
129
|
+
// Two things keep it from becoming a capability list by degrees: it says what the shell may DRAW,
|
|
130
|
+
// never what the server may do — every door still asks Gate itself — and it is one field with one
|
|
131
|
+
// consumer. A second one is a second reason, written down when it exists.
|
|
132
|
+
export const SessionUser = z.strictObject({
|
|
133
|
+
id: IntelId,
|
|
134
|
+
email: z.email(),
|
|
135
|
+
name: z.string().min(1).max(240).nullable(),
|
|
136
|
+
isAdmin: z.boolean(),
|
|
137
|
+
});
|
|
138
|
+
// One reference, never a list. The old `knowledge` node carried up to a hundred, plus a retrieval
|
|
139
|
+
// mode and a query that nothing read — three things in one, and the last two describing a retrieval
|
|
140
|
+
// Intel does not perform (D24: the agent fetches, Intel does not put anything into a context).
|
|
141
|
+
// Splitting by kind is what makes "exactly one" sayable at all, and it lets the editor filter the
|
|
142
|
+
// picker by what the node is for.
|
|
143
|
+
export const LinkConfiguration = z.strictObject({ resourceId: IntelId });
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const FeedAction: z.ZodEnum<{
|
|
3
|
+
"node.create": "node.create";
|
|
4
|
+
"node.save": "node.save";
|
|
5
|
+
"node.append": "node.append";
|
|
6
|
+
"node.update": "node.update";
|
|
7
|
+
"node.archive": "node.archive";
|
|
8
|
+
"node.share": "node.share";
|
|
9
|
+
"node.revoke": "node.revoke";
|
|
10
|
+
"flows.create": "flows.create";
|
|
11
|
+
"flows.update": "flows.update";
|
|
12
|
+
"flows.archive": "flows.archive";
|
|
13
|
+
"flows.save": "flows.save";
|
|
14
|
+
"flows.publish": "flows.publish";
|
|
15
|
+
"flows.complete": "flows.complete";
|
|
16
|
+
"flows.cancel": "flows.cancel";
|
|
17
|
+
"flows.unpublish": "flows.unpublish";
|
|
18
|
+
"flows.share": "flows.share";
|
|
19
|
+
"flows.revoke": "flows.revoke";
|
|
20
|
+
"node.purge": "node.purge";
|
|
21
|
+
"flows.purge": "flows.purge";
|
|
22
|
+
}>;
|
|
23
|
+
export type FeedAction = z.infer<typeof FeedAction>;
|
|
24
|
+
/**
|
|
25
|
+
* What an entry is about. Derived from the action rather than carried separately: the two can then
|
|
26
|
+
* never disagree, and a reader that has to draw a flow differently from a document does not depend
|
|
27
|
+
* on a second field being filled in correctly.
|
|
28
|
+
*/
|
|
29
|
+
export declare function feedKindOf(action: FeedAction): "node" | "flow";
|
|
30
|
+
/**
|
|
31
|
+
* Which `resource_type` the journal wrote an action against — a different question from
|
|
32
|
+
* `feedKindOf`, and the two answers disagree on purpose for exactly two actions (#767).
|
|
33
|
+
*
|
|
34
|
+
* A card about a finished run is a card about a **flow**: that is what it names, that is where it
|
|
35
|
+
* links, and `feedKindOf` says so. But the ROW it was written as carries `flow-run` and the run's
|
|
36
|
+
* id, so the query has to find it under a third kind and walk run → flow → folder to decide whether
|
|
37
|
+
* it may be seen.
|
|
38
|
+
*
|
|
39
|
+
* ⚠️ Derived here rather than written out beside the SQL. A second list that has to agree with this
|
|
40
|
+
* one is a second list too many — the same reason `NODE_ACTIONS` and `FLOW_ACTIONS` are filtered
|
|
41
|
+
* out of `FeedAction.options` instead of being typed again.
|
|
42
|
+
*/
|
|
43
|
+
export declare function feedResourceTypeOf(action: FeedAction): "node" | "flow" | "flow-run";
|
|
44
|
+
export declare const FeedPathSegment: z.ZodObject<{
|
|
45
|
+
id: z.ZodString;
|
|
46
|
+
title: z.ZodString;
|
|
47
|
+
}, z.core.$strict>;
|
|
48
|
+
export type FeedPathSegment = z.infer<typeof FeedPathSegment>;
|
|
49
|
+
export declare const FeedEvent: z.ZodObject<{
|
|
50
|
+
id: z.ZodString;
|
|
51
|
+
actorId: z.ZodString;
|
|
52
|
+
action: z.ZodEnum<{
|
|
53
|
+
"node.create": "node.create";
|
|
54
|
+
"node.save": "node.save";
|
|
55
|
+
"node.append": "node.append";
|
|
56
|
+
"node.update": "node.update";
|
|
57
|
+
"node.archive": "node.archive";
|
|
58
|
+
"node.share": "node.share";
|
|
59
|
+
"node.revoke": "node.revoke";
|
|
60
|
+
"flows.create": "flows.create";
|
|
61
|
+
"flows.update": "flows.update";
|
|
62
|
+
"flows.archive": "flows.archive";
|
|
63
|
+
"flows.save": "flows.save";
|
|
64
|
+
"flows.publish": "flows.publish";
|
|
65
|
+
"flows.complete": "flows.complete";
|
|
66
|
+
"flows.cancel": "flows.cancel";
|
|
67
|
+
"flows.unpublish": "flows.unpublish";
|
|
68
|
+
"flows.share": "flows.share";
|
|
69
|
+
"flows.revoke": "flows.revoke";
|
|
70
|
+
"node.purge": "node.purge";
|
|
71
|
+
"flows.purge": "flows.purge";
|
|
72
|
+
}>;
|
|
73
|
+
resourceId: z.ZodString;
|
|
74
|
+
resourceTitle: z.ZodString;
|
|
75
|
+
path: z.ZodArray<z.ZodObject<{
|
|
76
|
+
id: z.ZodString;
|
|
77
|
+
title: z.ZodString;
|
|
78
|
+
}, z.core.$strict>>;
|
|
79
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
80
|
+
occurredAt: z.ZodISODateTime;
|
|
81
|
+
}, z.core.$strict>;
|
|
82
|
+
export type FeedEvent = z.infer<typeof FeedEvent>;
|
|
83
|
+
export declare const FeedCursor: z.ZodString;
|
|
84
|
+
export declare const FeedListRequest: z.ZodObject<{
|
|
85
|
+
actor: z.ZodOptional<z.ZodString>;
|
|
86
|
+
before: z.ZodOptional<z.ZodString>;
|
|
87
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
88
|
+
}, z.core.$strict>;
|
|
89
|
+
export type FeedListRequest = z.infer<typeof FeedListRequest>;
|
|
90
|
+
export declare const FeedListResponse: z.ZodObject<{
|
|
91
|
+
events: z.ZodArray<z.ZodObject<{
|
|
92
|
+
id: z.ZodString;
|
|
93
|
+
actorId: z.ZodString;
|
|
94
|
+
action: z.ZodEnum<{
|
|
95
|
+
"node.create": "node.create";
|
|
96
|
+
"node.save": "node.save";
|
|
97
|
+
"node.append": "node.append";
|
|
98
|
+
"node.update": "node.update";
|
|
99
|
+
"node.archive": "node.archive";
|
|
100
|
+
"node.share": "node.share";
|
|
101
|
+
"node.revoke": "node.revoke";
|
|
102
|
+
"flows.create": "flows.create";
|
|
103
|
+
"flows.update": "flows.update";
|
|
104
|
+
"flows.archive": "flows.archive";
|
|
105
|
+
"flows.save": "flows.save";
|
|
106
|
+
"flows.publish": "flows.publish";
|
|
107
|
+
"flows.complete": "flows.complete";
|
|
108
|
+
"flows.cancel": "flows.cancel";
|
|
109
|
+
"flows.unpublish": "flows.unpublish";
|
|
110
|
+
"flows.share": "flows.share";
|
|
111
|
+
"flows.revoke": "flows.revoke";
|
|
112
|
+
"node.purge": "node.purge";
|
|
113
|
+
"flows.purge": "flows.purge";
|
|
114
|
+
}>;
|
|
115
|
+
resourceId: z.ZodString;
|
|
116
|
+
resourceTitle: z.ZodString;
|
|
117
|
+
path: z.ZodArray<z.ZodObject<{
|
|
118
|
+
id: z.ZodString;
|
|
119
|
+
title: z.ZodString;
|
|
120
|
+
}, z.core.$strict>>;
|
|
121
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
122
|
+
occurredAt: z.ZodISODateTime;
|
|
123
|
+
}, z.core.$strict>>;
|
|
124
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
125
|
+
}, z.core.$strict>;
|
|
126
|
+
export type FeedListResponse = z.infer<typeof FeedListResponse>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { IntelId, IsoDateTime } from "./contract.js";
|
|
3
|
+
// What a person did, in the words a person would use. This is a POSITIVE LIST and not the set of
|
|
4
|
+
// actions the journal carries (#740).
|
|
5
|
+
//
|
|
6
|
+
// ⚠️ Two omissions are the point of the list, not an oversight. `node.version` is written by the
|
|
7
|
+
// same batch as `node.save`, so admitting both would show every edit twice — and because this feed
|
|
8
|
+
// does not group anything yet, twice means two cards. `node.link` and `node.import` are machine
|
|
9
|
+
// traces of a save rather than something anybody did.
|
|
10
|
+
//
|
|
11
|
+
// ⚠️ And it stays a positive list. "Everything except" would silently admit whatever the next
|
|
12
|
+
// migration starts writing, on a surface whose whole job is to be readable.
|
|
13
|
+
export const FeedAction = z.enum([
|
|
14
|
+
"node.create",
|
|
15
|
+
"node.save",
|
|
16
|
+
"node.update",
|
|
17
|
+
"node.append",
|
|
18
|
+
"node.archive",
|
|
19
|
+
// ⚠️ The one event whose node no longer exists when it is read. Its visibility runs over the
|
|
20
|
+
// surviving folder, from `parentId` in the metadata, and its title comes from there too — the row
|
|
21
|
+
// it would have been read from is gone (#645).
|
|
22
|
+
"node.purge",
|
|
23
|
+
"node.share",
|
|
24
|
+
"node.revoke",
|
|
25
|
+
// The flow half (#763). Twelve kinds are written; these are the ones a person did rather than a
|
|
26
|
+
// machine bookkeeping step.
|
|
27
|
+
//
|
|
28
|
+
// ⚠️ **`flows.run` is deliberately NOT here, and its two siblings are** (#767, Jacks Entscheidung
|
|
29
|
+
// 2026-08-24). A run writes up to three events, and an agent runs often — without summarising,
|
|
30
|
+
// which #742 struck, twenty runs on one morning would be sixty cards and every human entry would
|
|
31
|
+
// lie buried under them.
|
|
32
|
+
//
|
|
33
|
+
// The END was chosen over the START, and not because it is cheaper: a finished run carries BOTH
|
|
34
|
+
// pieces — that it ran *and* how it went — while a start carries half of one. A run that hangs or
|
|
35
|
+
// fails looks exactly like one that sailed through, and that is the case somebody opens the feed
|
|
36
|
+
// for. What it costs is that a long run is invisible until it ends; that is the deliberate price
|
|
37
|
+
// of needing no merge over the run id, which is the only way a start-card could later be updated.
|
|
38
|
+
//
|
|
39
|
+
// ⚠️ These two are the only actions in this list written against `resource_type = 'flow-run'`,
|
|
40
|
+
// with the RUN's id — which is why `feedResourceTypeOf` exists below and why the query needs a
|
|
41
|
+
// third visibility walk (run → flow → folder) and a title read from the flow.
|
|
42
|
+
"flows.complete",
|
|
43
|
+
"flows.cancel",
|
|
44
|
+
"flows.create",
|
|
45
|
+
"flows.save",
|
|
46
|
+
"flows.update",
|
|
47
|
+
"flows.publish",
|
|
48
|
+
"flows.unpublish",
|
|
49
|
+
"flows.archive",
|
|
50
|
+
"flows.share",
|
|
51
|
+
"flows.revoke",
|
|
52
|
+
// ⚠️ The flow-side twin of `node.purge`, and it carries the same two consequences: its row is
|
|
53
|
+
// gone when the card is read, so both its visibility and its title come from the metadata of the
|
|
54
|
+
// event itself (#763, D73).
|
|
55
|
+
"flows.purge",
|
|
56
|
+
]);
|
|
57
|
+
/**
|
|
58
|
+
* What an entry is about. Derived from the action rather than carried separately: the two can then
|
|
59
|
+
* never disagree, and a reader that has to draw a flow differently from a document does not depend
|
|
60
|
+
* on a second field being filled in correctly.
|
|
61
|
+
*/
|
|
62
|
+
export function feedKindOf(action) {
|
|
63
|
+
return action.startsWith("flows.") ? "flow" : "node";
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Which `resource_type` the journal wrote an action against — a different question from
|
|
67
|
+
* `feedKindOf`, and the two answers disagree on purpose for exactly two actions (#767).
|
|
68
|
+
*
|
|
69
|
+
* A card about a finished run is a card about a **flow**: that is what it names, that is where it
|
|
70
|
+
* links, and `feedKindOf` says so. But the ROW it was written as carries `flow-run` and the run's
|
|
71
|
+
* id, so the query has to find it under a third kind and walk run → flow → folder to decide whether
|
|
72
|
+
* it may be seen.
|
|
73
|
+
*
|
|
74
|
+
* ⚠️ Derived here rather than written out beside the SQL. A second list that has to agree with this
|
|
75
|
+
* one is a second list too many — the same reason `NODE_ACTIONS` and `FLOW_ACTIONS` are filtered
|
|
76
|
+
* out of `FeedAction.options` instead of being typed again.
|
|
77
|
+
*/
|
|
78
|
+
export function feedResourceTypeOf(action) {
|
|
79
|
+
if (action === "flows.complete" || action === "flows.cancel")
|
|
80
|
+
return "flow-run";
|
|
81
|
+
return feedKindOf(action);
|
|
82
|
+
}
|
|
83
|
+
// One step on the way down to the node, from the root. It carries the id as well as the title
|
|
84
|
+
// because the surface links each step, and two folders may share a name.
|
|
85
|
+
export const FeedPathSegment = z.strictObject({
|
|
86
|
+
id: IntelId,
|
|
87
|
+
title: z.string().min(1),
|
|
88
|
+
});
|
|
89
|
+
// One card's worth of journal.
|
|
90
|
+
//
|
|
91
|
+
// ⚠️ `resourceTitle` and `path` are read from `nodes` or `flows` at query time, so they are TODAY's
|
|
92
|
+
// title and today's place — not the ones the thing had when the event happened. That is the right
|
|
93
|
+
// answer for a feed (the reader wants to find it now) and the wrong one for an audit trail, which is
|
|
94
|
+
// one more reason these are two doors and not one.
|
|
95
|
+
//
|
|
96
|
+
// ⚠️ The fields say `resource` and not `node` because half of them are not nodes (#763). Which half
|
|
97
|
+
// is answered by `feedKindOf(action)` and by nothing on the card — a second field saying "flow"
|
|
98
|
+
// beside an action that already says `flows.publish` is a second truth, and two truths disagree.
|
|
99
|
+
//
|
|
100
|
+
// `metadata` is whatever the write site recorded, untyped on purpose: a schema per action would
|
|
101
|
+
// have to be kept in step with eleven write sites and would go stale in silence. What the surface
|
|
102
|
+
// needs from it today is `sequence` on a `node.save`, which is the version number behind the card's
|
|
103
|
+
// button.
|
|
104
|
+
export const FeedEvent = z.strictObject({
|
|
105
|
+
id: IntelId,
|
|
106
|
+
actorId: z.string().min(1),
|
|
107
|
+
action: FeedAction,
|
|
108
|
+
resourceId: IntelId,
|
|
109
|
+
resourceTitle: z.string().min(1),
|
|
110
|
+
path: z.array(FeedPathSegment),
|
|
111
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
112
|
+
occurredAt: IsoDateTime,
|
|
113
|
+
});
|
|
114
|
+
// ⚠️ Opaque BY CONTRACT, like the audit cursor and for the same reason: it is a PAIR
|
|
115
|
+
// (`occurredAt`, `id`), and a timestamp alone cannot separate two events written in the same
|
|
116
|
+
// millisecond — the normal case inside one batch. A reader continuing on the timestamp alone skips
|
|
117
|
+
// the second one with no error and no log.
|
|
118
|
+
//
|
|
119
|
+
// ⚠️ It is deliberately NOT interchangeable with an audit cursor, although both encode the same
|
|
120
|
+
// pair. The two doors walk the journal in opposite directions, so handing one's position to the
|
|
121
|
+
// other reads on from the wrong end — and would look like a feed that suddenly starts at the
|
|
122
|
+
// beginning of time rather than like a mistake. The encoding therefore carries its own marker and
|
|
123
|
+
// the other door's cursor is refused.
|
|
124
|
+
export const FeedCursor = z.string().min(1).max(400);
|
|
125
|
+
export const FeedListRequest = z.strictObject({
|
|
126
|
+
actor: z
|
|
127
|
+
.string()
|
|
128
|
+
.min(1)
|
|
129
|
+
.optional()
|
|
130
|
+
.describe("Show only what this person or agent did. Omit it for everybody whose work you may see anyway."),
|
|
131
|
+
before: FeedCursor.optional().describe("Where to continue: the `nextCursor` of a previous answer, passed back unchanged. Omit it to start at the most recent event. Do not build one — it is opaque on purpose, and a cursor from `audit_list` is refused rather than followed backwards."),
|
|
132
|
+
limit: z
|
|
133
|
+
.number()
|
|
134
|
+
.int()
|
|
135
|
+
.min(1)
|
|
136
|
+
.max(100)
|
|
137
|
+
.default(30)
|
|
138
|
+
.describe("How many events to return at most. The answer may be shorter."),
|
|
139
|
+
});
|
|
140
|
+
// `nextCursor` is present exactly when another page may exist, and it is the cursor of the LAST
|
|
141
|
+
// returned row.
|
|
142
|
+
//
|
|
143
|
+
// ⚠️ Present does not promise the next page is non-empty: the rows a reader may see can shrink
|
|
144
|
+
// between calls. Treating "cursor present" as "there is more" is fair; treating an empty answer as
|
|
145
|
+
// "you have reached the beginning of the journal" is not.
|
|
146
|
+
export const FeedListResponse = z.strictObject({
|
|
147
|
+
events: z.array(FeedEvent),
|
|
148
|
+
nextCursor: FeedCursor.nullable(),
|
|
149
|
+
});
|