kennel 0.2.0 → 0.2.2
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 +18 -5
- package/dist/cli/dispatch.js +9 -0
- package/dist/cli/src/automations/notifications.d.ts +40 -0
- package/dist/cli/src/automations/notifications.js +220 -0
- package/dist/cli/src/cli/dispatch.d.ts +1 -0
- package/dist/cli/src/cli/dispatch.js +125 -0
- package/dist/cli/src/cli/usage.d.ts +1 -0
- package/dist/cli/src/cli/usage.js +25 -0
- package/dist/cli/src/core/api-client.d.ts +13 -0
- package/dist/cli/src/core/api-client.js +1 -0
- package/dist/cli/src/core/command.d.ts +1 -0
- package/dist/cli/src/core/command.js +69 -0
- package/dist/cli/src/core/core-folders.d.ts +1 -0
- package/dist/cli/src/core/core-folders.js +42 -0
- package/dist/cli/src/core/init.d.ts +1 -0
- package/dist/cli/src/core/init.js +141 -0
- package/dist/cli/src/core/runtime.d.ts +14 -0
- package/dist/cli/src/core/runtime.js +1 -0
- package/dist/cli/src/deploy/cloudflare.d.ts +6 -0
- package/dist/cli/src/deploy/cloudflare.js +100 -0
- package/dist/cli/src/deploy/environment.d.ts +2 -0
- package/dist/cli/src/deploy/environment.js +47 -0
- package/dist/cli/src/deploy/smoke-tests.d.ts +4 -0
- package/dist/cli/src/deploy/smoke-tests.js +92 -0
- package/dist/cli/src/deploy/trigger-dev.d.ts +2 -0
- package/dist/cli/src/deploy/trigger-dev.js +255 -0
- package/dist/cli/src/deploy/vercel.d.ts +3 -0
- package/dist/cli/src/deploy/vercel.js +67 -0
- package/dist/cli/src/main.d.ts +1 -0
- package/dist/cli/src/main.js +9 -0
- package/dist/cli/src/mcp/agent-tools.d.ts +8 -0
- package/dist/cli/src/mcp/agent-tools.js +247 -0
- package/dist/cli/src/mcp/config.d.ts +25 -0
- package/dist/cli/src/mcp/config.js +185 -0
- package/dist/cli/src/mcp/function-source.d.ts +7 -0
- package/dist/cli/src/mcp/function-source.js +42 -0
- package/dist/cli/src/mcp/generate.d.ts +1 -0
- package/dist/cli/src/mcp/generate.js +47 -0
- package/dist/cli/src/mcp/install-page.d.ts +12 -0
- package/dist/cli/src/mcp/install-page.js +5 -0
- package/dist/cli/src/notifications/email-worker.d.ts +8 -0
- package/dist/cli/src/notifications/email-worker.js +137 -0
- package/dist/cli/src/package/mcp-data.d.ts +1 -0
- package/dist/cli/src/package/mcp-data.js +1 -0
- package/dist/cli/src/package/mcp-email-worker.d.ts +1 -0
- package/dist/cli/src/package/mcp-email-worker.js +1 -0
- package/dist/cli/src/package/mcp-http.d.ts +1 -0
- package/dist/cli/src/package/mcp-http.js +1 -0
- package/dist/cli/src/package/mcp-stdio.d.ts +1 -0
- package/dist/cli/src/package/mcp-stdio.js +1 -0
- package/dist/cli/src/package/mcp.d.ts +1 -0
- package/dist/cli/src/package/mcp.js +1 -0
- package/dist/cli/src/package/preview.d.ts +9 -0
- package/dist/cli/src/package/preview.js +1 -0
- package/dist/cli/src/plugins/external.d.ts +36 -0
- package/dist/cli/src/plugins/external.js +503 -0
- package/dist/cli/src/publish/cloudflare-init.d.ts +12 -0
- package/dist/cli/src/publish/cloudflare-init.js +101 -0
- package/dist/cli/src/publish/config.d.ts +28 -0
- package/dist/cli/src/publish/config.js +178 -0
- package/dist/cli/src/publish/options.d.ts +13 -0
- package/dist/cli/src/publish/options.js +78 -0
- package/dist/cli/src/publish/vercel-init.d.ts +9 -0
- package/dist/cli/src/publish/vercel-init.js +52 -0
- package/dist/cli/src/shared/json.d.ts +4 -0
- package/dist/cli/src/shared/json.js +56 -0
- package/dist/cli/src/shared/object.d.ts +2 -0
- package/dist/cli/src/shared/object.js +3 -0
- package/dist/cli/src/shared/package-manager.d.ts +11 -0
- package/dist/cli/src/shared/package-manager.js +39 -0
- package/dist/cli/src/shared/path.d.ts +4 -0
- package/dist/cli/src/shared/path.js +40 -0
- package/dist/cli/src/shared/process.d.ts +7 -0
- package/dist/cli/src/shared/process.js +12 -0
- package/dist/cli/src/shared/project-config.d.ts +2 -0
- package/dist/cli/src/shared/project-config.js +26 -0
- package/dist/cli/src/site/dev.d.ts +10 -0
- package/dist/cli/src/site/dev.js +126 -0
- package/dist/cli/src/site/extension.d.ts +8 -0
- package/dist/cli/src/site/extension.js +113 -0
- package/dist/cli/src/site/folder-icons.d.ts +46 -0
- package/dist/cli/src/site/folder-icons.js +86 -0
- package/dist/cli/src/site/hot-viewer.d.ts +2 -0
- package/dist/cli/src/site/hot-viewer.js +231 -0
- package/dist/cli/src/site/kinds.d.ts +1 -0
- package/dist/cli/src/site/kinds.js +1 -0
- package/dist/cli/src/site/mail.d.ts +1 -0
- package/dist/cli/src/site/mail.js +10 -0
- package/dist/cli/src/site/renderers.d.ts +61 -0
- package/dist/cli/src/site/renderers.js +219 -0
- package/dist/cli/src/site/server-plugins.d.ts +54 -0
- package/dist/cli/src/site/server-plugins.js +1 -0
- package/dist/cli/src/site/viewer.d.ts +36 -0
- package/dist/cli/src/site/viewer.js +352 -0
- package/dist/cli/src/site/vitepress.d.ts +1 -0
- package/dist/cli/src/site/vitepress.js +1 -0
- package/dist/cli/usage.js +1 -0
- package/dist/core/api-client.js +75 -44
- package/dist/core/command.js +6 -3
- package/dist/core/core-folders.js +38280 -33
- package/dist/core/init.js +59 -4
- package/dist/core/runtime.js +57163 -41853
- package/dist/package/preview.js +40589 -17894
- package/dist/plugins/external.d.ts +36 -0
- package/dist/plugins/external.js +503 -0
- package/dist/site/server-plugins.js +394 -59
- package/dist/site/viewer.js +18 -5
- package/kernel/apps/web/.env.example +11 -0
- package/kernel/apps/web/components.json +20 -0
- package/kernel/apps/web/eslint.config.mjs +60 -0
- package/kernel/apps/web/index.html +17 -0
- package/kernel/apps/web/package.json +79 -0
- package/kernel/apps/web/public/favicon.svg +6 -0
- package/kernel/apps/web/public/providers/claude.svg +1 -0
- package/kernel/apps/web/public/providers/codex.svg +1 -0
- package/kernel/apps/web/public/providers/cursor.svg +1 -0
- package/kernel/apps/web/public/providers/opencode.svg +1 -0
- package/kernel/apps/web/public/providers/pi.svg +1 -0
- package/kernel/apps/web/server/acp/index.ts +1 -0
- package/kernel/apps/web/server/acp/live-agent-connection.ts +1 -0
- package/kernel/apps/web/server/acp/process-manager.ts +1 -0
- package/kernel/apps/web/server/acp/registry.ts +1 -0
- package/kernel/apps/web/server/acp/sdk.ts +1 -0
- package/kernel/apps/web/server/acp/transport.ts +1 -0
- package/kernel/apps/web/server/acp/types.ts +1 -0
- package/kernel/apps/web/server/acp-live-plugin.ts +30 -0
- package/kernel/apps/web/server/api/document-edit.ts +1 -0
- package/kernel/apps/web/server/api/open-path.ts +1 -0
- package/kernel/apps/web/server/core-plugin.ts +49 -0
- package/kernel/apps/web/server/folder-favicon.ts +1 -0
- package/kernel/apps/web/server/folder-icons.ts +1 -0
- package/kernel/apps/web/server/folder-metadata-plugin.ts +31 -0
- package/kernel/apps/web/server/plugins.ts +1 -0
- package/kernel/apps/web/server/preview-kinds.ts +1 -0
- package/kernel/apps/web/src/ai-input.tsx +62 -0
- package/kernel/apps/web/src/annotations.tsx +430 -0
- package/kernel/apps/web/src/api/client.ts +3 -0
- package/kernel/apps/web/src/api/errors.ts +1 -0
- package/kernel/apps/web/src/api/events.ts +42 -0
- package/kernel/apps/web/src/app.css +332 -0
- package/kernel/apps/web/src/app.tsx +667 -0
- package/kernel/apps/web/src/ask-draft.ts +164 -0
- package/kernel/apps/web/src/ask-tray.tsx +256 -0
- package/kernel/apps/web/src/comment-editor.tsx +93 -0
- package/kernel/apps/web/src/comment-form.tsx +162 -0
- package/kernel/apps/web/src/copy-path.ts +18 -0
- package/kernel/apps/web/src/deferred-ask-tray.tsx +20 -0
- package/kernel/apps/web/src/document-url.ts +46 -0
- package/kernel/apps/web/src/documents-url.ts +23 -0
- package/kernel/apps/web/src/dropped-folder.ts +64 -0
- package/kernel/apps/web/src/external-plugins.ts +3 -0
- package/kernel/apps/web/src/file-viewer.tsx +171 -0
- package/kernel/apps/web/src/folder-filter-icons.tsx +39 -0
- package/kernel/apps/web/src/folder-metadata.ts +76 -0
- package/kernel/apps/web/src/folder-plugin-view.tsx +87 -0
- package/kernel/apps/web/src/folder-query-cache.ts +66 -0
- package/kernel/apps/web/src/host-adapters.ts +209 -0
- package/kernel/apps/web/src/host-bridge.ts +214 -0
- package/kernel/apps/web/src/lib/entity-folder.ts +2 -0
- package/kernel/apps/web/src/linked-session-header.tsx +43 -0
- package/kernel/apps/web/src/live-session-controls.tsx +326 -0
- package/kernel/apps/web/src/local-source.ts +32 -0
- package/kernel/apps/web/src/main.tsx +24 -0
- package/kernel/apps/web/src/markdown-page.tsx +444 -0
- package/kernel/apps/web/src/notes-page.tsx +103 -0
- package/kernel/apps/web/src/plugins.ts +53 -0
- package/kernel/apps/web/src/project-search-dialog.tsx +257 -0
- package/kernel/apps/web/src/project-search.ts +18 -0
- package/kernel/apps/web/src/query-client.ts +4 -0
- package/kernel/apps/web/src/rehype-source-lines.ts +22 -0
- package/kernel/apps/web/src/routes/document.tsx +1 -0
- package/kernel/apps/web/src/routes/entities.tsx +277 -0
- package/kernel/apps/web/src/routes/search.tsx +60 -0
- package/kernel/apps/web/src/selection-context.ts +68 -0
- package/kernel/apps/web/src/selection-input.tsx +58 -0
- package/kernel/apps/web/src/selection-popup.tsx +155 -0
- package/kernel/apps/web/src/session-transcript-page.tsx +152 -0
- package/kernel/apps/web/src/use-annotations.ts +162 -0
- package/kernel/apps/web/src/use-ask-ai.ts +26 -0
- package/kernel/apps/web/src/use-ask-draft.ts +27 -0
- package/kernel/apps/web/src/use-document.ts +37 -0
- package/kernel/apps/web/src/use-folder-notes.ts +49 -0
- package/kernel/apps/web/src/use-linked-session.ts +33 -0
- package/kernel/apps/web/src/view-context.tsx +69 -0
- package/kernel/apps/web/src/view-header.tsx +66 -0
- package/kernel/apps/web/src/viewer-capabilities.ts +33 -0
- package/kernel/apps/web/src/viewer-route.ts +1 -0
- package/kernel/apps/web/src/viewport-height.ts +33 -0
- package/kernel/apps/web/tsconfig.json +24 -0
- package/kernel/apps/web/vite.config.ts +252 -0
- package/kernel/packages/agents/eslint.config.js +10 -0
- package/kernel/packages/agents/package.json +75 -0
- package/kernel/packages/agents/src/agent-card.tsx +334 -0
- package/kernel/packages/agents/src/client.tsx +13 -0
- package/kernel/packages/agents/src/index.ts +18 -0
- package/kernel/packages/agents/src/manifest.ts +7 -0
- package/kernel/packages/agents/src/node.ts +447 -0
- package/kernel/packages/agents/src/profiles.ts +137 -0
- package/kernel/packages/agents/src/resolve.ts +69 -0
- package/kernel/packages/agents/src/server.ts +60 -0
- package/kernel/packages/agents/src/types.ts +82 -0
- package/kernel/packages/agents/src/viewer.tsx +370 -0
- package/kernel/packages/agents/test/profiles.test.mjs +88 -0
- package/kernel/packages/agents/test/resolve.test.mjs +729 -0
- package/kernel/packages/agents/tsconfig.json +17 -0
- package/kernel/packages/api/README.md +73 -0
- package/kernel/packages/api/openapi.json +3368 -0
- package/kernel/packages/api/package.json +41 -0
- package/kernel/packages/api/src/client/errors.ts +1 -0
- package/kernel/packages/api/src/client/index.ts +2 -0
- package/kernel/packages/api/src/contracts/schemas.ts +277 -0
- package/kernel/packages/api/src/contracts.ts +20 -0
- package/kernel/packages/api/src/index.ts +34 -0
- package/kernel/packages/api/src/server/acp/index.ts +35 -0
- package/kernel/packages/api/src/server/acp/live-agent-connection.ts +44 -0
- package/kernel/packages/api/src/server/acp/process-manager.ts +291 -0
- package/kernel/packages/api/src/server/acp/registry.ts +140 -0
- package/kernel/packages/api/src/server/acp/sdk.ts +15 -0
- package/kernel/packages/api/src/server/acp/transport.ts +115 -0
- package/kernel/packages/api/src/server/acp/types.ts +89 -0
- package/kernel/packages/api/src/server/acp-live-plugin.ts +423 -0
- package/kernel/packages/api/src/server/api/create-agent-file.ts +46 -0
- package/kernel/packages/api/src/server/api/document-edit.ts +125 -0
- package/kernel/packages/api/src/server/api/open-path.ts +40 -0
- package/kernel/packages/api/src/server/contracts.ts +85 -0
- package/kernel/packages/api/src/server/entity-folder.ts +353 -0
- package/kernel/packages/api/src/server/folder-favicon.ts +17 -0
- package/kernel/packages/api/src/server/folder-icons.ts +113 -0
- package/kernel/packages/api/src/server/folder-metadata-plugin.ts +1758 -0
- package/kernel/packages/api/src/server/host.ts +21 -0
- package/kernel/packages/api/src/server/index.ts +197 -0
- package/kernel/packages/api/src/server/linked-folder-discovery.ts +158 -0
- package/kernel/packages/api/src/server/plugins.ts +205 -0
- package/kernel/packages/api/src/server/project-discovery.ts +69 -0
- package/kernel/packages/api/src/server/watcher.ts +46 -0
- package/kernel/packages/api/src/shared/selection.ts +16 -0
- package/kernel/packages/api/src/shared/viewer-route.ts +200 -0
- package/kernel/packages/api/test/agents-loading.test.ts +94 -0
- package/kernel/packages/api/test/core.test.ts +364 -0
- package/kernel/packages/api/test/entity-folder.test.ts +131 -0
- package/kernel/packages/api/test/linked-folder-discovery.test.ts +78 -0
- package/kernel/packages/api/test/media-endpoint.test.ts +83 -0
- package/kernel/packages/api/test/partial-loading.test.ts +43 -0
- package/kernel/packages/api/test/project-discovery.test.ts +44 -0
- package/kernel/packages/api/tsconfig.json +11 -0
- package/kernel/packages/api-client/README.md +72 -0
- package/kernel/packages/api-client/package.json +26 -0
- package/kernel/packages/api-client/scripts/generate.ts +68 -0
- package/kernel/packages/api-client/src/errors.ts +59 -0
- package/kernel/packages/api-client/src/generated.d.ts +1248 -0
- package/kernel/packages/api-client/src/index.ts +206 -0
- package/kernel/packages/api-client/src/responses.ts +19 -0
- package/kernel/packages/api-client/test/client.test.ts +143 -0
- package/kernel/packages/api-client/tsconfig.json +12 -0
- package/kernel/packages/folder-plugin/eslint.config.js +10 -0
- package/kernel/packages/folder-plugin/package.json +50 -0
- package/kernel/packages/folder-plugin/src/client.ts +73 -0
- package/kernel/packages/folder-plugin/src/endpoint.ts +273 -0
- package/kernel/packages/folder-plugin/src/index.ts +15 -0
- package/kernel/packages/folder-plugin/src/server.ts +78 -0
- package/kernel/packages/folder-plugin/src/subpath.ts +34 -0
- package/kernel/packages/folder-plugin/src/types.ts +86 -0
- package/kernel/packages/folder-plugin/src/validation.ts +56 -0
- package/kernel/packages/folder-plugin/test/contract.test.mjs +133 -0
- package/kernel/packages/folder-plugin/tsconfig.json +17 -0
- package/kernel/packages/kinds/package.json +24 -0
- package/kernel/packages/kinds/src/kinds.ts +172 -0
- package/kernel/packages/markdown/README.md +40 -0
- package/kernel/packages/markdown/explorer.css +1 -0
- package/kernel/packages/markdown/package.json +30 -0
- package/kernel/packages/markdown/src/documents.ts +1 -0
- package/kernel/packages/markdown/src/explorer.ts +1 -0
- package/kernel/packages/markdown/src/index.ts +2 -0
- package/kernel/packages/markdown/src/metadata.ts +63 -0
- package/kernel/packages/markdown/src/node.ts +1 -0
- package/kernel/packages/markdown/styles.css +1 -0
- package/kernel/packages/notes/SKILL.md +19 -0
- package/kernel/packages/notes/eslint.config.js +10 -0
- package/kernel/packages/notes/package.json +72 -0
- package/kernel/packages/notes/src/client.tsx +12 -0
- package/kernel/packages/notes/src/data/ai-input.ts +58 -0
- package/kernel/packages/notes/src/data/api.ts +40 -0
- package/kernel/packages/notes/src/data/parse.ts +15 -0
- package/kernel/packages/notes/src/data/routing.ts +33 -0
- package/kernel/packages/notes/src/data/use-folder-notes.ts +49 -0
- package/kernel/packages/notes/src/index.ts +2 -0
- package/kernel/packages/notes/src/manifest.ts +6 -0
- package/kernel/packages/notes/src/pages/notes-page.tsx +79 -0
- package/kernel/packages/notes/src/pages/single-note-page.tsx +57 -0
- package/kernel/packages/notes/src/server.ts +88 -0
- package/kernel/packages/notes/src/ui/ai-composer-controls.tsx +70 -0
- package/kernel/packages/notes/src/ui/folder-notes-list.tsx +140 -0
- package/kernel/packages/notes/tsconfig.json +16 -0
- package/kernel/packages/schemas/ICON-POLICY.md +43 -0
- package/kernel/packages/schemas/SKILL.md +185 -0
- package/kernel/packages/schemas/eslint.config.js +10 -0
- package/kernel/packages/schemas/package.json +81 -0
- package/kernel/packages/schemas/src/client.tsx +137 -0
- package/kernel/packages/schemas/src/data/config-file.ts +37 -0
- package/kernel/packages/schemas/src/data/contract.ts +174 -0
- package/kernel/packages/schemas/src/data/favicon.ts +218 -0
- package/kernel/packages/schemas/src/data/fields.ts +96 -0
- package/kernel/packages/schemas/src/data/icon-image.ts +53 -0
- package/kernel/packages/schemas/src/data/icon.ts +97 -0
- package/kernel/packages/schemas/src/data/load.ts +161 -0
- package/kernel/packages/schemas/src/data/params.ts +103 -0
- package/kernel/packages/schemas/src/data/query.ts +33 -0
- package/kernel/packages/schemas/src/data/sort.ts +50 -0
- package/kernel/packages/schemas/src/data/workspace.ts +101 -0
- package/kernel/packages/schemas/src/index.ts +22 -0
- package/kernel/packages/schemas/src/manifest.ts +4 -0
- package/kernel/packages/schemas/src/node.ts +384 -0
- package/kernel/packages/schemas/src/pages/collection.tsx +252 -0
- package/kernel/packages/schemas/src/server.ts +208 -0
- package/kernel/packages/schemas/src/ui/schema-entity-list.tsx +124 -0
- package/kernel/packages/schemas/src/ui/schema-filters.tsx +186 -0
- package/kernel/packages/schemas/src/ui/schema-search.tsx +35 -0
- package/kernel/packages/schemas/src/ui/use-query-param-filter-setting.tsx +15 -0
- package/kernel/packages/schemas/test/contract.test.mjs +26 -0
- package/kernel/packages/schemas/test/fields.test.mjs +187 -0
- package/kernel/packages/schemas/test/load.test.mjs +12 -0
- package/kernel/packages/schemas/test/node.test.mjs +412 -0
- package/kernel/packages/schemas/test/query.test.mjs +134 -0
- package/kernel/packages/schemas/test/workspace.test.mjs +86 -0
- package/kernel/packages/schemas/tsconfig.json +17 -0
- package/kernel/packages/session-finding/package.json +33 -0
- package/kernel/packages/session-finding/src/index.ts +120 -0
- package/kernel/packages/session-finding/test/list-sessions.test.mjs +139 -0
- package/kernel/packages/session-finding/tsconfig.json +12 -0
- package/kernel/packages/ui/LICENSE +21 -0
- package/kernel/packages/ui/components.json +20 -0
- package/kernel/packages/ui/eslint.config.js +8 -0
- package/kernel/packages/ui/package.json +106 -0
- package/kernel/packages/ui/src/chat/file-link.ts +178 -0
- package/kernel/packages/ui/src/chat/index.ts +18 -0
- package/kernel/packages/ui/src/chat/transcript.tsx +348 -0
- package/kernel/packages/ui/src/chat/turns.ts +76 -0
- package/kernel/packages/ui/src/chat/types.ts +23 -0
- package/kernel/packages/ui/src/chat/use-overflowing.ts +56 -0
- package/kernel/packages/ui/src/components/accordion.tsx +74 -0
- package/kernel/packages/ui/src/components/alert-dialog.tsx +164 -0
- package/kernel/packages/ui/src/components/alert.tsx +68 -0
- package/kernel/packages/ui/src/components/app-breadcrumbs.tsx +170 -0
- package/kernel/packages/ui/src/components/app-header.tsx +125 -0
- package/kernel/packages/ui/src/components/app-options.tsx +87 -0
- package/kernel/packages/ui/src/components/app-view-header.tsx +34 -0
- package/kernel/packages/ui/src/components/aspect-ratio.tsx +11 -0
- package/kernel/packages/ui/src/components/avatar.tsx +53 -0
- package/kernel/packages/ui/src/components/badge.tsx +47 -0
- package/kernel/packages/ui/src/components/base-dialog.tsx +3 -0
- package/kernel/packages/ui/src/components/base-tabs.tsx +63 -0
- package/kernel/packages/ui/src/components/breadcrumb.tsx +110 -0
- package/kernel/packages/ui/src/components/button-group.tsx +86 -0
- package/kernel/packages/ui/src/components/button.tsx +65 -0
- package/kernel/packages/ui/src/components/calendar.tsx +240 -0
- package/kernel/packages/ui/src/components/card.tsx +95 -0
- package/kernel/packages/ui/src/components/carousel.tsx +240 -0
- package/kernel/packages/ui/src/components/chart.tsx +375 -0
- package/kernel/packages/ui/src/components/checkbox.tsx +39 -0
- package/kernel/packages/ui/src/components/collapsible.tsx +33 -0
- package/kernel/packages/ui/src/components/collection-icon.tsx +28 -0
- package/kernel/packages/ui/src/components/command.tsx +205 -0
- package/kernel/packages/ui/src/components/content-issues.tsx +63 -0
- package/kernel/packages/ui/src/components/context-menu.tsx +298 -0
- package/kernel/packages/ui/src/components/copy-context.tsx +134 -0
- package/kernel/packages/ui/src/components/dialog.tsx +157 -0
- package/kernel/packages/ui/src/components/drawer.tsx +162 -0
- package/kernel/packages/ui/src/components/dropdown-menu.tsx +303 -0
- package/kernel/packages/ui/src/components/empty.tsx +108 -0
- package/kernel/packages/ui/src/components/field.tsx +260 -0
- package/kernel/packages/ui/src/components/file-preview.tsx +152 -0
- package/kernel/packages/ui/src/components/file-renderer.tsx +466 -0
- package/kernel/packages/ui/src/components/filter-chip-panel.tsx +157 -0
- package/kernel/packages/ui/src/components/filter-select.tsx +127 -0
- package/kernel/packages/ui/src/components/folder-activity.tsx +646 -0
- package/kernel/packages/ui/src/components/folder-file-list.tsx +58 -0
- package/kernel/packages/ui/src/components/folder-filter-bar.tsx +191 -0
- package/kernel/packages/ui/src/components/folder-image.tsx +18 -0
- package/kernel/packages/ui/src/components/folder-landing.tsx +70 -0
- package/kernel/packages/ui/src/components/folder-list.tsx +140 -0
- package/kernel/packages/ui/src/components/folder-metadata.tsx +107 -0
- package/kernel/packages/ui/src/components/folder-mobile-bar.tsx +60 -0
- package/kernel/packages/ui/src/components/folder-project-list.tsx +133 -0
- package/kernel/packages/ui/src/components/folder-session-list.tsx +113 -0
- package/kernel/packages/ui/src/components/folder-session-page.tsx +126 -0
- package/kernel/packages/ui/src/components/folder-sidebar.tsx +52 -0
- package/kernel/packages/ui/src/components/folder-skill-list.tsx +62 -0
- package/kernel/packages/ui/src/components/folder-tabs.tsx +156 -0
- package/kernel/packages/ui/src/components/form.tsx +167 -0
- package/kernel/packages/ui/src/components/hover-card.tsx +52 -0
- package/kernel/packages/ui/src/components/icons.tsx +34 -0
- package/kernel/packages/ui/src/components/input-group.tsx +184 -0
- package/kernel/packages/ui/src/components/input-otp.tsx +90 -0
- package/kernel/packages/ui/src/components/input.tsx +29 -0
- package/kernel/packages/ui/src/components/item.tsx +195 -0
- package/kernel/packages/ui/src/components/kbd.tsx +32 -0
- package/kernel/packages/ui/src/components/label.tsx +27 -0
- package/kernel/packages/ui/src/components/link.tsx +45 -0
- package/kernel/packages/ui/src/components/live-tool-call.tsx +193 -0
- package/kernel/packages/ui/src/components/menubar.tsx +323 -0
- package/kernel/packages/ui/src/components/navigation-menu.tsx +210 -0
- package/kernel/packages/ui/src/components/note-card.tsx +149 -0
- package/kernel/packages/ui/src/components/pagination.tsx +128 -0
- package/kernel/packages/ui/src/components/popover.tsx +56 -0
- package/kernel/packages/ui/src/components/progress.tsx +31 -0
- package/kernel/packages/ui/src/components/radio-group.tsx +54 -0
- package/kernel/packages/ui/src/components/scroll-area.tsx +61 -0
- package/kernel/packages/ui/src/components/select.tsx +219 -0
- package/kernel/packages/ui/src/components/separator.tsx +30 -0
- package/kernel/packages/ui/src/components/session-icon.tsx +124 -0
- package/kernel/packages/ui/src/components/sheet.tsx +157 -0
- package/kernel/packages/ui/src/components/sidebar.tsx +789 -0
- package/kernel/packages/ui/src/components/skeleton.tsx +13 -0
- package/kernel/packages/ui/src/components/slider.tsx +73 -0
- package/kernel/packages/ui/src/components/sonner.tsx +41 -0
- package/kernel/packages/ui/src/components/spinner.tsx +16 -0
- package/kernel/packages/ui/src/components/switch.tsx +40 -0
- package/kernel/packages/ui/src/components/table.tsx +120 -0
- package/kernel/packages/ui/src/components/tabs.tsx +78 -0
- package/kernel/packages/ui/src/components/textarea.tsx +25 -0
- package/kernel/packages/ui/src/components/toggle-group.tsx +87 -0
- package/kernel/packages/ui/src/components/toggle.tsx +48 -0
- package/kernel/packages/ui/src/components/tooltip.tsx +71 -0
- package/kernel/packages/ui/src/components/viewer-options.tsx +166 -0
- package/kernel/packages/ui/src/hooks/use-folder-filter.ts +103 -0
- package/kernel/packages/ui/src/hooks/use-mobile.ts +19 -0
- package/kernel/packages/ui/src/index.ts +13 -0
- package/kernel/packages/ui/src/lib/document-extensions.ts +83 -0
- package/kernel/packages/ui/src/lib/folder-activity.ts +143 -0
- package/kernel/packages/ui/src/lib/folder-filter.ts +284 -0
- package/kernel/packages/ui/src/lib/live-tool-call.tsx +109 -0
- package/kernel/packages/ui/src/lib/media-urls.ts +176 -0
- package/kernel/packages/ui/src/lib/obsidian-links.ts +120 -0
- package/kernel/packages/ui/src/lib/source-components.tsx +65 -0
- package/kernel/packages/ui/src/lib/utils.tsx +7 -0
- package/kernel/packages/ui/src/pages/entity-detail-page.tsx +82 -0
- package/kernel/packages/ui/src/pages/entity-list-page.tsx +50 -0
- package/kernel/packages/ui/src/pages/entity-page.tsx +69 -0
- package/kernel/packages/ui/src/styles/folder-activity.css +2151 -0
- package/kernel/packages/ui/test/copy-context.test.mjs +48 -0
- package/kernel/packages/ui/test/folder-filter.test.mjs +484 -0
- package/kernel/packages/ui/tsconfig.json +15 -0
- package/kernel/plugins/calendar/SKILL.md +173 -0
- package/kernel/plugins/calendar/eslint.config.js +10 -0
- package/kernel/plugins/calendar/package.json +73 -0
- package/kernel/plugins/calendar/schema.json +137 -0
- package/kernel/plugins/calendar/src/calendar.tsx +328 -0
- package/kernel/plugins/calendar/src/client.tsx +139 -0
- package/kernel/plugins/calendar/src/context.ts +48 -0
- package/kernel/plugins/calendar/src/copy-button.tsx +66 -0
- package/kernel/plugins/calendar/src/event-dialog.tsx +270 -0
- package/kernel/plugins/calendar/src/index.ts +4 -0
- package/kernel/plugins/calendar/src/manifest.ts +7 -0
- package/kernel/plugins/calendar/src/parse.ts +610 -0
- package/kernel/plugins/calendar/src/server.ts +160 -0
- package/kernel/plugins/calendar/src/utils.ts +80 -0
- package/kernel/plugins/calendar/src/views.tsx +418 -0
- package/kernel/plugins/calendar/test/context.test.mjs +60 -0
- package/kernel/plugins/calendar/test/package.test.mjs +43 -0
- package/kernel/plugins/calendar/test/parse.test.mjs +392 -0
- package/kernel/plugins/calendar/test/server.test.mjs +126 -0
- package/kernel/plugins/calendar/tsconfig.json +17 -0
- package/kernel/plugins/mail/SKILL.md +97 -0
- package/kernel/plugins/mail/eslint.config.js +10 -0
- package/kernel/plugins/mail/package.json +79 -0
- package/kernel/plugins/mail/src/api.ts +359 -0
- package/kernel/plugins/mail/src/bun-ffi.d.ts +14 -0
- package/kernel/plugins/mail/src/client.tsx +14 -0
- package/kernel/plugins/mail/src/flock.ts +137 -0
- package/kernel/plugins/mail/src/folders.ts +37 -0
- package/kernel/plugins/mail/src/history.ts +485 -0
- package/kernel/plugins/mail/src/index.ts +3 -0
- package/kernel/plugins/mail/src/mail-card.tsx +123 -0
- package/kernel/plugins/mail/src/mail-conversation.tsx +153 -0
- package/kernel/plugins/mail/src/mail-detail-page.tsx +467 -0
- package/kernel/plugins/mail/src/mail-hooks.ts +252 -0
- package/kernel/plugins/mail/src/mail-page.tsx +109 -0
- package/kernel/plugins/mail/src/mail-request.ts +78 -0
- package/kernel/plugins/mail/src/mail-send-box.tsx +175 -0
- package/kernel/plugins/mail/src/mailos.ts +723 -0
- package/kernel/plugins/mail/src/manifest.ts +7 -0
- package/kernel/plugins/mail/src/node.ts +171 -0
- package/kernel/plugins/mail/src/parse.ts +139 -0
- package/kernel/plugins/mail/src/server.ts +125 -0
- package/kernel/plugins/mail/src/types.ts +10 -0
- package/kernel/plugins/mail/src/viewer.tsx +147 -0
- package/kernel/plugins/mail/test/flock.test.mjs +156 -0
- package/kernel/plugins/mail/test/folders.test.mjs +138 -0
- package/kernel/plugins/mail/test/history.test.mjs +460 -0
- package/kernel/plugins/mail/test/mailos.test.mjs +752 -0
- package/kernel/plugins/mail/test/node.test.mjs +207 -0
- package/kernel/plugins/mail/test/package.test.mjs +54 -0
- package/kernel/plugins/mail/test/parse.test.mjs +32 -0
- package/kernel/plugins/mail/test/server.test.mjs +116 -0
- package/kernel/plugins/mail/test/viewer.test.mjs +192 -0
- package/kernel/plugins/mail/tsconfig.json +17 -0
- package/kernel/plugins/projects/SKILL.md +73 -0
- package/kernel/plugins/projects/eslint.config.js +10 -0
- package/kernel/plugins/projects/package.json +70 -0
- package/kernel/plugins/projects/src/client.tsx +17 -0
- package/kernel/plugins/projects/src/data/model.ts +129 -0
- package/kernel/plugins/projects/src/index.ts +17 -0
- package/kernel/plugins/projects/src/manifest.ts +7 -0
- package/kernel/plugins/projects/src/project-context.ts +41 -0
- package/kernel/plugins/projects/src/server.ts +276 -0
- package/kernel/plugins/projects/src/ui/project-card.tsx +61 -0
- package/kernel/plugins/projects/src/ui/projects-page.tsx +102 -0
- package/kernel/plugins/projects/test/package.test.mjs +51 -0
- package/kernel/plugins/projects/tsconfig.json +17 -0
- package/kernel/plugins/tasks/SKILL.md +341 -0
- package/kernel/plugins/tasks/eslint.config.js +10 -0
- package/kernel/plugins/tasks/package.json +74 -0
- package/kernel/plugins/tasks/schema.json +939 -0
- package/kernel/plugins/tasks/src/api.ts +212 -0
- package/kernel/plugins/tasks/src/client.tsx +23 -0
- package/kernel/plugins/tasks/src/data/parse.ts +544 -0
- package/kernel/plugins/tasks/src/data/task-id.ts +56 -0
- package/kernel/plugins/tasks/src/data/todo-model.ts +795 -0
- package/kernel/plugins/tasks/src/index.ts +34 -0
- package/kernel/plugins/tasks/src/manifest.ts +7 -0
- package/kernel/plugins/tasks/src/pages/task-detail.tsx +48 -0
- package/kernel/plugins/tasks/src/pages/task-list.tsx +88 -0
- package/kernel/plugins/tasks/src/server.ts +447 -0
- package/kernel/plugins/tasks/src/styles.css +9 -0
- package/kernel/plugins/tasks/src/ui/compact-todo-list.tsx +372 -0
- package/kernel/plugins/tasks/src/ui/error-details.tsx +78 -0
- package/kernel/plugins/tasks/src/ui/task-page.tsx +392 -0
- package/kernel/plugins/tasks/src/ui/todo-agent-filter.tsx +36 -0
- package/kernel/plugins/tasks/src/ui/todo-filter-bar.tsx +66 -0
- package/kernel/plugins/tasks/src/ui/todo-item.tsx +494 -0
- package/kernel/plugins/tasks/src/ui/todo-status-filter.tsx +60 -0
- package/kernel/plugins/tasks/src/ui/todo-tag-filter.tsx +48 -0
- package/kernel/plugins/tasks/src/ui/todo-warnings.tsx +106 -0
- package/kernel/plugins/tasks/test/api.test.mjs +99 -0
- package/kernel/plugins/tasks/test/folder-sources.test.mjs +46 -0
- package/kernel/plugins/tasks/test/package.test.mjs +54 -0
- package/kernel/plugins/tasks/test/parse.test.mjs +225 -0
- package/kernel/plugins/tasks/test/server.test.mjs +386 -0
- package/kernel/plugins/tasks/tsconfig.json +17 -0
- package/node_modules/@agentclientprotocol/sdk/LICENSE +191 -0
- package/node_modules/@agentclientprotocol/sdk/README.md +70 -0
- package/node_modules/@agentclientprotocol/sdk/dist/acp.d.ts +1835 -0
- package/node_modules/@agentclientprotocol/sdk/dist/acp.js +1885 -0
- package/node_modules/@agentclientprotocol/sdk/dist/acp.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/acp.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/acp.test.js +5036 -0
- package/node_modules/@agentclientprotocol/sdk/dist/acp.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/connection.d.ts +82 -0
- package/node_modules/@agentclientprotocol/sdk/dist/connection.js +428 -0
- package/node_modules/@agentclientprotocol/sdk/dist/connection.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/connection.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/connection.test.js +470 -0
- package/node_modules/@agentclientprotocol/sdk/dist/connection.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.d.ts +26 -0
- package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.js +96 -0
- package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.js +77 -0
- package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.d.ts +2 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.js +232 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/client.d.ts +2 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/client.js +132 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/client.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.d.ts +9 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.js +221 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.d.ts +2 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.js +86 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.d.ts +2 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.js +112 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.d.ts +2 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.js +88 -0
- package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/http-stream.d.ts +33 -0
- package/node_modules/@agentclientprotocol/sdk/dist/http-stream.js +435 -0
- package/node_modules/@agentclientprotocol/sdk/dist/http-stream.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.js +1380 -0
- package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.d.ts +603 -0
- package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js +1064 -0
- package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.js +851 -0
- package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.d.ts +22 -0
- package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.js +64 -0
- package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.js +45 -0
- package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.d.ts +17 -0
- package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.js +426 -0
- package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.js +499 -0
- package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.d.ts +37 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.js +474 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.js +535 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol.d.ts +11 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol.js +57 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.js +73 -0
- package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.d.ts +199 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js +211 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/index.d.ts +51 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/index.js +52 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/index.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.d.ts +6118 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.js +3 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.d.ts +14160 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.js +3066 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.d.ts +30 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.js +98 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.js +93 -0
- package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.js +261 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.js +490 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-sse.d.ts +2 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-sse.js +104 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-sse.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.js +52 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.js +946 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server.d.ts +81 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server.js +380 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server.test.js +1082 -0
- package/node_modules/@agentclientprotocol/sdk/dist/server.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/sse.d.ts +4 -0
- package/node_modules/@agentclientprotocol/sdk/dist/sse.js +91 -0
- package/node_modules/@agentclientprotocol/sdk/dist/sse.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/sse.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/sse.test.js +126 -0
- package/node_modules/@agentclientprotocol/sdk/dist/sse.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/stream.d.ts +35 -0
- package/node_modules/@agentclientprotocol/sdk/dist/stream.js +106 -0
- package/node_modules/@agentclientprotocol/sdk/dist/stream.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/stream.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/stream.test.js +206 -0
- package/node_modules/@agentclientprotocol/sdk/dist/stream.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.d.ts +8 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.js +51 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.d.ts +24 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.js +163 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.d.ts +9 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.js +74 -0
- package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.d.ts +806 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.js +1183 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.js +512 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.d.ts +954 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.js +1035 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.d.ts +42 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.js +43 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.d.ts +6146 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.js +3 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.d.ts +30552 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.js +3204 -0
- package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-server.d.ts +14 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-server.js +358 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-server.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.d.ts +54 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.js +246 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.js +833 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.d.ts +13 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.js +78 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.d.ts +1 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.js +42 -0
- package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.js.map +1 -0
- package/node_modules/@agentclientprotocol/sdk/package.json +105 -0
- package/node_modules/@agentclientprotocol/sdk/schema/schema.json +8819 -0
- package/node_modules/@agentclientprotocol/sdk/schema/v2/schema.unstable.json +10098 -0
- package/package.json +52 -6
- package/web/assets/{abnfDiagram-VRR7QNED-Nfq-O04D.js → abnfDiagram-VRR7QNED-Bgfb1nEB.js} +1 -1
- package/web/assets/app-DoGr2Zi7.js +2 -0
- package/web/assets/app-options-D-RJiQ-X.js +25 -0
- package/web/assets/app-view-header-BLvLq02T.js +1 -0
- package/web/assets/arc-Dk_KI36B.js +1 -0
- package/web/assets/{architectureDiagram-ZJ3FMSHR-qhRwPNcQ.js → architectureDiagram-ZJ3FMSHR-NR_KhRCf.js} +1 -1
- package/web/assets/ask-tray-TzeTcO6-.js +14 -0
- package/web/assets/{blockDiagram-677ZJIJ3-C56P3bGu.js → blockDiagram-677ZJIJ3-CkLkwx9C.js} +1 -1
- package/web/assets/button-C6arH7zt.js +1 -0
- package/web/assets/{c4Diagram-LMCZKHZV-Ey1M72zD.js → c4Diagram-LMCZKHZV-CFCUH8e_.js} +1 -1
- package/web/assets/channel-uMEjV8qc.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-a6isk9VU.js → chunk-2Q5K7J3B-B_BPLWsW.js} +1 -1
- package/web/assets/{chunk-32BRIVSS-uy4kdSLL.js → chunk-32BRIVSS-B1VB1hOy.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-oj2sBFd7.js → chunk-5VM5RSS4-KFcYr8Co.js} +1 -1
- package/web/assets/{chunk-EX3LRPZG-Bzl1ukAi.js → chunk-EX3LRPZG-CpBX3kuK.js} +3 -3
- package/web/assets/{chunk-JWPE2WC7-sUph7I_t.js → chunk-JWPE2WC7-BPSl40wG.js} +1 -1
- package/web/assets/{chunk-MOJQB5TN-C0ERSuVK.js → chunk-MOJQB5TN-D2RcYmoU.js} +1 -1
- package/web/assets/{chunk-RYQCIY6F-Dyw1Hfwp.js → chunk-RYQCIY6F-m7Gyn-t3.js} +1 -1
- package/web/assets/{chunk-V7JOEXUC-DnSz22rb.js → chunk-V7JOEXUC-TDvdopxS.js} +1 -1
- package/web/assets/{chunk-VR4S4FIN-Bp2SNel7.js → chunk-VR4S4FIN-DZTsG51a.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-Dqtar746.js → chunk-XXDRQBXY-Dp0--RE2.js} +1 -1
- package/web/assets/classDiagram-OUVF2IWQ-fbZocVor.js +1 -0
- package/web/assets/classDiagram-v2-EOCWNBFH-fbZocVor.js +1 -0
- package/web/assets/client-C6Nxdfif.js +2 -0
- package/web/assets/client-CXYfBko5.js +17 -0
- package/web/assets/client-CoKtOq-X.js +7 -0
- package/web/assets/client-DyRQz5RU.js +53 -0
- package/web/assets/client-OY6HUzuD.js +98 -0
- package/web/assets/client-YOYWZIFi.js +34 -0
- package/web/assets/client-j2kQmxsO.js +22 -0
- package/web/assets/command-BugZBGXE.js +38 -0
- package/web/assets/copy-context-C0Uqsp-3.js +1 -0
- package/web/assets/{cose-bilkent-JH36ORCC-Dx1VqMjj.js → cose-bilkent-JH36ORCC-CPu3PI8h.js} +1 -1
- package/web/assets/{cynefin-VYW2F7L2-SjhCWmIV.js → cynefin-VYW2F7L2-DWxftYAm.js} +1 -1
- package/web/assets/{cynefinDiagram-TSTJHNR4-Dvqz2594.js → cynefinDiagram-TSTJHNR4-DsmN2V-p.js} +1 -1
- package/web/assets/{dagre-VKFMJZFB-Ju2m2qXt.js → dagre-VKFMJZFB-COEbApyY.js} +1 -1
- package/web/assets/{diagram-FQU43EPY-DsHKTt0k.js → diagram-FQU43EPY-0O9WGWKB.js} +1 -1
- package/web/assets/{diagram-G47NLZAW-DWHAcLkJ.js → diagram-G47NLZAW-CutEdMVh.js} +1 -1
- package/web/assets/{diagram-NH7WQ7WH-uUMz46ZD.js → diagram-NH7WQ7WH-C9KZc3B2.js} +1 -1
- package/web/assets/{diagram-OA4YK3LP-BRjVzjdp.js → diagram-OA4YK3LP-D8kkPXbY.js} +1 -1
- package/web/assets/{diagram-WEI45ONY-Cb-FhBpQ.js → diagram-WEI45ONY-_YqiTaGP.js} +1 -1
- package/web/assets/document-Dgt5eZFj.js +19 -0
- package/web/assets/{ebnfDiagram-CCIWWBDH-IhhxX3IB.js → ebnfDiagram-CCIWWBDH-JO-zQh6g.js} +1 -1
- package/web/assets/{entities-DUnx74kH.js → entities-C3wz7FCx.js} +12 -12
- package/web/assets/{erDiagram-Q63AITRT-D1frgeWf.js → erDiagram-Q63AITRT-9UjQwJ4P.js} +1 -1
- package/web/assets/file-viewer-DZJ8nYnl.js +1 -0
- package/web/assets/{flowDiagram-23GEKE2U-BiPPM-FY.js → flowDiagram-23GEKE2U-Ca08tnYM.js} +5 -5
- package/web/assets/folder-image-BfGgxo7i.js +1 -0
- package/web/assets/folder-landing-qUKBCnG-.js +54 -0
- package/web/assets/folder-list-BfFjv7rR.js +1 -0
- package/web/assets/folder-metadata-DCw8xzHk.js +2 -0
- package/web/assets/folder-mobile-bar-Ubz4babf.js +1 -0
- package/web/assets/folder-plugin-view-DsWR1zmQ.js +6 -0
- package/web/assets/{ganttDiagram-NO4QXBWP-CmEOlHD7.js → ganttDiagram-NO4QXBWP-KnHzX5W3.js} +1 -1
- package/web/assets/{gitGraphDiagram-IHSO6WYX-tTjcpZpU.js → gitGraphDiagram-IHSO6WYX-Cm8woNtK.js} +1 -1
- package/web/assets/index-BaRnbYRw.js +1 -0
- package/web/assets/index-BexmLxIP.css +1 -0
- package/web/assets/index-Bp9DidgD.js +1 -0
- package/web/assets/{index-eL1k96k8.js → index-CCXE8zc9.js} +1 -1
- package/web/assets/index-CNyy98F8.js +2 -0
- package/web/assets/{index-DmrKjrlM.js → index-CXhBn-ar.js} +1 -1
- package/web/assets/index-DDirZMgx.js +1 -0
- package/web/assets/{infoDiagram-FWYZ7A6U-Ok2sdbc1.js → infoDiagram-FWYZ7A6U-yyqmUtIb.js} +1 -1
- package/web/assets/{ishikawaDiagram-FXEZZL3T-kPnM5psX.js → ishikawaDiagram-FXEZZL3T-BfvR_Zy4.js} +4 -4
- package/web/assets/{journeyDiagram-5HDEW3XC-BkoT0-45.js → journeyDiagram-5HDEW3XC-BKuw06HM.js} +1 -1
- package/web/assets/{kanban-definition-HUTT4EX6-xnm_eFoU.js → kanban-definition-HUTT4EX6-n0010rmQ.js} +8 -8
- package/web/assets/{linear-CLZpgLH-.js → linear-C0d0lT8O.js} +1 -1
- package/web/assets/linked-session-header-BkEweU0Z.js +3 -0
- package/web/assets/{markdown-njUwQKsR.js → markdown-Bw9RgUGR.js} +9 -9
- package/web/assets/{mermaid.core-Bvxj3RoN.js → mermaid.core-BDVbShyO.js} +6 -6
- package/web/assets/metadata-KV0dpp4G.js +1 -0
- package/web/assets/{mindmap-definition-LN4V7U3C-42Uoox79.js → mindmap-definition-LN4V7U3C--_0ks3GF.js} +1 -1
- package/web/assets/note-card-DBfX6gW1.js +6 -0
- package/web/assets/{pegDiagram-2B236MQR-B-GZCw3w.js → pegDiagram-2B236MQR-CBoNIpKR.js} +1 -1
- package/web/assets/{pieDiagram-ENE6RG2P-DRmmssIB.js → pieDiagram-ENE6RG2P-MA5tkYh5.js} +3 -3
- package/web/assets/popover-DBD7FF-W.js +9 -0
- package/web/assets/{project-search-dialog-B730oZ1S.js → project-search-dialog-DM1IkSZu.js} +6 -6
- package/web/assets/{quadrantDiagram-ABIIQ3AL-BfhVQ7V9.js → quadrantDiagram-ABIIQ3AL-CWT1ryqF.js} +1 -1
- package/web/assets/{railroadDiagram-RFXS5EU6-DxKx7XRp.js → railroadDiagram-RFXS5EU6-ZiLB5FGi.js} +1 -1
- package/web/assets/{react-DZzLHL-l.js → react-B9jn2M18.js} +2 -2
- package/web/assets/{requirementDiagram-TGXJPOKE-NUzj9fw1.js → requirementDiagram-TGXJPOKE-CQq9uneq.js} +1 -1
- package/web/assets/{sankeyDiagram-HTMAVEWB-Cy9OMnl-.js → sankeyDiagram-HTMAVEWB-qDG-0JqI.js} +1 -1
- package/web/assets/search-DNrQA5fF.js +2 -0
- package/web/assets/select-D8cqNgcp.js +30 -0
- package/web/assets/selection-popup-DmtTeRs2.js +7 -0
- package/web/assets/{sequenceDiagram-DBY2YBRQ-CBNE9mzn.js → sequenceDiagram-DBY2YBRQ-CiApurLO.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-S4HhfX0n.js → sizeCapture-X5ZJPWSS-DZSR5QXm.js} +1 -1
- package/web/assets/stateDiagram-2N3HPSRC-CjJJR9_z.js +1 -0
- package/web/assets/stateDiagram-v2-6OUMAXLB-BpeGSCu9.js +1 -0
- package/web/assets/{swimlanes-5IMT3BWC-DJ2aLWal.js → swimlanes-5IMT3BWC-CKmo1sg6.js} +2 -2
- package/web/assets/swimlanesDiagram-G3AALYLV-D9RjLKb9.js +8 -0
- package/web/assets/tanstack-YzX_Mi37.js +3 -0
- package/web/assets/{timeline-definition-FHXFAJF6-vFDUVPCX.js → timeline-definition-FHXFAJF6-D-NMwS3y.js} +1 -1
- package/web/assets/{use-folder-filter-BbTUlXgG.js → use-folder-filter-LQyXns5Q.js} +1 -1
- package/web/assets/{utils-CwHGE3BB.js → utils-DCaHk0Gm.js} +1 -1
- package/web/assets/{vennDiagram-L72KCM5P-AsnhK2zW.js → vennDiagram-L72KCM5P-CfL6LBWw.js} +1 -1
- package/web/assets/view-context-gyDl_p2V.js +229 -0
- package/web/assets/viewer-capabilities-Bpp8Uvcg.js +1 -0
- package/web/assets/{wardleyDiagram-EHGQE667-Cj1wFbNV.js → wardleyDiagram-EHGQE667-DgldMxaj.js} +1 -1
- package/web/assets/{xychartDiagram-FW5EYKEG-Bbvnutsm.js → xychartDiagram-FW5EYKEG-CIoAIFX8.js} +1 -1
- package/web/favicon.svg +6 -0
- package/web/index.html +5 -4
- package/web/assets/app-CPSmsokP.js +0 -2
- package/web/assets/app-options-XEWvevsz.js +0 -25
- package/web/assets/app-view-header-BKZ90ToF.js +0 -1
- package/web/assets/arc-DbpbZvCt.js +0 -1
- package/web/assets/arrow-left-CFeHb-Z1.js +0 -1
- package/web/assets/ask-tray-D2YHtbPj.js +0 -14
- package/web/assets/button-BJ7z-ZA7.js +0 -1
- package/web/assets/calendar-days-DWh2XMO2.js +0 -1
- package/web/assets/channel-dSRp_qTo.js +0 -1
- package/web/assets/chevron-down-C5oRtqbX.js +0 -1
- package/web/assets/chevron-right-CsPtvh8C.js +0 -1
- package/web/assets/chevron-up-DjpU6Pyv.js +0 -1
- package/web/assets/classDiagram-OUVF2IWQ-B7B2zLzM.js +0 -1
- package/web/assets/classDiagram-v2-EOCWNBFH-B7B2zLzM.js +0 -1
- package/web/assets/client-CAudjYV9.js +0 -34
- package/web/assets/client-Dn9-_Gm_.js +0 -14
- package/web/assets/client-Dxrf2tyq.js +0 -102
- package/web/assets/client-aFI2M4pE.js +0 -53
- package/web/assets/collection-icon-TbOVyORG.js +0 -1
- package/web/assets/collection-page-Du6FKkuU.js +0 -10
- package/web/assets/command-C_g5E1Wx.js +0 -38
- package/web/assets/copy-Ikmr6Iq2.js +0 -1
- package/web/assets/copy-context-Cl1TE2PJ.js +0 -1
- package/web/assets/document-DcjNSJCk.js +0 -2
- package/web/assets/external-link-BXmSXqqF.js +0 -1
- package/web/assets/file-renderer-BRZTrYx8.js +0 -19
- package/web/assets/file-text-CiiSsCDq.js +0 -1
- package/web/assets/file-viewer-C1wAeVDK.js +0 -1
- package/web/assets/folder-image-AXBrHUcU.js +0 -1
- package/web/assets/folder-landing-BhRg7hwn.js +0 -54
- package/web/assets/folder-list-rIdszVde.js +0 -1
- package/web/assets/folder-metadata-puTC5QqJ.js +0 -2
- package/web/assets/folder-mobile-bar-DjjRQo3T.js +0 -1
- package/web/assets/folder-plugin-view-BU_kzR8j.js +0 -6
- package/web/assets/index-DS2Wmd9I.css +0 -1
- package/web/assets/index-DgqzSeIR.js +0 -1
- package/web/assets/index-DnlTDqaa.js +0 -1
- package/web/assets/index-DztTMDFz.js +0 -2
- package/web/assets/index-kY75qc96.js +0 -1
- package/web/assets/index-p38i_yyY.js +0 -1
- package/web/assets/link-2-BWKA6t--.js +0 -1
- package/web/assets/link-DC_1Z6Yy.js +0 -11
- package/web/assets/linked-session-header-DJYWZ_-q.js +0 -3
- package/web/assets/mail-2rCdIFul.js +0 -1
- package/web/assets/markdown-title-dncAYYiP.js +0 -131
- package/web/assets/notes-page-DIW6rgJp.js +0 -10
- package/web/assets/pencil-8cobiSSq.js +0 -1
- package/web/assets/plus-BHV2wJr7.js +0 -1
- package/web/assets/popover-Cmmgj-MJ.js +0 -9
- package/web/assets/search-CvlYUkN6.js +0 -2
- package/web/assets/select-1SvaKQsS.js +0 -30
- package/web/assets/selection-popup-ntjycEVh.js +0 -7
- package/web/assets/sparkles-CBhGREdc.js +0 -1
- package/web/assets/stateDiagram-2N3HPSRC-BEw1Mheu.js +0 -1
- package/web/assets/stateDiagram-v2-6OUMAXLB-BHtjl1iD.js +0 -1
- package/web/assets/swimlanesDiagram-G3AALYLV-Z362aroZ.js +0 -8
- package/web/assets/tanstack-CD46mJkU.js +0 -1
- package/web/assets/view-context-D-fh9AbH.js +0 -81
- package/web/assets/viewer-capabilities-CROIaoqh.js +0 -1
- package/web/assets/x-BUeE--I4.js +0 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http"
|
|
2
|
+
|
|
3
|
+
export type ApiErrorCode =
|
|
4
|
+
| "aborted"
|
|
5
|
+
| "bad-request"
|
|
6
|
+
| "conflict"
|
|
7
|
+
| "failed"
|
|
8
|
+
| "forbidden"
|
|
9
|
+
| "internal"
|
|
10
|
+
| "method-not-allowed"
|
|
11
|
+
| "not-found"
|
|
12
|
+
| "payload-too-large"
|
|
13
|
+
| "timeout"
|
|
14
|
+
|
|
15
|
+
const statusByCode: Record<ApiErrorCode, number> = {
|
|
16
|
+
aborted: 400,
|
|
17
|
+
"bad-request": 400,
|
|
18
|
+
conflict: 409,
|
|
19
|
+
failed: 500,
|
|
20
|
+
forbidden: 403,
|
|
21
|
+
internal: 500,
|
|
22
|
+
"method-not-allowed": 405,
|
|
23
|
+
"not-found": 404,
|
|
24
|
+
"payload-too-large": 413,
|
|
25
|
+
timeout: 504,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class ApiError extends Error {
|
|
29
|
+
readonly code: ApiErrorCode
|
|
30
|
+
readonly status: number
|
|
31
|
+
|
|
32
|
+
constructor(code: ApiErrorCode, message: string) {
|
|
33
|
+
super(message)
|
|
34
|
+
this.name = "ApiError"
|
|
35
|
+
this.code = code
|
|
36
|
+
this.status = statusByCode[code]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function apiError(code: ApiErrorCode, message: string) {
|
|
41
|
+
return new ApiError(code, message)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function jsonResponse(
|
|
45
|
+
response: ServerResponse,
|
|
46
|
+
status: number,
|
|
47
|
+
body: unknown,
|
|
48
|
+
extraHeaders: Record<string, string> = {},
|
|
49
|
+
) {
|
|
50
|
+
// Guard against double emission: a handler that already finished the
|
|
51
|
+
// response (or a client that disconnected after completion) must never
|
|
52
|
+
// trigger a `writeHead after end` crash.
|
|
53
|
+
if (response.writableEnded || response.headersSent || response.destroyed) {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
response.writeHead(status, {
|
|
57
|
+
"Cache-Control": "no-store",
|
|
58
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
59
|
+
...extraHeaders,
|
|
60
|
+
})
|
|
61
|
+
response.end(JSON.stringify(body))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function jsonError(
|
|
65
|
+
response: ServerResponse,
|
|
66
|
+
status: number,
|
|
67
|
+
code: ApiErrorCode,
|
|
68
|
+
message: string,
|
|
69
|
+
extraHeaders: Record<string, string> = {},
|
|
70
|
+
) {
|
|
71
|
+
jsonResponse(response, status, { error: { code, message } }, extraHeaders)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Same-origin guard for mutating requests (POST/DELETE). A browser sends
|
|
76
|
+
* `Origin` (or `Referer`) on cross-site requests; require the header, when
|
|
77
|
+
* present, to match the requested host and reject mutations without any
|
|
78
|
+
* origin signal. GET requests never mutate and are exempt.
|
|
79
|
+
*/
|
|
80
|
+
export function sameOrigin(request: IncomingMessage): boolean {
|
|
81
|
+
const host = request.headers.host
|
|
82
|
+
if (!host) return false
|
|
83
|
+
|
|
84
|
+
const origin = request.headers.origin
|
|
85
|
+
if (origin) {
|
|
86
|
+
try {
|
|
87
|
+
return new URL(origin).host === host
|
|
88
|
+
} catch {
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const referer = request.headers.referer
|
|
94
|
+
if (referer) {
|
|
95
|
+
try {
|
|
96
|
+
return new URL(referer).host === host
|
|
97
|
+
} catch {
|
|
98
|
+
return false
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return false
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Read a request body bounded to `maxBytes` bytes. Real Node requests are
|
|
107
|
+
* async-iterable; the caller must set `Content-Length` expectations too. An
|
|
108
|
+
* oversized body or a cancellation aborts with a structured ApiError.
|
|
109
|
+
*/
|
|
110
|
+
export async function readBoundedBody(
|
|
111
|
+
request: IncomingMessage,
|
|
112
|
+
maxBytes: number,
|
|
113
|
+
signal: AbortSignal,
|
|
114
|
+
): Promise<string> {
|
|
115
|
+
const iterable = request as IncomingMessage & {
|
|
116
|
+
[Symbol.asyncIterator]?: () => AsyncIterableIterator<Buffer>
|
|
117
|
+
}
|
|
118
|
+
if (typeof iterable[Symbol.asyncIterator] !== "function") return ""
|
|
119
|
+
|
|
120
|
+
let total = 0
|
|
121
|
+
const chunks: Buffer[] = []
|
|
122
|
+
for await (const chunk of iterable) {
|
|
123
|
+
if (signal.aborted) throw apiError("aborted", "Request aborted")
|
|
124
|
+
total += chunk.length
|
|
125
|
+
if (total > maxBytes) {
|
|
126
|
+
throw apiError("payload-too-large", "Request body too large")
|
|
127
|
+
}
|
|
128
|
+
chunks.push(chunk)
|
|
129
|
+
}
|
|
130
|
+
return Buffer.concat(chunks).toString("utf8")
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* JSON body helper for mutations. Returns the parsed object or throws a
|
|
135
|
+
* structured bad-request error; non-Object payloads are rejected.
|
|
136
|
+
*/
|
|
137
|
+
export function parseJsonBody(body: string): Record<string, unknown> {
|
|
138
|
+
if (!body.trim()) throw apiError("bad-request", "Request body required")
|
|
139
|
+
let value: unknown
|
|
140
|
+
try {
|
|
141
|
+
value = JSON.parse(body)
|
|
142
|
+
} catch {
|
|
143
|
+
throw apiError("bad-request", "Request body is not valid JSON")
|
|
144
|
+
}
|
|
145
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
146
|
+
throw apiError("bad-request", "Request body must be a JSON object")
|
|
147
|
+
}
|
|
148
|
+
return value as Record<string, unknown>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type ApiRouteHandle<Context> = (ctx: {
|
|
152
|
+
body: string
|
|
153
|
+
context: Context
|
|
154
|
+
query: URLSearchParams
|
|
155
|
+
request: IncomingMessage
|
|
156
|
+
response: ServerResponse
|
|
157
|
+
signal: AbortSignal
|
|
158
|
+
url: URL
|
|
159
|
+
}) => Promise<void> | void
|
|
160
|
+
|
|
161
|
+
export type ApiRouteSpec<Context> = {
|
|
162
|
+
/** Only this HTTP method is accepted; anything else gets a 405. */
|
|
163
|
+
method: "GET" | "POST" | "DELETE"
|
|
164
|
+
/** Bounded request body in bytes; mutations without a body may set 0. */
|
|
165
|
+
maxBodyBytes?: number
|
|
166
|
+
/** Hard cap on handler execution; the child/request is cancelled after. */
|
|
167
|
+
timeoutMs?: number
|
|
168
|
+
/**
|
|
169
|
+
* Height of `ctx.body` before validation. Sizes over `maxBodyBytes` are
|
|
170
|
+
* rejected as 413, non-mutating methods never read a body.
|
|
171
|
+
*/
|
|
172
|
+
handle: ApiRouteHandle<Context>
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const methodAllowHeader = (method: string) => ({ Allow: method })
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Run one declarative API route. Handles explicit method restriction,
|
|
179
|
+
* same-origin protection for mutations, bounded bodies, abort on client
|
|
180
|
+
* disconnect, timeouts, and structured JSON errors. Handlers never see raw
|
|
181
|
+
* internals; unexpected errors become a generic 500 that cannot leak
|
|
182
|
+
* command output or credentials.
|
|
183
|
+
*/
|
|
184
|
+
export async function runApiRoute<Context>(
|
|
185
|
+
request: IncomingMessage,
|
|
186
|
+
response: ServerResponse,
|
|
187
|
+
url: URL,
|
|
188
|
+
spec: ApiRouteSpec<Context>,
|
|
189
|
+
context: Context,
|
|
190
|
+
): Promise<void> {
|
|
191
|
+
const method = (request.method ?? "GET").toUpperCase()
|
|
192
|
+
if (method !== spec.method) {
|
|
193
|
+
jsonError(
|
|
194
|
+
response,
|
|
195
|
+
405,
|
|
196
|
+
"method-not-allowed",
|
|
197
|
+
`Method ${method} not allowed`,
|
|
198
|
+
methodAllowHeader(spec.method),
|
|
199
|
+
)
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const controller = new AbortController()
|
|
204
|
+
const disconnect = () => controller.abort()
|
|
205
|
+
request.on?.("aborted", disconnect)
|
|
206
|
+
response.on?.("close", disconnect)
|
|
207
|
+
|
|
208
|
+
let timer: ReturnType<typeof setTimeout> | undefined
|
|
209
|
+
const timeoutPromise = spec.timeoutMs
|
|
210
|
+
? new Promise<never>((_resolve, reject) => {
|
|
211
|
+
timer = setTimeout(() => {
|
|
212
|
+
// Cancel the child first (signal-aware handlers die immediately),
|
|
213
|
+
// then surface the timeout through the race below.
|
|
214
|
+
controller.abort()
|
|
215
|
+
reject(apiError("timeout", "Request timed out"))
|
|
216
|
+
}, spec.timeoutMs)
|
|
217
|
+
})
|
|
218
|
+
: null
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
if (method !== "GET" && !sameOrigin(request)) {
|
|
222
|
+
throw apiError("forbidden", "Cross-origin mutations are not allowed")
|
|
223
|
+
}
|
|
224
|
+
const maxBody = spec.maxBodyBytes ?? (method === "GET" ? 0 : 1024 * 1024)
|
|
225
|
+
const body =
|
|
226
|
+
method === "GET"
|
|
227
|
+
? ""
|
|
228
|
+
: await readBoundedBody(request, maxBody, controller.signal)
|
|
229
|
+
const ctx = {
|
|
230
|
+
body,
|
|
231
|
+
context,
|
|
232
|
+
query: url.searchParams,
|
|
233
|
+
request,
|
|
234
|
+
response,
|
|
235
|
+
signal: controller.signal,
|
|
236
|
+
url,
|
|
237
|
+
}
|
|
238
|
+
// The handler is raced against the deadline so an unresponsive handler
|
|
239
|
+
// cannot hang the server. Its own failures are collected and rethrown
|
|
240
|
+
// after the race (a late failure after a timeout is dropped silently).
|
|
241
|
+
let handlerError: unknown
|
|
242
|
+
const handlerPromise = (async () => {
|
|
243
|
+
await spec.handle(ctx)
|
|
244
|
+
})().catch((error: unknown) => {
|
|
245
|
+
handlerError = error
|
|
246
|
+
})
|
|
247
|
+
if (timeoutPromise) await Promise.race([handlerPromise, timeoutPromise])
|
|
248
|
+
else await handlerPromise
|
|
249
|
+
if (handlerError !== undefined) throw handlerError
|
|
250
|
+
} catch (error) {
|
|
251
|
+
if (error instanceof ApiError && error.code === "timeout") {
|
|
252
|
+
jsonError(response, 504, "timeout", error.message)
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
if (controller.signal.aborted) {
|
|
256
|
+
// Client is gone; nothing useful left to write.
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
if (error instanceof ApiError) {
|
|
260
|
+
jsonError(response, error.status, error.code, error.message)
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
264
|
+
jsonError(response, 400, "aborted", "Request aborted")
|
|
265
|
+
return
|
|
266
|
+
}
|
|
267
|
+
jsonError(response, 500, "internal", "Internal server error")
|
|
268
|
+
} finally {
|
|
269
|
+
if (timer) clearTimeout(timer)
|
|
270
|
+
request.removeListener?.("aborted", disconnect)
|
|
271
|
+
response.removeListener?.("close", disconnect)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
FolderPluginDetection,
|
|
3
|
+
FolderPluginId,
|
|
4
|
+
FolderPluginManifest,
|
|
5
|
+
} from "./types.ts"
|
|
6
|
+
export type {
|
|
7
|
+
FolderPluginClient,
|
|
8
|
+
FolderPluginHostActions,
|
|
9
|
+
FolderPluginViewProps,
|
|
10
|
+
} from "./client.ts"
|
|
11
|
+
export type {
|
|
12
|
+
FolderPluginDataset,
|
|
13
|
+
FolderPluginPayload,
|
|
14
|
+
FolderPluginPayloadError,
|
|
15
|
+
} from "./types.ts"
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { FolderPluginDetection, FolderPluginManifest } from "./types.ts"
|
|
2
|
+
|
|
3
|
+
export type {
|
|
4
|
+
FolderPluginDataset,
|
|
5
|
+
FolderPluginDetection,
|
|
6
|
+
FolderPluginPayload,
|
|
7
|
+
FolderPluginPayloadError,
|
|
8
|
+
} from "./types.ts"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Context the host passes to a plugin's server entry. The host performs the
|
|
12
|
+
* authorized folder resolution and root containment before calling any
|
|
13
|
+
* plugin, so a plugin id or subpath is never an access grant.
|
|
14
|
+
*/
|
|
15
|
+
export type FolderPluginContext = {
|
|
16
|
+
/** Absolute authorized folder path, already realpath-resolved by the host. */
|
|
17
|
+
folder: string
|
|
18
|
+
/**
|
|
19
|
+
* Folders connected to the viewed folder by repository links, resolved by
|
|
20
|
+
* the host (same relation graph that powers linked notes). Plugins may
|
|
21
|
+
* read read-only content there (notes, tasks, instructions) but never
|
|
22
|
+
* write. Empty for remote, restricted, or machine-root hosts.
|
|
23
|
+
*/
|
|
24
|
+
linkedFolders?: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Payload a plugin returns from its data handler. The host serializes it to
|
|
29
|
+
* the client. `unavailable` lets a direct plugin URL render an explicit
|
|
30
|
+
* empty state without blocking core folder navigation.
|
|
31
|
+
*/
|
|
32
|
+
export type FolderPluginData =
|
|
33
|
+
{ kind: "available"; data: unknown } | { kind: "unavailable" }
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Node-side entry for a trusted folder plugin: an id/label manifest plus
|
|
37
|
+
* content detection and a generic list/detail data handler. Plugins may not
|
|
38
|
+
* touch the host shell; the host owns routing, layout, and dispatch.
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Thrown by a plugin to signal a server-side failure (like a preview read
|
|
42
|
+
* error). The host maps this to an HTTP 5xx so it can never be mistaken for
|
|
43
|
+
* an empty but healthy result. All other thrown errors in a handler map to a
|
|
44
|
+
* not-found (4xx) response.
|
|
45
|
+
*/
|
|
46
|
+
export class FolderPluginFailure extends Error {
|
|
47
|
+
constructor(message: string) {
|
|
48
|
+
super(message)
|
|
49
|
+
this.name = "FolderPluginFailure"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Files a plugin wants scaffolding to create, paths relative to the
|
|
55
|
+
* authorized folder root (containment is enforced by the scaffolder).
|
|
56
|
+
*/
|
|
57
|
+
export type FolderPluginInitFile = {
|
|
58
|
+
path: string
|
|
59
|
+
content: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type FolderPluginInitResult = {
|
|
63
|
+
files: FolderPluginInitFile[]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type FolderPluginServer = FolderPluginManifest & {
|
|
67
|
+
detect(context: FolderPluginContext): Promise<FolderPluginDetection>
|
|
68
|
+
handle(
|
|
69
|
+
context: FolderPluginContext,
|
|
70
|
+
subpath: string,
|
|
71
|
+
): Promise<FolderPluginData>
|
|
72
|
+
/**
|
|
73
|
+
* Optional starter content scaffolding (`kennel init` / host init
|
|
74
|
+
* commands). Returns files to create; the host skips files that already
|
|
75
|
+
* exist unless forced. Absent for read-only views with no content file.
|
|
76
|
+
*/
|
|
77
|
+
init?(context: FolderPluginContext): Promise<FolderPluginInitResult>
|
|
78
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared subpath matching for folder plugins: a detail subpath selects one
|
|
3
|
+
* item across every discovered source, first match wins. Plugins with a
|
|
4
|
+
* richer address scheme (tasks' `<folderRef>@<id>` qualified ids) parse
|
|
5
|
+
* their own scheme first, then fall back to this helper for bare ids so
|
|
6
|
+
* not-found semantics stay consistent across plugins.
|
|
7
|
+
*/
|
|
8
|
+
export type SubpathMatch<Source, Item> = {
|
|
9
|
+
/** The full source object the caller supplied, kept intact for reuse. */
|
|
10
|
+
source: Source
|
|
11
|
+
item: Item
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a detail subpath to one item across the given sources. A source
|
|
16
|
+
* earlier in the list wins over a later one, mirroring the "first source
|
|
17
|
+
* that contains it wins" behavior of the reference plugins. Returns
|
|
18
|
+
* undefined when no item matches; callers render their not-found state.
|
|
19
|
+
*/
|
|
20
|
+
export function matchSubpath<Source, Item>(
|
|
21
|
+
sources: Source[],
|
|
22
|
+
subpath: string,
|
|
23
|
+
itemsOf: (source: Source) => Iterable<Item>,
|
|
24
|
+
matches: (item: Item, id: string) => boolean,
|
|
25
|
+
): SubpathMatch<Source, Item> | undefined {
|
|
26
|
+
const id = subpath.trim()
|
|
27
|
+
if (!id) return undefined
|
|
28
|
+
for (const source of sources) {
|
|
29
|
+
for (const item of itemsOf(source)) {
|
|
30
|
+
if (matches(item, id)) return { item, source }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined
|
|
34
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export type FolderPluginId = string
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One precise problem found in plugin content, shared by every plugin's
|
|
5
|
+
* validation functions. `path` is JSON-pointer-ish (`tasks[2].status`) or
|
|
6
|
+
* `#` for file-level problems.
|
|
7
|
+
*/
|
|
8
|
+
export type ContentIssue = {
|
|
9
|
+
path: string
|
|
10
|
+
message: string
|
|
11
|
+
/** Advisory problem; absent means a hard error. Warnings never
|
|
12
|
+
* invalidate content — the file still detects as valid. */
|
|
13
|
+
severity?: "warning"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type FolderPluginManifest = {
|
|
17
|
+
/** Stable identifier used in routes, URLs, and registries. Never a URL segment turned into an import path. */
|
|
18
|
+
id: FolderPluginId
|
|
19
|
+
/** Navigation label shown in the folder shell. */
|
|
20
|
+
label: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Result of a server-side content check. `available` reports an optional
|
|
25
|
+
* count so the navigation item can show a number. `unavailable` means the
|
|
26
|
+
* folder has no plugin content; `error` means detection failed and is not
|
|
27
|
+
* proof of absence. The detect call never returns full content payloads.
|
|
28
|
+
*/
|
|
29
|
+
export type FolderPluginDetection =
|
|
30
|
+
| { count?: number; status: "available" }
|
|
31
|
+
| { status: "unavailable" }
|
|
32
|
+
| { error: string; status: "error" }
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Decoded-dataset payload: the plugin's typed dataset for the view plus
|
|
36
|
+
* optional advisory warnings. Extra fields (like the owning folder) are
|
|
37
|
+
* allowed; the index signature keeps host serialization flexible without
|
|
38
|
+
* weakening the required `status` check.
|
|
39
|
+
*/
|
|
40
|
+
export type FolderPluginDataset<T> = {
|
|
41
|
+
/** The plugin's decoded dataset for the view. */
|
|
42
|
+
dataset: T
|
|
43
|
+
status: "available"
|
|
44
|
+
/** Advisory problems; they never invalidate the dataset. */
|
|
45
|
+
warnings?: ContentIssue[]
|
|
46
|
+
} & { [key: string]: unknown }
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* In-band error payload: precise issues or a message, never a throw. The
|
|
50
|
+
* client renders the issue list (the shared `ContentIssues` panel) so a
|
|
51
|
+
* broken content file shows exactly which fields are wrong.
|
|
52
|
+
*/
|
|
53
|
+
export type FolderPluginPayloadError = {
|
|
54
|
+
/** Per-field issues for invalid content; empty for a not-found detail. */
|
|
55
|
+
issues?: ContentIssue[]
|
|
56
|
+
/** Human message for a not-found detail subpath. */
|
|
57
|
+
message?: string
|
|
58
|
+
status: "error"
|
|
59
|
+
} & { [key: string]: unknown }
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Typed payload a plugin returns from its data handler. The `kind`/`status`
|
|
63
|
+
* pairing is the contract: a handler never throws for content problems — it
|
|
64
|
+
* returns `{ kind: "available", data: { status: "error", issues } }` in
|
|
65
|
+
* band, or `{ kind: "unavailable" }` when the folder has no content at all.
|
|
66
|
+
* The host-side `FolderPluginData` stays the loose type for tolerance; new
|
|
67
|
+
* plugins type their handler as `FolderPluginPayload<T>`.
|
|
68
|
+
*/
|
|
69
|
+
export type FolderPluginPayload<T> =
|
|
70
|
+
| {
|
|
71
|
+
data: FolderPluginDataset<T> | FolderPluginPayloadError
|
|
72
|
+
kind: "available"
|
|
73
|
+
}
|
|
74
|
+
| { kind: "unavailable" }
|
|
75
|
+
|
|
76
|
+
/** True when the decoded data is an in-band error payload. */
|
|
77
|
+
export function isPluginPayloadError(
|
|
78
|
+
data: unknown,
|
|
79
|
+
): data is FolderPluginPayloadError {
|
|
80
|
+
return (
|
|
81
|
+
typeof data === "object" &&
|
|
82
|
+
data !== null &&
|
|
83
|
+
"status" in data &&
|
|
84
|
+
(data as { status: unknown }).status === "error"
|
|
85
|
+
)
|
|
86
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ContentIssue } from "./types.ts"
|
|
2
|
+
|
|
3
|
+
export type { ContentIssue } from "./types.ts"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Result of validating a content source: a typed document, or a list of
|
|
7
|
+
* precise per-field issues. Parsing never throws — invalid JSON becomes an
|
|
8
|
+
* issue with the parser's position detail so callers can render it directly.
|
|
9
|
+
*/
|
|
10
|
+
export type Validated<T> =
|
|
11
|
+
{ ok: true; document: T } | { ok: false; issues: ContentIssue[] }
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Shared "validation function" primitive for folder plugins: parse a JSON
|
|
15
|
+
* source string, run the plugin's `validate` rules, and return either the
|
|
16
|
+
* typed document or structured issues. This is what every plugin's
|
|
17
|
+
* `src/parse.ts` should build on so detection, data loading, client rendering
|
|
18
|
+
* and tests all share one rule set.
|
|
19
|
+
*/
|
|
20
|
+
export function parseJsonSource<T>(
|
|
21
|
+
source: string,
|
|
22
|
+
validate: (value: unknown) => ContentIssue[],
|
|
23
|
+
): Validated<T> {
|
|
24
|
+
let value: unknown
|
|
25
|
+
try {
|
|
26
|
+
value = JSON.parse(source)
|
|
27
|
+
} catch (error) {
|
|
28
|
+
const detail =
|
|
29
|
+
error instanceof Error && error.message
|
|
30
|
+
? error.message
|
|
31
|
+
: "could not be parsed"
|
|
32
|
+
return {
|
|
33
|
+
ok: false,
|
|
34
|
+
issues: [{ path: "#", message: `not valid JSON: ${detail}` }],
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const issues = validate(value)
|
|
38
|
+
if (issues.length > 0) return { ok: false, issues }
|
|
39
|
+
return { ok: true, document: value as T }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Compact one-line summary of validation issues for nav badges and error
|
|
44
|
+
* headers: the single issue when there is one, otherwise a count plus the
|
|
45
|
+
* first problem.
|
|
46
|
+
*/
|
|
47
|
+
export function issueSummary(
|
|
48
|
+
issues: ContentIssue[],
|
|
49
|
+
file = "content file",
|
|
50
|
+
): string {
|
|
51
|
+
const first = issues[0]
|
|
52
|
+
if (!first) return `${file} is valid`
|
|
53
|
+
const label = first.path && first.path !== "#" ? first.path : file
|
|
54
|
+
if (issues.length === 1) return `${label}: ${first.message}`
|
|
55
|
+
return `${issues.length} problems found in ${file} (first: ${label} — ${first.message})`
|
|
56
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import assert from "node:assert/strict"
|
|
2
|
+
import { readFile } from "node:fs/promises"
|
|
3
|
+
import test from "node:test"
|
|
4
|
+
|
|
5
|
+
import { FolderPluginFailure } from "../src/server.ts"
|
|
6
|
+
import { matchSubpath } from "../src/subpath.ts"
|
|
7
|
+
import { isPluginPayloadError } from "../src/types.ts"
|
|
8
|
+
import { issueSummary, parseJsonSource } from "../src/validation.ts"
|
|
9
|
+
|
|
10
|
+
const indexSource = await readFile(
|
|
11
|
+
new URL("../src/index.ts", import.meta.url),
|
|
12
|
+
"utf8",
|
|
13
|
+
)
|
|
14
|
+
const clientSource = await readFile(
|
|
15
|
+
new URL("../src/client.ts", import.meta.url),
|
|
16
|
+
"utf8",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
test("the shared index re-exports browser-safe types only", () => {
|
|
20
|
+
assert.match(indexSource, /FolderPluginClient/)
|
|
21
|
+
assert.match(indexSource, /FolderPluginManifest/)
|
|
22
|
+
assert.doesNotMatch(indexSource, /node:/)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test("the client entry never imports the Node server entry", () => {
|
|
26
|
+
assert.doesNotMatch(clientSource, /node:/)
|
|
27
|
+
assert.doesNotMatch(clientSource, /server["']/)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test("the server failure class extends Error with a stable name and message", () => {
|
|
31
|
+
const failure = new FolderPluginFailure("Mail preview failed: boom")
|
|
32
|
+
assert.ok(failure instanceof FolderPluginFailure)
|
|
33
|
+
assert.ok(failure instanceof Error)
|
|
34
|
+
assert.equal(failure.name, "FolderPluginFailure")
|
|
35
|
+
assert.equal(failure.message, "Mail preview failed: boom")
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test("parseJsonSource returns a document for valid input and issues otherwise", () => {
|
|
39
|
+
const valid = parseJsonSource(JSON.stringify({ name: "ok" }), (value) =>
|
|
40
|
+
value && typeof value === "object" && "name" in value
|
|
41
|
+
? []
|
|
42
|
+
: [{ path: "#", message: "no name" }],
|
|
43
|
+
)
|
|
44
|
+
assert.equal(valid.ok, true)
|
|
45
|
+
if (valid.ok) assert.equal(valid.document.name, "ok")
|
|
46
|
+
|
|
47
|
+
const invalidJson = parseJsonSource("{ nope", () => [])
|
|
48
|
+
assert.equal(invalidJson.ok, false)
|
|
49
|
+
if (!invalidJson.ok) {
|
|
50
|
+
assert.equal(invalidJson.issues[0].path, "#")
|
|
51
|
+
assert.match(invalidJson.issues[0].message, /not valid JSON/)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const invalidValue = parseJsonSource("[]", () => [
|
|
55
|
+
{ path: "#", message: "no name" },
|
|
56
|
+
])
|
|
57
|
+
assert.equal(invalidValue.ok, false)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test("matchSubpath resolves one item across sources, first source wins", () => {
|
|
61
|
+
const sources = [
|
|
62
|
+
{ folder: "/root", items: [{ id: "shared" }, { id: "root-only" }] },
|
|
63
|
+
{ folder: "/linked", items: [{ id: "shared" }, { id: "linked-only" }] },
|
|
64
|
+
]
|
|
65
|
+
const itemsOf = (source) => source.items
|
|
66
|
+
|
|
67
|
+
const shared = matchSubpath(
|
|
68
|
+
sources,
|
|
69
|
+
"shared",
|
|
70
|
+
itemsOf,
|
|
71
|
+
(item, id) => item.id === id,
|
|
72
|
+
)
|
|
73
|
+
assert.equal(shared.source.folder, "/root")
|
|
74
|
+
assert.equal(shared.item.id, "shared")
|
|
75
|
+
|
|
76
|
+
const linked = matchSubpath(
|
|
77
|
+
sources,
|
|
78
|
+
"linked-only",
|
|
79
|
+
itemsOf,
|
|
80
|
+
(item, id) => item.id === id,
|
|
81
|
+
)
|
|
82
|
+
assert.equal(linked.source.folder, "/linked")
|
|
83
|
+
|
|
84
|
+
assert.equal(
|
|
85
|
+
matchSubpath(sources, "missing", itemsOf, (item, id) => item.id === id),
|
|
86
|
+
undefined,
|
|
87
|
+
)
|
|
88
|
+
assert.equal(
|
|
89
|
+
matchSubpath(sources, " ", itemsOf, (item, id) => item.id === id),
|
|
90
|
+
undefined,
|
|
91
|
+
)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test("isPluginPayloadError narrows in-band error payloads only", () => {
|
|
95
|
+
assert.equal(
|
|
96
|
+
isPluginPayloadError({
|
|
97
|
+
status: "error",
|
|
98
|
+
issues: [{ path: "a", message: "b" }],
|
|
99
|
+
}),
|
|
100
|
+
true,
|
|
101
|
+
)
|
|
102
|
+
assert.equal(
|
|
103
|
+
isPluginPayloadError({ message: "not found", status: "error" }),
|
|
104
|
+
true,
|
|
105
|
+
)
|
|
106
|
+
assert.equal(
|
|
107
|
+
isPluginPayloadError({ dataset: {}, status: "available" }),
|
|
108
|
+
false,
|
|
109
|
+
)
|
|
110
|
+
assert.equal(isPluginPayloadError(null), false)
|
|
111
|
+
assert.equal(isPluginPayloadError("error"), false)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test("issueSummary formats single and multiple issues", () => {
|
|
115
|
+
assert.equal(
|
|
116
|
+
issueSummary([{ path: "tasks[0].name", message: "required" }], "todo.json"),
|
|
117
|
+
"tasks[0].name: required",
|
|
118
|
+
)
|
|
119
|
+
assert.equal(
|
|
120
|
+
issueSummary([{ path: "#", message: "not valid JSON: boom" }], "todo.json"),
|
|
121
|
+
"todo.json: not valid JSON: boom",
|
|
122
|
+
)
|
|
123
|
+
assert.equal(
|
|
124
|
+
issueSummary(
|
|
125
|
+
[
|
|
126
|
+
{ path: "a", message: "one" },
|
|
127
|
+
{ path: "b", message: "two" },
|
|
128
|
+
],
|
|
129
|
+
"todo.json",
|
|
130
|
+
),
|
|
131
|
+
"2 problems found in todo.json (first: a — one)",
|
|
132
|
+
)
|
|
133
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "@raggle-ai/tsconfig/base.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"target": "ES2022",
|
|
6
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
7
|
+
"jsx": "preserve",
|
|
8
|
+
"baseUrl": ".",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
// local copy: bun doesn't read paths inherited via `extends`
|
|
11
|
+
"paths": {
|
|
12
|
+
"~/*": ["${configDir}/../../packages/*/src"]
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"],
|
|
16
|
+
"exclude": ["node_modules", "dist", "eslint.config.mjs"]
|
|
17
|
+
}
|