@vascend/talos 0.1.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 +202 -0
- package/dist/backend/asset-events.d.ts +31 -0
- package/dist/backend/asset-events.js +149 -0
- package/dist/backend/assets.d.ts +31 -0
- package/dist/backend/assets.js +210 -0
- package/dist/backend/auth.d.ts +18 -0
- package/dist/backend/auth.js +59 -0
- package/dist/backend/config.d.ts +14 -0
- package/dist/backend/config.js +41 -0
- package/dist/backend/conversations.d.ts +21 -0
- package/dist/backend/conversations.js +141 -0
- package/dist/backend/crypto.d.ts +9 -0
- package/dist/backend/crypto.js +68 -0
- package/dist/backend/engine.d.ts +13 -0
- package/dist/backend/engine.js +78 -0
- package/dist/backend/http.d.ts +25 -0
- package/dist/backend/http.js +112 -0
- package/dist/backend/index.d.ts +1 -0
- package/dist/backend/index.js +24 -0
- package/dist/backend/routes.d.ts +14 -0
- package/dist/backend/routes.js +169 -0
- package/dist/backend/sdk.d.ts +12 -0
- package/dist/backend/sdk.js +11 -0
- package/dist/backend/server.d.ts +12 -0
- package/dist/backend/server.js +91 -0
- package/dist/backend/temp-image-store.d.ts +46 -0
- package/dist/backend/temp-image-store.js +197 -0
- package/dist/backend/types.d.ts +103 -0
- package/dist/backend/types.js +29 -0
- package/dist/backend/users.d.ts +13 -0
- package/dist/backend/users.js +76 -0
- package/dist/backend/ws-handler.d.ts +14 -0
- package/dist/backend/ws-handler.js +72 -0
- package/dist/backend/ws.d.ts +19 -0
- package/dist/backend/ws.js +146 -0
- package/dist/core/agent.d.ts +56 -0
- package/dist/core/agent.js +1783 -0
- package/dist/core/background.d.ts +45 -0
- package/dist/core/background.js +140 -0
- package/dist/core/bootstrap.d.ts +45 -0
- package/dist/core/bootstrap.js +294 -0
- package/dist/core/cli-args.d.ts +41 -0
- package/dist/core/cli-args.js +282 -0
- package/dist/core/collapsible-output.d.ts +38 -0
- package/dist/core/collapsible-output.js +143 -0
- package/dist/core/compaction-checkpoint.d.ts +9 -0
- package/dist/core/compaction-checkpoint.js +58 -0
- package/dist/core/compaction.d.ts +42 -0
- package/dist/core/compaction.js +270 -0
- package/dist/core/config.d.ts +49 -0
- package/dist/core/config.js +417 -0
- package/dist/core/context-ledger.d.ts +99 -0
- package/dist/core/context-ledger.js +222 -0
- package/dist/core/context-policy.d.ts +17 -0
- package/dist/core/context-policy.js +81 -0
- package/dist/core/continuation-review.d.ts +23 -0
- package/dist/core/continuation-review.js +64 -0
- package/dist/core/crash-report.d.ts +3 -0
- package/dist/core/crash-report.js +27 -0
- package/dist/core/credentials.d.ts +11 -0
- package/dist/core/credentials.js +183 -0
- package/dist/core/doctor.d.ts +24 -0
- package/dist/core/doctor.js +125 -0
- package/dist/core/effort.d.ts +5 -0
- package/dist/core/effort.js +42 -0
- package/dist/core/env-paths.d.ts +3 -0
- package/dist/core/env-paths.js +38 -0
- package/dist/core/execution-guidance.d.ts +9 -0
- package/dist/core/execution-guidance.js +73 -0
- package/dist/core/execution-target.d.ts +41 -0
- package/dist/core/execution-target.js +69 -0
- package/dist/core/file-coordination.d.ts +66 -0
- package/dist/core/file-coordination.js +176 -0
- package/dist/core/file-lease-store.d.ts +14 -0
- package/dist/core/file-lease-store.js +89 -0
- package/dist/core/image-limits.d.ts +26 -0
- package/dist/core/image-limits.js +205 -0
- package/dist/core/interruptible-completion.d.ts +3 -0
- package/dist/core/interruptible-completion.js +42 -0
- package/dist/core/kingdoms-mode-state.d.ts +24 -0
- package/dist/core/kingdoms-mode-state.js +139 -0
- package/dist/core/licenza.d.ts +38 -0
- package/dist/core/licenza.js +125 -0
- package/dist/core/model-limits.d.ts +2 -0
- package/dist/core/model-limits.js +36 -0
- package/dist/core/output-lifecycle.d.ts +44 -0
- package/dist/core/output-lifecycle.js +190 -0
- package/dist/core/package-update.d.ts +15 -0
- package/dist/core/package-update.js +121 -0
- package/dist/core/permission-queue.d.ts +2 -0
- package/dist/core/permission-queue.js +20 -0
- package/dist/core/prompt-attachment.d.ts +21 -0
- package/dist/core/prompt-attachment.js +123 -0
- package/dist/core/request-plan.d.ts +16 -0
- package/dist/core/request-plan.js +36 -0
- package/dist/core/run-timing.d.ts +17 -0
- package/dist/core/run-timing.js +123 -0
- package/dist/core/self-update.d.ts +17 -0
- package/dist/core/self-update.js +54 -0
- package/dist/core/session-refs.d.ts +27 -0
- package/dist/core/session-refs.js +126 -0
- package/dist/core/session-storage.d.ts +4 -0
- package/dist/core/session-storage.js +48 -0
- package/dist/core/session-title.d.ts +1 -0
- package/dist/core/session-title.js +21 -0
- package/dist/core/session-usage.d.ts +17 -0
- package/dist/core/session-usage.js +74 -0
- package/dist/core/session.d.ts +58 -0
- package/dist/core/session.js +296 -0
- package/dist/core/settings.d.ts +17 -0
- package/dist/core/settings.js +107 -0
- package/dist/core/storage-retention.d.ts +21 -0
- package/dist/core/storage-retention.js +227 -0
- package/dist/core/text-sanitize.d.ts +1 -0
- package/dist/core/text-sanitize.js +35 -0
- package/dist/core/tool-artifacts.d.ts +6 -0
- package/dist/core/tool-artifacts.js +51 -0
- package/dist/core/tool-compress.d.ts +8 -0
- package/dist/core/tool-compress.js +111 -0
- package/dist/core/tool-executor.d.ts +16 -0
- package/dist/core/tool-executor.js +97 -0
- package/dist/core/tool-result-index.d.ts +52 -0
- package/dist/core/tool-result-index.js +327 -0
- package/dist/core/tool-result-store.d.ts +38 -0
- package/dist/core/tool-result-store.js +190 -0
- package/dist/core/tool-scheduler.d.ts +16 -0
- package/dist/core/tool-scheduler.js +35 -0
- package/dist/core/trust.d.ts +21 -0
- package/dist/core/trust.js +95 -0
- package/dist/core/types.d.ts +402 -0
- package/dist/core/types.js +1 -0
- package/dist/core/update-check.d.ts +26 -0
- package/dist/core/update-check.js +89 -0
- package/dist/core/update-process.d.ts +10 -0
- package/dist/core/update-process.js +31 -0
- package/dist/core/user-inbox.d.ts +23 -0
- package/dist/core/user-inbox.js +56 -0
- package/dist/core/user-input.d.ts +10 -0
- package/dist/core/user-input.js +35 -0
- package/dist/core/version.d.ts +1 -0
- package/dist/core/version.js +10 -0
- package/dist/core/vibe-modes.d.ts +38 -0
- package/dist/core/vibe-modes.js +383 -0
- package/dist/core/workspace-roots.d.ts +13 -0
- package/dist/core/workspace-roots.js +91 -0
- package/dist/core/workspace-sessions.d.ts +51 -0
- package/dist/core/workspace-sessions.js +243 -0
- package/dist/cowork/client.d.ts +29 -0
- package/dist/cowork/client.js +49 -0
- package/dist/cowork/engine-bridge.d.ts +22 -0
- package/dist/cowork/engine-bridge.js +98 -0
- package/dist/cowork/index.d.ts +11 -0
- package/dist/cowork/index.js +16 -0
- package/dist/cowork/ipc.d.ts +97 -0
- package/dist/cowork/ipc.js +96 -0
- package/dist/cowork/manager.d.ts +66 -0
- package/dist/cowork/manager.js +325 -0
- package/dist/cowork/store.d.ts +23 -0
- package/dist/cowork/store.js +182 -0
- package/dist/cowork/sync.d.ts +20 -0
- package/dist/cowork/sync.js +164 -0
- package/dist/cowork/types.d.ts +78 -0
- package/dist/cowork/types.js +21 -0
- package/dist/extensions/ext-tools.d.ts +3 -0
- package/dist/extensions/ext-tools.js +73 -0
- package/dist/extensions/loader.d.ts +91 -0
- package/dist/extensions/loader.js +474 -0
- package/dist/extensions/settings.d.ts +20 -0
- package/dist/extensions/settings.js +86 -0
- package/dist/extensions/types.d.ts +219 -0
- package/dist/extensions/types.js +1 -0
- package/dist/horizon/async-queue.d.ts +9 -0
- package/dist/horizon/async-queue.js +46 -0
- package/dist/horizon/engine.d.ts +85 -0
- package/dist/horizon/engine.js +603 -0
- package/dist/horizon/index.d.ts +4 -0
- package/dist/horizon/index.js +2 -0
- package/dist/horizon/main-team.d.ts +163 -0
- package/dist/horizon/main-team.js +774 -0
- package/dist/horizon/types.d.ts +233 -0
- package/dist/horizon/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +233 -0
- package/dist/mcp/protocol.d.ts +81 -0
- package/dist/mcp/protocol.js +122 -0
- package/dist/package.json +1 -0
- package/dist/packages/packages.d.ts +12 -0
- package/dist/packages/packages.js +323 -0
- package/dist/prompts/templates.d.ts +13 -0
- package/dist/prompts/templates.js +139 -0
- package/dist/providers/anthropic-oauth.d.ts +13 -0
- package/dist/providers/anthropic-oauth.js +124 -0
- package/dist/providers/anthropic.d.ts +27 -0
- package/dist/providers/anthropic.js +526 -0
- package/dist/providers/catalog.d.ts +15 -0
- package/dist/providers/catalog.js +166 -0
- package/dist/providers/effort.d.ts +12 -0
- package/dist/providers/effort.js +102 -0
- package/dist/providers/model-catalog.d.ts +43 -0
- package/dist/providers/model-catalog.js +70 -0
- package/dist/providers/model-effort.d.ts +5 -0
- package/dist/providers/model-effort.js +43 -0
- package/dist/providers/model-registry.d.ts +39 -0
- package/dist/providers/model-registry.js +142 -0
- package/dist/providers/models-dev.d.ts +9 -0
- package/dist/providers/models-dev.js +97 -0
- package/dist/providers/oauth-callback-server.d.ts +28 -0
- package/dist/providers/oauth-callback-server.js +184 -0
- package/dist/providers/oauth-orchestrator.d.ts +58 -0
- package/dist/providers/oauth-orchestrator.js +159 -0
- package/dist/providers/oauth-store.d.ts +12 -0
- package/dist/providers/oauth-store.js +139 -0
- package/dist/providers/open-browser.d.ts +20 -0
- package/dist/providers/open-browser.js +92 -0
- package/dist/providers/openai-compat.d.ts +14 -0
- package/dist/providers/openai-compat.js +523 -0
- package/dist/providers/openai-oauth.d.ts +15 -0
- package/dist/providers/openai-oauth.js +382 -0
- package/dist/providers/openrouter-auth.d.ts +73 -0
- package/dist/providers/openrouter-auth.js +321 -0
- package/dist/providers/openrouter-manual-fallback.d.ts +25 -0
- package/dist/providers/openrouter-manual-fallback.js +161 -0
- package/dist/providers/openrouter.d.ts +15 -0
- package/dist/providers/openrouter.js +107 -0
- package/dist/providers/plan-limits.d.ts +6 -0
- package/dist/providers/plan-limits.js +175 -0
- package/dist/providers/provider-reset.d.ts +4 -0
- package/dist/providers/provider-reset.js +83 -0
- package/dist/providers/quota-limits.d.ts +4 -0
- package/dist/providers/quota-limits.js +33 -0
- package/dist/providers/registry.d.ts +33 -0
- package/dist/providers/registry.js +213 -0
- package/dist/providers/retry.d.ts +37 -0
- package/dist/providers/retry.js +347 -0
- package/dist/rpc/server.d.ts +23 -0
- package/dist/rpc/server.js +222 -0
- package/dist/sdk.d.ts +67 -0
- package/dist/sdk.js +64 -0
- package/dist/skills/skills.d.ts +17 -0
- package/dist/skills/skills.js +155 -0
- package/dist/text-sanitize.js +28 -0
- package/dist/tools/ask-user.d.ts +2 -0
- package/dist/tools/ask-user.js +60 -0
- package/dist/tools/builtin.d.ts +48 -0
- package/dist/tools/builtin.js +2494 -0
- package/dist/tools/capabilities.d.ts +5 -0
- package/dist/tools/capabilities.js +55 -0
- package/dist/tools/computer-capture.d.ts +2 -0
- package/dist/tools/computer-capture.js +91 -0
- package/dist/tools/computer-posix.d.ts +5 -0
- package/dist/tools/computer-posix.js +136 -0
- package/dist/tools/computer-use.d.ts +14 -0
- package/dist/tools/computer-use.js +108 -0
- package/dist/tools/discovery.d.ts +12 -0
- package/dist/tools/discovery.js +205 -0
- package/dist/tools/execute.d.ts +2 -0
- package/dist/tools/execute.js +73 -0
- package/dist/tools/normalize-input.d.ts +17 -0
- package/dist/tools/normalize-input.js +174 -0
- package/dist/tools/output-artifact.d.ts +3 -0
- package/dist/tools/output-artifact.js +80 -0
- package/dist/tools/pagination.d.ts +15 -0
- package/dist/tools/pagination.js +93 -0
- package/dist/tools/plan-status.d.ts +2 -0
- package/dist/tools/plan-status.js +109 -0
- package/dist/tools/program-input.d.ts +3 -0
- package/dist/tools/program-input.js +19 -0
- package/dist/tools/program.d.ts +3 -0
- package/dist/tools/program.js +567 -0
- package/dist/tools/protocol-catalog.d.ts +12 -0
- package/dist/tools/protocol-catalog.js +46 -0
- package/dist/tools/ramification-tools.d.ts +12 -0
- package/dist/tools/ramification-tools.js +528 -0
- package/dist/tools/regex-compat.d.ts +9 -0
- package/dist/tools/regex-compat.js +96 -0
- package/dist/tools/registry.d.ts +51 -0
- package/dist/tools/registry.js +185 -0
- package/dist/tools/resolve.d.ts +2 -0
- package/dist/tools/resolve.js +107 -0
- package/dist/tools/shell-env.d.ts +2 -0
- package/dist/tools/shell-env.js +7 -0
- package/dist/tools/team-input.d.ts +3 -0
- package/dist/tools/team-input.js +129 -0
- package/dist/tools/team-tools.d.ts +7 -0
- package/dist/tools/team-tools.js +348 -0
- package/dist/tools/workspace-sessions.d.ts +2 -0
- package/dist/tools/workspace-sessions.js +35 -0
- package/dist/tui/account-entry.d.ts +1 -0
- package/dist/tui/account-entry.js +93 -0
- package/dist/tui/attachment-highlight.d.ts +1 -0
- package/dist/tui/attachment-highlight.js +24 -0
- package/dist/tui/attachment-refs.d.ts +2 -0
- package/dist/tui/attachment-refs.js +3 -0
- package/dist/tui/bottom-input.d.ts +219 -0
- package/dist/tui/bottom-input.js +1958 -0
- package/dist/tui/branding.d.ts +107 -0
- package/dist/tui/branding.js +750 -0
- package/dist/tui/clipboard-image.d.ts +10 -0
- package/dist/tui/clipboard-image.js +163 -0
- package/dist/tui/clipboard-text.d.ts +9 -0
- package/dist/tui/clipboard-text.js +51 -0
- package/dist/tui/clipboard-windows.d.ts +8 -0
- package/dist/tui/clipboard-windows.js +84 -0
- package/dist/tui/collapsible-command.d.ts +15 -0
- package/dist/tui/collapsible-command.js +48 -0
- package/dist/tui/command-feedback.d.ts +10 -0
- package/dist/tui/command-feedback.js +46 -0
- package/dist/tui/command-output-registry.d.ts +28 -0
- package/dist/tui/command-output-registry.js +103 -0
- package/dist/tui/command-transcript.d.ts +12 -0
- package/dist/tui/command-transcript.js +90 -0
- package/dist/tui/commands.d.ts +20 -0
- package/dist/tui/commands.js +131 -0
- package/dist/tui/context-bar.d.ts +4 -0
- package/dist/tui/context-bar.js +74 -0
- package/dist/tui/context-meter.d.ts +25 -0
- package/dist/tui/context-meter.js +81 -0
- package/dist/tui/cost-binding.d.ts +8 -0
- package/dist/tui/cost-binding.js +43 -0
- package/dist/tui/cost-tracker.d.ts +49 -0
- package/dist/tui/cost-tracker.js +122 -0
- package/dist/tui/diff.d.ts +9 -0
- package/dist/tui/diff.js +119 -0
- package/dist/tui/i18n-catalog.d.ts +5 -0
- package/dist/tui/i18n-catalog.js +184 -0
- package/dist/tui/i18n.d.ts +6 -0
- package/dist/tui/i18n.js +10 -0
- package/dist/tui/image-attachments.d.ts +46 -0
- package/dist/tui/image-attachments.js +167 -0
- package/dist/tui/images.d.ts +12 -0
- package/dist/tui/images.js +87 -0
- package/dist/tui/intro.d.ts +13 -0
- package/dist/tui/intro.js +109 -0
- package/dist/tui/language-preference.d.ts +6 -0
- package/dist/tui/language-preference.js +24 -0
- package/dist/tui/live-output.d.ts +2 -0
- package/dist/tui/live-output.js +18 -0
- package/dist/tui/locales.d.ts +19 -0
- package/dist/tui/locales.js +22 -0
- package/dist/tui/login-menu.d.ts +17 -0
- package/dist/tui/login-menu.js +58 -0
- package/dist/tui/logo.d.ts +8 -0
- package/dist/tui/logo.js +305 -0
- package/dist/tui/markdown-inline.d.ts +3 -0
- package/dist/tui/markdown-inline.js +99 -0
- package/dist/tui/markdown-table.d.ts +4 -0
- package/dist/tui/markdown-table.js +63 -0
- package/dist/tui/markdown.d.ts +11 -0
- package/dist/tui/markdown.js +257 -0
- package/dist/tui/mcp-transcript.d.ts +7 -0
- package/dist/tui/mcp-transcript.js +40 -0
- package/dist/tui/model-details.d.ts +2 -0
- package/dist/tui/model-details.js +21 -0
- package/dist/tui/model-selection.d.ts +7 -0
- package/dist/tui/model-selection.js +41 -0
- package/dist/tui/native-scrollback.d.ts +27 -0
- package/dist/tui/native-scrollback.js +134 -0
- package/dist/tui/onboarding.d.ts +72 -0
- package/dist/tui/onboarding.js +207 -0
- package/dist/tui/paste-collapse.d.ts +39 -0
- package/dist/tui/paste-collapse.js +117 -0
- package/dist/tui/perm-mode.d.ts +8 -0
- package/dist/tui/perm-mode.js +41 -0
- package/dist/tui/prompt-queue-store.d.ts +26 -0
- package/dist/tui/prompt-queue-store.js +87 -0
- package/dist/tui/prompt-queue.d.ts +47 -0
- package/dist/tui/prompt-queue.js +187 -0
- package/dist/tui/provider-menu.d.ts +33 -0
- package/dist/tui/provider-menu.js +175 -0
- package/dist/tui/question.d.ts +24 -0
- package/dist/tui/question.js +32 -0
- package/dist/tui/queue-screen.d.ts +25 -0
- package/dist/tui/queue-screen.js +152 -0
- package/dist/tui/queue-team.d.ts +3 -0
- package/dist/tui/queue-team.js +28 -0
- package/dist/tui/queued-questions.d.ts +20 -0
- package/dist/tui/queued-questions.js +163 -0
- package/dist/tui/quick-help.d.ts +1 -0
- package/dist/tui/quick-help.js +53 -0
- package/dist/tui/repl.d.ts +78 -0
- package/dist/tui/repl.js +4130 -0
- package/dist/tui/restore-queued-input.d.ts +3 -0
- package/dist/tui/restore-queued-input.js +20 -0
- package/dist/tui/review-detail.d.ts +6 -0
- package/dist/tui/review-detail.js +56 -0
- package/dist/tui/review-files.d.ts +3 -0
- package/dist/tui/review-files.js +22 -0
- package/dist/tui/review-render.d.ts +22 -0
- package/dist/tui/review-render.js +98 -0
- package/dist/tui/review-screen.d.ts +38 -0
- package/dist/tui/review-screen.js +358 -0
- package/dist/tui/review-store.d.ts +60 -0
- package/dist/tui/review-store.js +270 -0
- package/dist/tui/review-team.d.ts +2 -0
- package/dist/tui/review-team.js +27 -0
- package/dist/tui/selector-mouse.d.ts +26 -0
- package/dist/tui/selector-mouse.js +65 -0
- package/dist/tui/selector.d.ts +51 -0
- package/dist/tui/selector.js +299 -0
- package/dist/tui/session-replay.d.ts +10 -0
- package/dist/tui/session-replay.js +78 -0
- package/dist/tui/session-usage.d.ts +22 -0
- package/dist/tui/session-usage.js +55 -0
- package/dist/tui/skill-transcript.d.ts +5 -0
- package/dist/tui/skill-transcript.js +31 -0
- package/dist/tui/startup.d.ts +5 -0
- package/dist/tui/startup.js +61 -0
- package/dist/tui/status-line-loader.d.ts +8 -0
- package/dist/tui/status-line-loader.js +33 -0
- package/dist/tui/status-line.d.ts +38 -0
- package/dist/tui/status-line.js +213 -0
- package/dist/tui/system-language.d.ts +8 -0
- package/dist/tui/system-language.js +41 -0
- package/dist/tui/task-labels.d.ts +2 -0
- package/dist/tui/task-labels.js +7 -0
- package/dist/tui/term-bg.d.ts +4 -0
- package/dist/tui/term-bg.js +67 -0
- package/dist/tui/terminal-screen.d.ts +12 -0
- package/dist/tui/terminal-screen.js +1 -0
- package/dist/tui/terminal-text.d.ts +7 -0
- package/dist/tui/terminal-text.js +123 -0
- package/dist/tui/theme.d.ts +25 -0
- package/dist/tui/theme.js +383 -0
- package/dist/tui/tool-style.d.ts +7 -0
- package/dist/tui/tool-style.js +119 -0
- package/dist/tui/update-prompt.d.ts +14 -0
- package/dist/tui/update-prompt.js +104 -0
- package/dist/tui/usage-footer.d.ts +9 -0
- package/dist/tui/usage-footer.js +123 -0
- package/dist/tui/vascend-login.d.ts +68 -0
- package/dist/tui/vascend-login.js +355 -0
- package/dist/tui/web-login.d.ts +28 -0
- package/dist/tui/web-login.js +115 -0
- package/dist/vascend/activity-status.d.ts +12 -0
- package/dist/vascend/activity-status.js +68 -0
- package/dist/vascend/architecture-map.d.ts +73 -0
- package/dist/vascend/architecture-map.js +424 -0
- package/dist/vascend/attention-layout.d.ts +19 -0
- package/dist/vascend/attention-layout.js +141 -0
- package/dist/vascend/budget-allocator.d.ts +31 -0
- package/dist/vascend/budget-allocator.js +79 -0
- package/dist/vascend/candidate-collector.d.ts +20 -0
- package/dist/vascend/candidate-collector.js +220 -0
- package/dist/vascend/code-events.d.ts +24 -0
- package/dist/vascend/code-events.js +304 -0
- package/dist/vascend/code-graph-memory.d.ts +38 -0
- package/dist/vascend/code-graph-memory.js +334 -0
- package/dist/vascend/code-graph-runtime.d.ts +19 -0
- package/dist/vascend/code-graph-runtime.js +190 -0
- package/dist/vascend/code-graph-types.d.ts +58 -0
- package/dist/vascend/code-graph-types.js +50 -0
- package/dist/vascend/code-parser.d.ts +4 -0
- package/dist/vascend/code-parser.js +257 -0
- package/dist/vascend/competitor-knowledge.d.ts +53 -0
- package/dist/vascend/competitor-knowledge.js +262 -0
- package/dist/vascend/completeness.d.ts +16 -0
- package/dist/vascend/completeness.js +90 -0
- package/dist/vascend/context-autotuner.d.ts +45 -0
- package/dist/vascend/context-autotuner.js +231 -0
- package/dist/vascend/context-candidate.d.ts +45 -0
- package/dist/vascend/context-candidate.js +150 -0
- package/dist/vascend/context-capsule.d.ts +51 -0
- package/dist/vascend/context-capsule.js +133 -0
- package/dist/vascend/context-fabric.d.ts +108 -0
- package/dist/vascend/context-fabric.js +480 -0
- package/dist/vascend/context-feedback-loop.d.ts +56 -0
- package/dist/vascend/context-feedback-loop.js +204 -0
- package/dist/vascend/context-learning-identity.d.ts +4 -0
- package/dist/vascend/context-learning-identity.js +8 -0
- package/dist/vascend/context-links.d.ts +14 -0
- package/dist/vascend/context-links.js +83 -0
- package/dist/vascend/context-lint.d.ts +22 -0
- package/dist/vascend/context-lint.js +91 -0
- package/dist/vascend/context-market-selection.d.ts +17 -0
- package/dist/vascend/context-market-selection.js +50 -0
- package/dist/vascend/context-metrics.d.ts +25 -0
- package/dist/vascend/context-metrics.js +57 -0
- package/dist/vascend/context-pack-render.d.ts +16 -0
- package/dist/vascend/context-pack-render.js +52 -0
- package/dist/vascend/context-pareto.d.ts +33 -0
- package/dist/vascend/context-pareto.js +165 -0
- package/dist/vascend/context-pattern-explorer.d.ts +41 -0
- package/dist/vascend/context-pattern-explorer.js +276 -0
- package/dist/vascend/context-regret.d.ts +32 -0
- package/dist/vascend/context-regret.js +93 -0
- package/dist/vascend/context-retriever.d.ts +22 -0
- package/dist/vascend/context-retriever.js +243 -0
- package/dist/vascend/context-scope-index.d.ts +5 -0
- package/dist/vascend/context-scope-index.js +96 -0
- package/dist/vascend/context-scorer.d.ts +35 -0
- package/dist/vascend/context-scorer.js +162 -0
- package/dist/vascend/context-search-index.d.ts +12 -0
- package/dist/vascend/context-search-index.js +25 -0
- package/dist/vascend/context-snapshot.d.ts +22 -0
- package/dist/vascend/context-snapshot.js +135 -0
- package/dist/vascend/context-window-compiler.d.ts +42 -0
- package/dist/vascend/context-window-compiler.js +237 -0
- package/dist/vascend/contract-memory.d.ts +61 -0
- package/dist/vascend/contract-memory.js +435 -0
- package/dist/vascend/council.d.ts +58 -0
- package/dist/vascend/council.js +337 -0
- package/dist/vascend/decision-promotion.d.ts +48 -0
- package/dist/vascend/decision-promotion.js +410 -0
- package/dist/vascend/delta-context.d.ts +12 -0
- package/dist/vascend/delta-context.js +36 -0
- package/dist/vascend/dev-context-compiler.d.ts +27 -0
- package/dist/vascend/dev-context-compiler.js +133 -0
- package/dist/vascend/dev-context-layout.d.ts +30 -0
- package/dist/vascend/dev-context-layout.js +262 -0
- package/dist/vascend/evidence-slots.d.ts +14 -0
- package/dist/vascend/evidence-slots.js +55 -0
- package/dist/vascend/expansion-levels.d.ts +15 -0
- package/dist/vascend/expansion-levels.js +178 -0
- package/dist/vascend/file-lock.d.ts +7 -0
- package/dist/vascend/file-lock.js +95 -0
- package/dist/vascend/granular-kingdom.d.ts +25 -0
- package/dist/vascend/granular-kingdom.js +259 -0
- package/dist/vascend/granular-launcher.d.ts +48 -0
- package/dist/vascend/granular-launcher.js +202 -0
- package/dist/vascend/kingdom-bus.d.ts +25 -0
- package/dist/vascend/kingdom-bus.js +54 -0
- package/dist/vascend/kingdom-channel.d.ts +22 -0
- package/dist/vascend/kingdom-channel.js +180 -0
- package/dist/vascend/kingdom-kpi.d.ts +48 -0
- package/dist/vascend/kingdom-kpi.js +172 -0
- package/dist/vascend/kingdom-live.d.ts +28 -0
- package/dist/vascend/kingdom-live.js +61 -0
- package/dist/vascend/kingdom-run.d.ts +18 -0
- package/dist/vascend/kingdom-run.js +506 -0
- package/dist/vascend/kingdom-scribe.d.ts +20 -0
- package/dist/vascend/kingdom-scribe.js +52 -0
- package/dist/vascend/kingdom.d.ts +79 -0
- package/dist/vascend/kingdom.js +870 -0
- package/dist/vascend/lexical-index.d.ts +10 -0
- package/dist/vascend/lexical-index.js +99 -0
- package/dist/vascend/lexical-search.d.ts +29 -0
- package/dist/vascend/lexical-search.js +262 -0
- package/dist/vascend/long-term-context.d.ts +51 -0
- package/dist/vascend/long-term-context.js +194 -0
- package/dist/vascend/mandate.d.ts +33 -0
- package/dist/vascend/mandate.js +107 -0
- package/dist/vascend/memory-packet.d.ts +13 -0
- package/dist/vascend/memory-packet.js +155 -0
- package/dist/vascend/memory-status.d.ts +22 -0
- package/dist/vascend/memory-status.js +73 -0
- package/dist/vascend/memory-store.d.ts +62 -0
- package/dist/vascend/memory-store.js +273 -0
- package/dist/vascend/objective-revision.d.ts +69 -0
- package/dist/vascend/objective-revision.js +319 -0
- package/dist/vascend/patch-plan-store.d.ts +33 -0
- package/dist/vascend/patch-plan-store.js +240 -0
- package/dist/vascend/patch-plan.d.ts +97 -0
- package/dist/vascend/patch-plan.js +345 -0
- package/dist/vascend/plan-progress.d.ts +11 -0
- package/dist/vascend/plan-progress.js +68 -0
- package/dist/vascend/plan-store.d.ts +64 -0
- package/dist/vascend/plan-store.js +460 -0
- package/dist/vascend/proof-chains.d.ts +19 -0
- package/dist/vascend/proof-chains.js +120 -0
- package/dist/vascend/ramification-store.d.ts +25 -0
- package/dist/vascend/ramification-store.js +94 -0
- package/dist/vascend/ramification.d.ts +193 -0
- package/dist/vascend/ramification.js +583 -0
- package/dist/vascend/recall-planner.d.ts +17 -0
- package/dist/vascend/recall-planner.js +109 -0
- package/dist/vascend/requirements.d.ts +31 -0
- package/dist/vascend/requirements.js +151 -0
- package/dist/vascend/reviewer.d.ts +9 -0
- package/dist/vascend/reviewer.js +93 -0
- package/dist/vascend/room-graph.d.ts +29 -0
- package/dist/vascend/room-graph.js +242 -0
- package/dist/vascend/room-memory.d.ts +57 -0
- package/dist/vascend/room-memory.js +631 -0
- package/dist/vascend/runtime.d.ts +84 -0
- package/dist/vascend/runtime.js +286 -0
- package/dist/vascend/self-improve.d.ts +104 -0
- package/dist/vascend/self-improve.js +396 -0
- package/dist/vascend/session-search.d.ts +52 -0
- package/dist/vascend/session-search.js +349 -0
- package/dist/vascend/supersession-graph.d.ts +14 -0
- package/dist/vascend/supersession-graph.js +70 -0
- package/dist/vascend/team-areas.d.ts +9 -0
- package/dist/vascend/team-areas.js +28 -0
- package/dist/vascend/team-handoff.d.ts +24 -0
- package/dist/vascend/team-handoff.js +37 -0
- package/dist/vascend/team-scheduler.d.ts +13 -0
- package/dist/vascend/team-scheduler.js +74 -0
- package/dist/vascend/team-session.d.ts +42 -0
- package/dist/vascend/team-session.js +142 -0
- package/dist/vascend/test-failure-memory.d.ts +76 -0
- package/dist/vascend/test-failure-memory.js +354 -0
- package/dist/vascend/token-market.d.ts +42 -0
- package/dist/vascend/token-market.js +144 -0
- package/dist/vascend/tuner-baseline-store.d.ts +52 -0
- package/dist/vascend/tuner-baseline-store.js +446 -0
- package/dist/vascend/user-profile.d.ts +44 -0
- package/dist/vascend/user-profile.js +131 -0
- package/dist/vascend/vision.d.ts +94 -0
- package/dist/vascend/vision.js +375 -0
- package/dist/vascend/work-agent.d.ts +12 -0
- package/dist/vascend/work-agent.js +83 -0
- package/dist/vascend/work-queue.d.ts +62 -0
- package/dist/vascend/work-queue.js +255 -0
- package/dist/vascend/work-runner.d.ts +64 -0
- package/dist/vascend/work-runner.js +137 -0
- package/dist/vascend/worktree.d.ts +38 -0
- package/dist/vascend/worktree.js +206 -0
- package/dist/vendor/computer-use/README.md +7 -0
- package/dist/vendor/computer-use/computer-desktop.js +211 -0
- package/dist/vendor/computer-use/computer-observe.js +315 -0
- package/dist/vendor/computer-use/computer-scripts.js +1230 -0
- package/dist/vendor/computer-use/computer-tools.js +2136 -0
- package/dist/vendor/computer-use/package.json +1 -0
- package/dist/vendor/computer-use/rac/atomic-input.js +91 -0
- package/dist/vendor/computer-use/rac/grammatica.js +101 -0
- package/dist/vendor/computer-use/rac/parser.js +185 -0
- package/dist/vendor/computer-use/rac/protocol.js +136 -0
- package/install.ps1 +30 -0
- package/install.sh +50 -0
- package/package.json +56 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Servizio di autenticazione: lega UserStore e JWT, e fornisce l'estrazione
|
|
2
|
+
// del principale (utente) da una richiesta HTTP/WS. Zero dipendenze.
|
|
3
|
+
import { signToken, verifyToken } from "./crypto.js";
|
|
4
|
+
import { HttpError, toPublicUser } from "./types.js";
|
|
5
|
+
export class AuthService {
|
|
6
|
+
users;
|
|
7
|
+
config;
|
|
8
|
+
constructor(users, config) {
|
|
9
|
+
this.users = users;
|
|
10
|
+
this.config = config;
|
|
11
|
+
}
|
|
12
|
+
register(email, password, displayName) {
|
|
13
|
+
const user = this.users.register(email, password, displayName);
|
|
14
|
+
return this.issue(user);
|
|
15
|
+
}
|
|
16
|
+
login(email, password) {
|
|
17
|
+
const user = this.users.authenticate(email, password);
|
|
18
|
+
return this.issue(user);
|
|
19
|
+
}
|
|
20
|
+
issue(user) {
|
|
21
|
+
const { token, expiresAt } = signToken({ sub: user.id, email: user.email }, this.config.jwtSecret, this.config.tokenTtlSeconds);
|
|
22
|
+
return { token, user: toPublicUser(user), expiresAt };
|
|
23
|
+
}
|
|
24
|
+
// Verifica un token grezzo e ritorna l'utente, o null se invalido.
|
|
25
|
+
resolve(token) {
|
|
26
|
+
if (!token)
|
|
27
|
+
return null;
|
|
28
|
+
const payload = verifyToken(token, this.config.jwtSecret);
|
|
29
|
+
if (!payload)
|
|
30
|
+
return null;
|
|
31
|
+
const user = this.users.get(payload.sub);
|
|
32
|
+
if (!user)
|
|
33
|
+
return null;
|
|
34
|
+
return { payload, user };
|
|
35
|
+
}
|
|
36
|
+
// Estrae il bearer token dall'header Authorization, o dal query param `token`
|
|
37
|
+
// (usato dal client WS che non puo' impostare header custom).
|
|
38
|
+
static extractToken(req) {
|
|
39
|
+
const auth = req.headers["authorization"];
|
|
40
|
+
if (typeof auth === "string" && auth.toLowerCase().startsWith("bearer ")) {
|
|
41
|
+
return auth.slice(7).trim();
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const url = new URL(req.url ?? "", "http://localhost");
|
|
45
|
+
const q = url.searchParams.get("token");
|
|
46
|
+
if (q)
|
|
47
|
+
return q;
|
|
48
|
+
}
|
|
49
|
+
catch { /* url malformata */ }
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
// Richiede un utente autenticato: lancia 401 se assente/invalido.
|
|
53
|
+
requireUser(req) {
|
|
54
|
+
const resolved = this.resolve(AuthService.extractToken(req));
|
|
55
|
+
if (!resolved)
|
|
56
|
+
throw new HttpError(401, "autenticazione richiesta", "unauthorized");
|
|
57
|
+
return resolved.user;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface BackendConfig {
|
|
2
|
+
readonly port: number;
|
|
3
|
+
readonly host: string;
|
|
4
|
+
readonly dataDir: string;
|
|
5
|
+
readonly sessionDir: string;
|
|
6
|
+
readonly cwd: string;
|
|
7
|
+
readonly model: string;
|
|
8
|
+
readonly jwtSecret: string;
|
|
9
|
+
readonly tokenTtlSeconds: number;
|
|
10
|
+
readonly corsOrigins: readonly string[];
|
|
11
|
+
readonly autoApprove: boolean;
|
|
12
|
+
readonly registrationToken: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function buildBackendConfig(env?: NodeJS.ProcessEnv): BackendConfig;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Configurazione del backend, derivata dall'ambiente. Default ragionevoli per
|
|
2
|
+
// far girare il server in locale senza setup. Zero dipendenze.
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, isAbsolute, resolve } from "node:path";
|
|
5
|
+
function resolvePath(p, base) {
|
|
6
|
+
return isAbsolute(p) ? p : resolve(base, p);
|
|
7
|
+
}
|
|
8
|
+
export function buildBackendConfig(env = process.env) {
|
|
9
|
+
const cwd = env["TALOS_BACKEND_CWD"] ?? process.cwd();
|
|
10
|
+
const home = homedir();
|
|
11
|
+
const dataDir = env["TALOS_BACKEND_DATA_DIR"]
|
|
12
|
+
? resolvePath(env["TALOS_BACKEND_DATA_DIR"], cwd)
|
|
13
|
+
: join(home, ".talos", "backend");
|
|
14
|
+
const sessionDir = env["TALOS_BACKEND_SESSION_DIR"]
|
|
15
|
+
? resolvePath(env["TALOS_BACKEND_SESSION_DIR"], cwd)
|
|
16
|
+
: join(dataDir, "sessions");
|
|
17
|
+
const port = Number(env["TALOS_BACKEND_PORT"] ?? env["PORT"] ?? 8787);
|
|
18
|
+
const ttl = Number(env["TALOS_BACKEND_TOKEN_TTL"] ?? 60 * 60 * 24 * 7); // 7 giorni
|
|
19
|
+
const corsRaw = env["TALOS_BACKEND_CORS"] ?? "";
|
|
20
|
+
const corsOrigins = corsRaw === "*" ? ["*"] : corsRaw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
21
|
+
const host = env["TALOS_BACKEND_HOST"] ?? "127.0.0.1";
|
|
22
|
+
if (!["127.0.0.1", "::1", "localhost"].includes(host)) {
|
|
23
|
+
throw new Error("Talos backend shares the host workspace and must bind to loopback. Use an authenticated local tunnel for remote access.");
|
|
24
|
+
}
|
|
25
|
+
const registrationToken = env["TALOS_BACKEND_REGISTRATION_TOKEN"] ?? "";
|
|
26
|
+
if (registrationToken && registrationToken.length < 32)
|
|
27
|
+
throw new Error("Registration token must contain at least 32 characters");
|
|
28
|
+
return {
|
|
29
|
+
port: Number.isFinite(port) && port > 0 ? port : 8787,
|
|
30
|
+
host,
|
|
31
|
+
dataDir,
|
|
32
|
+
sessionDir,
|
|
33
|
+
cwd,
|
|
34
|
+
model: env["TALOS_BACKEND_MODEL"] ?? env["TALOS_MODEL"] ?? "anthropic/claude-sonnet-4-6",
|
|
35
|
+
jwtSecret: env["TALOS_BACKEND_JWT_SECRET"] ?? "",
|
|
36
|
+
tokenTtlSeconds: Number.isFinite(ttl) && ttl > 0 ? ttl : 60 * 60 * 24 * 7,
|
|
37
|
+
corsOrigins,
|
|
38
|
+
autoApprove: env["TALOS_BACKEND_AUTO_APPROVE"] === "1",
|
|
39
|
+
registrationToken,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Session } from "../core/session.js";
|
|
2
|
+
import { type Conversation, type ConversationMessage } from "./types.js";
|
|
3
|
+
export declare class ConversationStore {
|
|
4
|
+
private readonly file;
|
|
5
|
+
private readonly sessionDir;
|
|
6
|
+
private readonly byId;
|
|
7
|
+
private constructor();
|
|
8
|
+
static open(dataDir: string, sessionDir: string): ConversationStore;
|
|
9
|
+
create(userId: string, opts: {
|
|
10
|
+
title?: string;
|
|
11
|
+
model: string;
|
|
12
|
+
}): Conversation;
|
|
13
|
+
listFor(userId: string): Conversation[];
|
|
14
|
+
require(id: string, userId: string): Conversation;
|
|
15
|
+
rename(id: string, userId: string, title: string): Conversation;
|
|
16
|
+
touch(id: string): void;
|
|
17
|
+
delete(id: string, userId: string): void;
|
|
18
|
+
openSession(id: string): Session;
|
|
19
|
+
messages(id: string, userId: string): ConversationMessage[];
|
|
20
|
+
private persist;
|
|
21
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// Store delle conversazioni: metadati (titolo, proprietario, modello) su file
|
|
2
|
+
// JSONL append-only, mentre il CONTENUTO del dialogo vive nelle Session
|
|
3
|
+
// dell'engine (sessionDir/<id>.jsonl). La conversazione e la Session
|
|
4
|
+
// condividono lo stesso id. Zero dipendenze.
|
|
5
|
+
import { appendFileSync, mkdirSync, readFileSync, existsSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { Session } from "../core/session.js";
|
|
8
|
+
import { newId } from "./crypto.js";
|
|
9
|
+
import { HttpError } from "./types.js";
|
|
10
|
+
function isDelete(e) {
|
|
11
|
+
return e.op === "delete";
|
|
12
|
+
}
|
|
13
|
+
export class ConversationStore {
|
|
14
|
+
file;
|
|
15
|
+
sessionDir;
|
|
16
|
+
byId = new Map();
|
|
17
|
+
constructor(file, sessionDir) {
|
|
18
|
+
this.file = file;
|
|
19
|
+
this.sessionDir = sessionDir;
|
|
20
|
+
}
|
|
21
|
+
static open(dataDir, sessionDir) {
|
|
22
|
+
mkdirSync(dataDir, { recursive: true });
|
|
23
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
24
|
+
const store = new ConversationStore(join(dataDir, "conversations.jsonl"), sessionDir);
|
|
25
|
+
if (existsSync(store.file)) {
|
|
26
|
+
const raw = readFileSync(store.file, "utf8");
|
|
27
|
+
for (const line of raw.split("\n")) {
|
|
28
|
+
if (!line.trim())
|
|
29
|
+
continue;
|
|
30
|
+
try {
|
|
31
|
+
const e = JSON.parse(line);
|
|
32
|
+
if (isDelete(e))
|
|
33
|
+
store.byId.delete(e.id);
|
|
34
|
+
else
|
|
35
|
+
store.byId.set(e.id, stripOp(e));
|
|
36
|
+
}
|
|
37
|
+
catch { /* riga corrotta */ }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return store;
|
|
41
|
+
}
|
|
42
|
+
// Crea una conversazione per l'utente e la Session sottostante.
|
|
43
|
+
create(userId, opts) {
|
|
44
|
+
const id = `s-${newId("conv").split("_")[1]}`;
|
|
45
|
+
Session.create(this.sessionDir, id); // garantisce il file della sessione
|
|
46
|
+
const now = Date.now();
|
|
47
|
+
const conv = {
|
|
48
|
+
id,
|
|
49
|
+
userId,
|
|
50
|
+
title: (opts.title ?? "Nuova conversazione").slice(0, 200),
|
|
51
|
+
model: opts.model,
|
|
52
|
+
createdAt: now,
|
|
53
|
+
updatedAt: now,
|
|
54
|
+
};
|
|
55
|
+
this.persist(conv);
|
|
56
|
+
return conv;
|
|
57
|
+
}
|
|
58
|
+
// Conversazioni di un utente, dalla piu' recente.
|
|
59
|
+
listFor(userId) {
|
|
60
|
+
return [...this.byId.values()]
|
|
61
|
+
.filter((c) => c.userId === userId)
|
|
62
|
+
.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
63
|
+
}
|
|
64
|
+
// Recupera una conversazione assicurando che appartenga all'utente.
|
|
65
|
+
require(id, userId) {
|
|
66
|
+
const conv = this.byId.get(id);
|
|
67
|
+
if (!conv)
|
|
68
|
+
throw new HttpError(404, "conversazione non trovata", "not_found");
|
|
69
|
+
if (conv.userId !== userId)
|
|
70
|
+
throw new HttpError(403, "accesso negato", "forbidden");
|
|
71
|
+
return conv;
|
|
72
|
+
}
|
|
73
|
+
rename(id, userId, title) {
|
|
74
|
+
const conv = this.require(id, userId);
|
|
75
|
+
const next = { ...conv, title: title.slice(0, 200), updatedAt: Date.now() };
|
|
76
|
+
this.persist(next);
|
|
77
|
+
return next;
|
|
78
|
+
}
|
|
79
|
+
touch(id) {
|
|
80
|
+
const conv = this.byId.get(id);
|
|
81
|
+
if (!conv)
|
|
82
|
+
return;
|
|
83
|
+
this.persist({ ...conv, updatedAt: Date.now() });
|
|
84
|
+
}
|
|
85
|
+
delete(id, userId) {
|
|
86
|
+
this.require(id, userId);
|
|
87
|
+
this.byId.delete(id);
|
|
88
|
+
appendFileSync(this.file, JSON.stringify({ op: "delete", id }) + "\n", "utf8");
|
|
89
|
+
}
|
|
90
|
+
// Apre (o ricarica) la Session dell'engine per questa conversazione.
|
|
91
|
+
openSession(id) {
|
|
92
|
+
return Session.load(this.sessionDir, id);
|
|
93
|
+
}
|
|
94
|
+
// Proiezione dei messaggi del dialogo per il client (storia lineare).
|
|
95
|
+
messages(id, userId) {
|
|
96
|
+
this.require(id, userId);
|
|
97
|
+
const session = Session.load(this.sessionDir, id);
|
|
98
|
+
return session.history().map(projectMessage).filter((m) => m !== null);
|
|
99
|
+
}
|
|
100
|
+
persist(conv) {
|
|
101
|
+
this.byId.set(conv.id, conv);
|
|
102
|
+
appendFileSync(this.file, JSON.stringify({ ...conv, op: "upsert" }) + "\n", "utf8");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function stripOp(e) {
|
|
106
|
+
const { op, ...conv } = e;
|
|
107
|
+
void op;
|
|
108
|
+
return conv;
|
|
109
|
+
}
|
|
110
|
+
// Converte un Message dell'engine nella proiezione del client. Salta i messaggi
|
|
111
|
+
// di sistema/riepilogo che non aggiungono valore al dialogo.
|
|
112
|
+
function projectMessage(m) {
|
|
113
|
+
if (m.role === "system")
|
|
114
|
+
return null;
|
|
115
|
+
const text = m.content
|
|
116
|
+
.filter((p) => p.type === "text")
|
|
117
|
+
.map((p) => p.text)
|
|
118
|
+
.join("")
|
|
119
|
+
.trim();
|
|
120
|
+
const toolCalls = m.content
|
|
121
|
+
.filter((p) => p.type === "tool_call")
|
|
122
|
+
.map((p) => {
|
|
123
|
+
const c = p;
|
|
124
|
+
return { id: c.id, name: c.name, input: c.input };
|
|
125
|
+
});
|
|
126
|
+
const toolResults = m.content
|
|
127
|
+
.filter((p) => p.type === "tool_result")
|
|
128
|
+
.map((p) => {
|
|
129
|
+
const r = p;
|
|
130
|
+
return { callId: r.callId, output: r.output, isError: r.isError };
|
|
131
|
+
});
|
|
132
|
+
if (!text && !toolCalls.length && !toolResults.length)
|
|
133
|
+
return null;
|
|
134
|
+
return {
|
|
135
|
+
role: m.role,
|
|
136
|
+
text,
|
|
137
|
+
...(toolCalls.length ? { toolCalls } : {}),
|
|
138
|
+
...(toolResults.length ? { toolResults } : {}),
|
|
139
|
+
ts: Date.now(),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AuthTokenPayload } from "./types.js";
|
|
2
|
+
export declare function hashPassword(password: string): string;
|
|
3
|
+
export declare function verifyPassword(password: string, stored: string): boolean;
|
|
4
|
+
export declare function newId(prefix: string): string;
|
|
5
|
+
export declare function signToken(payload: Omit<AuthTokenPayload, "iat" | "exp">, secret: string, ttlSeconds: number): {
|
|
6
|
+
token: string;
|
|
7
|
+
expiresAt: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function verifyToken(token: string, secret: string): AuthTokenPayload | null;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Primitive crittografiche del backend: hashing password (scrypt) e JWT
|
|
2
|
+
// (HS256) implementati con il solo modulo `node:crypto`. Zero dipendenze.
|
|
3
|
+
import { scryptSync, randomBytes, timingSafeEqual, createHmac, randomUUID } from "node:crypto";
|
|
4
|
+
const SCRYPT_KEYLEN = 64;
|
|
5
|
+
// Hash di una password: "salt:hash" in hex. scrypt e' deliberatamente lento.
|
|
6
|
+
export function hashPassword(password) {
|
|
7
|
+
const salt = randomBytes(16);
|
|
8
|
+
const hash = scryptSync(password, salt, SCRYPT_KEYLEN);
|
|
9
|
+
return `${salt.toString("hex")}:${hash.toString("hex")}`;
|
|
10
|
+
}
|
|
11
|
+
// Verifica una password contro l'hash memorizzato, in tempo costante.
|
|
12
|
+
export function verifyPassword(password, stored) {
|
|
13
|
+
const [saltHex, hashHex] = stored.split(":");
|
|
14
|
+
if (!saltHex || !hashHex)
|
|
15
|
+
return false;
|
|
16
|
+
const salt = Buffer.from(saltHex, "hex");
|
|
17
|
+
const expected = Buffer.from(hashHex, "hex");
|
|
18
|
+
const actual = scryptSync(password, salt, expected.length);
|
|
19
|
+
return actual.length === expected.length && timingSafeEqual(actual, expected);
|
|
20
|
+
}
|
|
21
|
+
export function newId(prefix) {
|
|
22
|
+
return `${prefix}_${randomUUID().replace(/-/g, "").slice(0, 24)}`;
|
|
23
|
+
}
|
|
24
|
+
// --- JWT HS256 ---------------------------------------------------------------
|
|
25
|
+
function base64url(input) {
|
|
26
|
+
return Buffer.from(input).toString("base64url");
|
|
27
|
+
}
|
|
28
|
+
function sign(data, secret) {
|
|
29
|
+
return createHmac("sha256", secret).update(data).digest("base64url");
|
|
30
|
+
}
|
|
31
|
+
// Emette un JWT firmato HS256. `payload` senza iat/exp: li calcoliamo qui.
|
|
32
|
+
export function signToken(payload, secret, ttlSeconds) {
|
|
33
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
34
|
+
const exp = iat + ttlSeconds;
|
|
35
|
+
const full = { ...payload, iat, exp };
|
|
36
|
+
const header = base64url(JSON.stringify({ alg: "HS256", typ: "JWT" }));
|
|
37
|
+
const body = base64url(JSON.stringify(full));
|
|
38
|
+
const signature = sign(`${header}.${body}`, secret);
|
|
39
|
+
return { token: `${header}.${body}.${signature}`, expiresAt: exp * 1000 };
|
|
40
|
+
}
|
|
41
|
+
// Verifica firma e scadenza; ritorna il payload o null se invalido/scaduto.
|
|
42
|
+
export function verifyToken(token, secret) {
|
|
43
|
+
if (token.length > 8192 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(token))
|
|
44
|
+
return null;
|
|
45
|
+
const parts = token.split(".");
|
|
46
|
+
if (parts.length !== 3)
|
|
47
|
+
return null;
|
|
48
|
+
const [header, body, signature] = parts;
|
|
49
|
+
const expected = sign(`${header}.${body}`, secret);
|
|
50
|
+
const a = Buffer.from(signature);
|
|
51
|
+
const b = Buffer.from(expected);
|
|
52
|
+
if (a.length !== b.length || !timingSafeEqual(a, b))
|
|
53
|
+
return null;
|
|
54
|
+
try {
|
|
55
|
+
const metadata = JSON.parse(Buffer.from(header, "base64url").toString("utf8"));
|
|
56
|
+
if (metadata?.alg !== "HS256" || metadata?.typ !== "JWT")
|
|
57
|
+
return null;
|
|
58
|
+
const payload = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
|
|
59
|
+
if (!payload || typeof payload.exp !== "number" || !Number.isFinite(payload.exp)
|
|
60
|
+
|| payload.exp * 1000 <= Date.now() || typeof payload.sub !== "string" || !payload.sub
|
|
61
|
+
|| typeof payload.iat !== "number" || !Number.isFinite(payload.iat))
|
|
62
|
+
return null;
|
|
63
|
+
return payload;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentEvent, EventSink } from "../core/types.js";
|
|
2
|
+
import type { BackendConfig } from "./config.js";
|
|
3
|
+
export declare class EngineBridge {
|
|
4
|
+
private readonly config;
|
|
5
|
+
private readonly live;
|
|
6
|
+
constructor(config: BackendConfig);
|
|
7
|
+
private ensure;
|
|
8
|
+
isBusy(conversationId: string): boolean;
|
|
9
|
+
prompt(conversationId: string, model: string, text: string, sink: EventSink): Promise<void>;
|
|
10
|
+
abort(conversationId: string): boolean;
|
|
11
|
+
promptCollect(conversationId: string, model: string, text: string): Promise<AgentEvent[]>;
|
|
12
|
+
evict(conversationId: string): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Bridge verso l'engine vascend-talos. Per ogni conversazione costruisce un
|
|
2
|
+
// Harness (bootstrap) legato alla Session di quella conversazione, ed esegue i
|
|
3
|
+
// turni dell'agente (runTurn) inoltrando gli AgentEvent ai sink registrati
|
|
4
|
+
// (WebSocket o accumulatore HTTP). Zero dipendenze a runtime: tutto via SDK.
|
|
5
|
+
import { bootstrap } from "../core/bootstrap.js";
|
|
6
|
+
import { runTurn } from "../core/agent.js";
|
|
7
|
+
export class EngineBridge {
|
|
8
|
+
config;
|
|
9
|
+
live = new Map();
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async ensure(conversationId, model) {
|
|
14
|
+
const existing = this.live.get(conversationId);
|
|
15
|
+
if (existing)
|
|
16
|
+
return existing;
|
|
17
|
+
const harness = await bootstrap({
|
|
18
|
+
cwd: this.config.cwd,
|
|
19
|
+
model,
|
|
20
|
+
sessionId: conversationId,
|
|
21
|
+
env: { ...process.env, TALOS_BACKEND_SESSION_DIR: this.config.sessionDir },
|
|
22
|
+
});
|
|
23
|
+
// La Session vive in sessionDir del backend: forziamo la config a puntarci
|
|
24
|
+
// cosi' bootstrap carica/persiste la conversazione giusta.
|
|
25
|
+
if (harness.config.sessionDir !== this.config.sessionDir) {
|
|
26
|
+
harness.config = { ...harness.config, sessionDir: this.config.sessionDir };
|
|
27
|
+
harness.loadSession(conversationId);
|
|
28
|
+
}
|
|
29
|
+
const live = { harness, controller: null };
|
|
30
|
+
this.live.set(conversationId, live);
|
|
31
|
+
return live;
|
|
32
|
+
}
|
|
33
|
+
// True se un giro e' gia' in corso per la conversazione.
|
|
34
|
+
isBusy(conversationId) {
|
|
35
|
+
return this.live.get(conversationId)?.controller != null;
|
|
36
|
+
}
|
|
37
|
+
// Esegue un prompt e fa lo streaming degli eventi al sink. Risolve a giro
|
|
38
|
+
// concluso (done/error). Rifiuta se un altro giro e' attivo.
|
|
39
|
+
async prompt(conversationId, model, text, sink) {
|
|
40
|
+
const live = await this.ensure(conversationId, model);
|
|
41
|
+
if (live.controller) {
|
|
42
|
+
sink({ type: "error", message: "un giro e' gia' in corso per questa conversazione" });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const controller = new AbortController();
|
|
46
|
+
live.controller = controller;
|
|
47
|
+
const deps = live.harness.deps(async () => this.config.autoApprove);
|
|
48
|
+
try {
|
|
49
|
+
await runTurn(deps, text, sink, controller.signal);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
sink({ type: "error", message: err.message });
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
live.controller = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Interrompe il giro in corso (se presente).
|
|
59
|
+
abort(conversationId) {
|
|
60
|
+
const live = this.live.get(conversationId);
|
|
61
|
+
if (live?.controller) {
|
|
62
|
+
live.controller.abort();
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
// Esegue un prompt accumulando tutti gli eventi (uso HTTP sincrono).
|
|
68
|
+
async promptCollect(conversationId, model, text) {
|
|
69
|
+
const events = [];
|
|
70
|
+
await this.prompt(conversationId, model, text, (e) => events.push(e));
|
|
71
|
+
return events;
|
|
72
|
+
}
|
|
73
|
+
// Rilascia lo stato caldo di una conversazione (es. dopo delete).
|
|
74
|
+
evict(conversationId) {
|
|
75
|
+
this.abort(conversationId);
|
|
76
|
+
this.live.delete(conversationId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { BackendConfig } from "./config.js";
|
|
3
|
+
export interface RouteMatch {
|
|
4
|
+
readonly params: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export declare function readJson<T = unknown>(req: IncomingMessage): Promise<T>;
|
|
7
|
+
export declare function readBinary(req: IncomingMessage, maxBytes?: number): Promise<Buffer>;
|
|
8
|
+
export declare function applyCors(res: ServerResponse, origin: string | undefined, config: BackendConfig): void;
|
|
9
|
+
export declare function sendJson(res: ServerResponse, status: number, body: unknown): void;
|
|
10
|
+
export declare function sendBinary(res: ServerResponse, status: number, data: Buffer, mime: string, filename?: string): void;
|
|
11
|
+
export declare function sendError(res: ServerResponse, err: unknown): void;
|
|
12
|
+
export type Method = "GET" | "POST" | "PATCH" | "DELETE";
|
|
13
|
+
export type Handler = (req: IncomingMessage, res: ServerResponse, match: RouteMatch) => Promise<void> | void;
|
|
14
|
+
export declare class Router {
|
|
15
|
+
private readonly routes;
|
|
16
|
+
add(method: Method, pattern: string, handler: Handler): this;
|
|
17
|
+
get(p: string, h: Handler): this;
|
|
18
|
+
post(p: string, h: Handler): this;
|
|
19
|
+
patch(p: string, h: Handler): this;
|
|
20
|
+
delete(p: string, h: Handler): this;
|
|
21
|
+
resolve(method: string, path: string): {
|
|
22
|
+
handler: Handler;
|
|
23
|
+
match: RouteMatch;
|
|
24
|
+
} | null;
|
|
25
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Utilita' HTTP minimali sopra node:http: parsing del body JSON, risposta
|
|
2
|
+
// JSON, gestione CORS e matching di route con parametri. Zero dipendenze.
|
|
3
|
+
import { HttpError } from "./types.js";
|
|
4
|
+
// Legge e parsa il body come JSON (limite anti-abuso 1MB). {} se vuoto.
|
|
5
|
+
export async function readJson(req) {
|
|
6
|
+
const chunks = [];
|
|
7
|
+
let size = 0;
|
|
8
|
+
for await (const chunk of req) {
|
|
9
|
+
size += chunk.length;
|
|
10
|
+
if (size > 1_000_000)
|
|
11
|
+
throw new HttpError(413, "body troppo grande", "payload_too_large");
|
|
12
|
+
chunks.push(chunk);
|
|
13
|
+
}
|
|
14
|
+
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
15
|
+
if (!raw)
|
|
16
|
+
return {};
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(raw);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new HttpError(400, "JSON non valido", "invalid_json");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Legge il body raw come Buffer binario (per upload di asset). Il limite e'
|
|
25
|
+
// parametrico (default 10MB) per non bloccare asset di esempio piu' grandi del
|
|
26
|
+
// limite JSON. Ritorna un Buffer vuoto se non c'e' body.
|
|
27
|
+
export async function readBinary(req, maxBytes = 10 * 1024 * 1024) {
|
|
28
|
+
const chunks = [];
|
|
29
|
+
let size = 0;
|
|
30
|
+
for await (const chunk of req) {
|
|
31
|
+
size += chunk.length;
|
|
32
|
+
if (size > maxBytes)
|
|
33
|
+
throw new HttpError(413, "body troppo grande", "payload_too_large");
|
|
34
|
+
chunks.push(chunk);
|
|
35
|
+
}
|
|
36
|
+
return Buffer.concat(chunks);
|
|
37
|
+
}
|
|
38
|
+
export function applyCors(res, origin, config) {
|
|
39
|
+
const allowed = config.corsOrigins.includes("*")
|
|
40
|
+
? "*"
|
|
41
|
+
: origin && config.corsOrigins.includes(origin)
|
|
42
|
+
? origin
|
|
43
|
+
: config.corsOrigins[0] ?? "";
|
|
44
|
+
if (allowed)
|
|
45
|
+
res.setHeader("Access-Control-Allow-Origin", allowed);
|
|
46
|
+
res.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,OPTIONS");
|
|
47
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
48
|
+
res.setHeader("Access-Control-Max-Age", "86400");
|
|
49
|
+
}
|
|
50
|
+
export function sendJson(res, status, body) {
|
|
51
|
+
const payload = JSON.stringify(body);
|
|
52
|
+
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
|
|
53
|
+
res.end(payload);
|
|
54
|
+
}
|
|
55
|
+
// Invia un body binario (download di asset) con MIME e nome file opzionali.
|
|
56
|
+
export function sendBinary(res, status, data, mime, filename) {
|
|
57
|
+
const headers = {
|
|
58
|
+
"Content-Type": mime || "application/octet-stream",
|
|
59
|
+
"Content-Length": String(data.length),
|
|
60
|
+
};
|
|
61
|
+
if (filename) {
|
|
62
|
+
const safe = filename.replace(/["\\\r\n]/g, "_");
|
|
63
|
+
headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
64
|
+
}
|
|
65
|
+
res.writeHead(status, headers);
|
|
66
|
+
res.end(data);
|
|
67
|
+
}
|
|
68
|
+
export function sendError(res, err) {
|
|
69
|
+
if (err instanceof HttpError) {
|
|
70
|
+
sendJson(res, err.status, { error: err.message, code: err.code });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const message = err instanceof Error ? err.message : "errore interno";
|
|
74
|
+
sendJson(res, 500, { error: message, code: "internal_error" });
|
|
75
|
+
}
|
|
76
|
+
// Router minimale: pattern come "/api/conversations/:id". Niente regex esotiche.
|
|
77
|
+
export class Router {
|
|
78
|
+
routes = [];
|
|
79
|
+
add(method, pattern, handler) {
|
|
80
|
+
this.routes.push({ method, pattern, segments: pattern.split("/").filter(Boolean), handler });
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
get(p, h) { return this.add("GET", p, h); }
|
|
84
|
+
post(p, h) { return this.add("POST", p, h); }
|
|
85
|
+
patch(p, h) { return this.add("PATCH", p, h); }
|
|
86
|
+
delete(p, h) { return this.add("DELETE", p, h); }
|
|
87
|
+
// Trova la route corrispondente a metodo+path, estraendo i parametri.
|
|
88
|
+
resolve(method, path) {
|
|
89
|
+
const parts = path.split("/").filter(Boolean);
|
|
90
|
+
for (const route of this.routes) {
|
|
91
|
+
if (route.method !== method)
|
|
92
|
+
continue;
|
|
93
|
+
if (route.segments.length !== parts.length)
|
|
94
|
+
continue;
|
|
95
|
+
const params = {};
|
|
96
|
+
let ok = true;
|
|
97
|
+
for (let i = 0; i < route.segments.length; i += 1) {
|
|
98
|
+
const seg = route.segments[i];
|
|
99
|
+
const val = parts[i];
|
|
100
|
+
if (seg.startsWith(":"))
|
|
101
|
+
params[seg.slice(1)] = decodeURIComponent(val);
|
|
102
|
+
else if (seg !== val) {
|
|
103
|
+
ok = false;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (ok)
|
|
108
|
+
return { handler: route.handler, match: { params } };
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Entrypoint del backend: avvia il server e gestisce lo shutdown pulito.
|
|
2
|
+
// Esegui con: bun run src/backend/index.ts (o tramite lo script npm).
|
|
3
|
+
import { createBackend } from "./server.js";
|
|
4
|
+
async function main() {
|
|
5
|
+
const backend = createBackend(process.env);
|
|
6
|
+
const { host, port } = await backend.listen();
|
|
7
|
+
process.stdout.write(`[backend] in ascolto su http://${host}:${port} (WS: ws://${host}:${port}/ws)\n`);
|
|
8
|
+
process.stdout.write(`[backend] modello di default: ${backend.config.model}\n`);
|
|
9
|
+
const shutdown = async (sig) => {
|
|
10
|
+
process.stdout.write(`\n[backend] ${sig}: chiusura...\n`);
|
|
11
|
+
try {
|
|
12
|
+
await backend.close();
|
|
13
|
+
}
|
|
14
|
+
finally {
|
|
15
|
+
process.exit(0);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
19
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
20
|
+
}
|
|
21
|
+
main().catch((err) => {
|
|
22
|
+
process.stderr.write(`[backend] errore fatale: ${err.message}\n`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Router } from "./http.js";
|
|
2
|
+
import type { AuthService } from "./auth.js";
|
|
3
|
+
import type { ConversationStore } from "./conversations.js";
|
|
4
|
+
import type { AssetStore } from "./assets.js";
|
|
5
|
+
import type { EngineBridge } from "./engine.js";
|
|
6
|
+
import type { BackendConfig } from "./config.js";
|
|
7
|
+
export interface RouteDeps {
|
|
8
|
+
readonly auth: AuthService;
|
|
9
|
+
readonly conversations: ConversationStore;
|
|
10
|
+
readonly assets: AssetStore;
|
|
11
|
+
readonly engine: EngineBridge;
|
|
12
|
+
readonly config: BackendConfig;
|
|
13
|
+
}
|
|
14
|
+
export declare function buildRouter(deps: RouteDeps): Router;
|