talos-code 0.0.1 → 0.2.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/CHANGELOG.md +87 -0
- package/LICENSE +661 -0
- package/README.md +116 -3
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/archive/zip.js +73 -0
- package/dist/args.js +100 -0
- package/dist/automations/history-store.js +34 -0
- package/dist/automations/policy-store.js +43 -0
- package/dist/automations/runner.js +107 -0
- package/dist/automations/schedule.js +85 -0
- package/dist/automations/windows-task.js +53 -0
- package/dist/commands/advanced-cli.js +233 -0
- package/dist/commands/checkpoint-cli.js +45 -0
- package/dist/commands/config-cli.js +107 -0
- package/dist/commands/context.js +17 -0
- package/dist/commands/extensions-cli.js +207 -0
- package/dist/commands/project-cli.js +74 -0
- package/dist/commands/project-commands.js +143 -0
- package/dist/commands/provider-cli.js +244 -0
- package/dist/commands/services-cli.js +248 -0
- package/dist/commands/session-cli.js +171 -0
- package/dist/commands/system-cli.js +405 -0
- package/dist/config/commands.js +60 -0
- package/dist/config/load.js +382 -0
- package/dist/config/migrations.js +48 -0
- package/dist/config/types.js +11 -0
- package/dist/diagnostics/development-log.js +154 -0
- package/dist/diagnostics/doctor.js +104 -0
- package/dist/diagnostics/redact.js +80 -0
- package/dist/diagnostics/zip.js +52 -0
- package/dist/errors.js +156 -0
- package/dist/events/bridge.js +130 -0
- package/dist/extensions/installer.js +178 -0
- package/dist/extensions/package-schema.js +24 -0
- package/dist/headless/result.js +84 -0
- package/dist/headless/run.js +230 -0
- package/dist/i18n/en/approval.js +46 -0
- package/dist/i18n/en/common.js +9 -0
- package/dist/i18n/en/credentials.js +92 -0
- package/dist/i18n/en/errors.js +267 -0
- package/dist/i18n/en/firstrun.js +101 -0
- package/dist/i18n/en/providers.js +37 -0
- package/dist/i18n/en/screen.js +774 -0
- package/dist/i18n/en/tools.js +127 -0
- package/dist/i18n/en.js +14 -0
- package/dist/i18n/error-view.js +307 -0
- package/dist/i18n/index.js +19 -0
- package/dist/i18n/kernel-map.js +139 -0
- package/dist/io.js +45 -0
- package/dist/main.js +331 -0
- package/dist/paths.js +41 -0
- package/dist/protocol/v2/codec.js +9 -0
- package/dist/protocol/v2/events.js +555 -0
- package/dist/protocol/v2/index.js +4 -0
- package/dist/protocol/v2/replay.js +28 -0
- package/dist/protocol/v2/types.js +1 -0
- package/dist/provider/control-plane.js +135 -0
- package/dist/provider/environment-keys.js +275 -0
- package/dist/provider/health.js +110 -0
- package/dist/provider/missing-key.js +48 -0
- package/dist/provider/model-catalog.js +168 -0
- package/dist/provider/openrouter-login.js +172 -0
- package/dist/provider/provider-text.js +13 -0
- package/dist/provider/store.js +95 -0
- package/dist/provider/system-keyring.js +214 -0
- package/dist/runtime/active-run.js +63 -0
- package/dist/runtime/agent-tree.js +74 -0
- package/dist/runtime/attachments.js +84 -0
- package/dist/runtime/brokered-executor.js +395 -0
- package/dist/runtime/context-archive.js +69 -0
- package/dist/runtime/context-status.js +76 -0
- package/dist/runtime/create-runtime.js +111 -0
- package/dist/runtime/model-profile.js +361 -0
- package/dist/runtime/output-store.js +137 -0
- package/dist/runtime/provider-attempts.js +185 -0
- package/dist/runtime/replay-buffer.js +153 -0
- package/dist/runtime/repo.js +95 -0
- package/dist/runtime/session-facade.js +135 -0
- package/dist/runtime/session-summary.js +125 -0
- package/dist/runtime/supervisor.js +265 -0
- package/dist/runtime/talos-composition.js +1011 -0
- package/dist/runtime/types.js +5 -0
- package/dist/runtime/usage-snapshot.js +82 -0
- package/dist/security/auto-classifier.js +38 -0
- package/dist/security/credential-free-environment.js +54 -0
- package/dist/security/evaluate.js +243 -0
- package/dist/security/execution-backends.js +236 -0
- package/dist/security/execution-broker.js +102 -0
- package/dist/security/forge-scan.js +74 -0
- package/dist/security/from-approval.js +39 -0
- package/dist/security/mxc-execution-backend.js +281 -0
- package/dist/security/permission-engine.js +138 -0
- package/dist/security/permission-explanation.js +54 -0
- package/dist/security/persist.js +179 -0
- package/dist/security/plugin-guard.js +230 -0
- package/dist/security/process-tree-evidence-store.js +74 -0
- package/dist/security/process-tree-probe.js +554 -0
- package/dist/security/project-resource-inventory.js +186 -0
- package/dist/security/project-trust-gate.js +38 -0
- package/dist/security/project-trust.js +367 -0
- package/dist/security/rule-parser.js +201 -0
- package/dist/security/shell-segmentation.js +68 -0
- package/dist/security/trust-authority.js +324 -0
- package/dist/security/types.js +1 -0
- package/dist/security/workspace-identity.js +102 -0
- package/dist/services/automation-facade.js +59 -0
- package/dist/services/forge-facade.js +77 -0
- package/dist/services/hook-facade.js +240 -0
- package/dist/services/index.js +16 -0
- package/dist/services/library-facade.js +174 -0
- package/dist/services/mcp-facade.js +348 -0
- package/dist/services/memory-facade.js +126 -0
- package/dist/services/notes-facade.js +157 -0
- package/dist/services/plugin-facade.js +308 -0
- package/dist/services/research-facade.js +110 -0
- package/dist/services/task-board-facade.js +236 -0
- package/dist/services/workflow-catalog.js +246 -0
- package/dist/sessions/export-format.js +98 -0
- package/dist/sessions/metadata-store.js +160 -0
- package/dist/sessions/share.js +122 -0
- package/dist/sessions/transfer.js +16 -0
- package/dist/subcommands.js +62 -0
- package/dist/tui/agent-roster.js +36 -0
- package/dist/tui/agent-view.js +51 -0
- package/dist/tui/app.js +4098 -0
- package/dist/tui/approval.js +36 -0
- package/dist/tui/boot/boot-sequence.js +76 -0
- package/dist/tui/boot/cinematic.js +243 -0
- package/dist/tui/boot/desktop-logo.js +82 -0
- package/dist/tui/boot.js +3 -0
- package/dist/tui/busy-input.js +58 -0
- package/dist/tui/catalog-service.js +560 -0
- package/dist/tui/components/assistant-stream.js +1 -0
- package/dist/tui/components/command-menu.js +68 -0
- package/dist/tui/components/composer.js +219 -0
- package/dist/tui/components/diff.js +35 -0
- package/dist/tui/components/footer.js +48 -0
- package/dist/tui/components/header.js +6 -0
- package/dist/tui/components/markdown.js +305 -0
- package/dist/tui/components/status-indicator.js +38 -0
- package/dist/tui/components/terminal-shell.js +214 -0
- package/dist/tui/components/thinking-row.js +19 -0
- package/dist/tui/components/tool-row.js +97 -0
- package/dist/tui/components/transcript-virtualizer.js +165 -0
- package/dist/tui/components/transcript.js +43 -0
- package/dist/tui/descendant-approvals.js +104 -0
- package/dist/tui/diff-model.js +77 -0
- package/dist/tui/editor-history.js +21 -0
- package/dist/tui/editor.js +210 -0
- package/dist/tui/event-adapter.js +436 -0
- package/dist/tui/exit-output.js +58 -0
- package/dist/tui/external-editor.js +53 -0
- package/dist/tui/file-completion.js +89 -0
- package/dist/tui/focus-manager.js +5 -0
- package/dist/tui/highlight.js +30 -0
- package/dist/tui/input-router.js +18 -0
- package/dist/tui/interrupt.js +99 -0
- package/dist/tui/keybindings.js +194 -0
- package/dist/tui/keymap-resolver.js +91 -0
- package/dist/tui/launch-state.js +148 -0
- package/dist/tui/line-diff.js +57 -0
- package/dist/tui/live-activity.js +56 -0
- package/dist/tui/metrics.js +123 -0
- package/dist/tui/onboarding.js +36 -0
- package/dist/tui/overlays/agent-tree.js +43 -0
- package/dist/tui/overlays/approval-dialog.js +642 -0
- package/dist/tui/overlays/automation-center.js +51 -0
- package/dist/tui/overlays/checkpoint-picker.js +47 -0
- package/dist/tui/overlays/context-inspector.js +36 -0
- package/dist/tui/overlays/effort-line.js +110 -0
- package/dist/tui/overlays/forge-center.js +46 -0
- package/dist/tui/overlays/help-dialog.js +16 -0
- package/dist/tui/overlays/history-picker.js +37 -0
- package/dist/tui/overlays/hook-center.js +70 -0
- package/dist/tui/overlays/library-center.js +55 -0
- package/dist/tui/overlays/mcp-center.js +60 -0
- package/dist/tui/overlays/memory-center.js +63 -0
- package/dist/tui/overlays/model-picker.js +77 -0
- package/dist/tui/overlays/notes-center.js +53 -0
- package/dist/tui/overlays/overlay-host.js +8 -0
- package/dist/tui/overlays/plugin-center.js +76 -0
- package/dist/tui/overlays/provider-picker.js +171 -0
- package/dist/tui/overlays/queue-editor.js +32 -0
- package/dist/tui/overlays/research-center.js +59 -0
- package/dist/tui/overlays/scroll-window.js +234 -0
- package/dist/tui/overlays/session-picker.js +115 -0
- package/dist/tui/overlays/tasks-center.js +83 -0
- package/dist/tui/overlays/theme-picker.js +21 -0
- package/dist/tui/overlays/transcript-search.js +58 -0
- package/dist/tui/overlays/trust-center.js +29 -0
- package/dist/tui/overlays/workflow-center.js +46 -0
- package/dist/tui/project-file-index.js +214 -0
- package/dist/tui/project-references.js +85 -0
- package/dist/tui/project-trust-prompt.js +289 -0
- package/dist/tui/prompt-history-store.js +116 -0
- package/dist/tui/queue-store.js +110 -0
- package/dist/tui/regions/budget.js +59 -0
- package/dist/tui/regions/views.js +96 -0
- package/dist/tui/render-coordinator.js +148 -0
- package/dist/tui/render-scheduler.js +4 -0
- package/dist/tui/run.js +69 -0
- package/dist/tui/selection-list.js +29 -0
- package/dist/tui/session-controller.js +791 -0
- package/dist/tui/session-export.js +54 -0
- package/dist/tui/setup-wizard.js +46 -0
- package/dist/tui/shell-input.js +35 -0
- package/dist/tui/shell-layout.js +48 -0
- package/dist/tui/shell-model.js +98 -0
- package/dist/tui/slash-commands.js +82 -0
- package/dist/tui/state.js +151 -0
- package/dist/tui/status-bar.js +125 -0
- package/dist/tui/status-view.js +40 -0
- package/dist/tui/terminal-capabilities.js +9 -0
- package/dist/tui/terminal-session.js +11 -0
- package/dist/tui/text-width.js +66 -0
- package/dist/tui/theme-catalog.js +27 -0
- package/dist/tui/theme-store.js +23 -0
- package/dist/tui/theme.js +23 -0
- package/dist/tui/tool-display.js +135 -0
- package/dist/tui/tool-facts.js +1 -0
- package/dist/tui/tools/bash-renderer.js +32 -0
- package/dist/tui/tools/change.js +61 -0
- package/dist/tui/tools/edit-renderer.js +17 -0
- package/dist/tui/tools/generic-renderer.js +13 -0
- package/dist/tui/tools/list-renderer.js +14 -0
- package/dist/tui/tools/read-renderer.js +13 -0
- package/dist/tui/tools/registry.js +20 -0
- package/dist/tui/tools/row-format.js +187 -0
- package/dist/tui/tools/search-renderer.js +38 -0
- package/dist/tui/tools/shared.js +97 -0
- package/dist/tui/tools/write-renderer.js +15 -0
- package/dist/tui/transcript-model.js +441 -0
- package/dist/tui/ui-preferences.js +79 -0
- package/dist/tui/usage-view.js +77 -0
- package/dist/tui/vim-mode.js +99 -0
- package/dist/update/check.js +15 -0
- package/dist/update/npm.js +51 -0
- package/dist/update/run.js +129 -0
- package/dist/version.js +2 -0
- package/dist/workspace/checkpoint-store.js +210 -0
- package/dist/workspace/checkpoint.js +413 -0
- package/dist/workspace/restore.js +232 -0
- package/package.json +64 -5
- package/vendor/context-engine/package.json +11 -0
- package/vendor/context-engine/src/compaction-planner.mjs +57 -0
- package/vendor/context-engine/src/contracts.mjs +48 -0
- package/vendor/context-engine/src/engine.mjs +445 -0
- package/vendor/context-engine/src/node/context-export.mjs +164 -0
- package/vendor/context-engine/src/node/legacy-import.mjs +92 -0
- package/vendor/context-engine/src/node/migrations/001-context.sql +126 -0
- package/vendor/context-engine/src/node/sqlite-store.mjs +85 -0
- package/vendor/context-engine/src/node/sqlite-worker.mjs +559 -0
- package/vendor/context-engine/src/profiles.mjs +10 -0
- package/vendor/context-engine/src/retrieval.mjs +104 -0
- package/vendor/context-engine/src/summary.mjs +97 -0
- package/vendor/context-engine/src/usage.mjs +34 -0
- package/vendor/harness-ui/package.json +38 -0
- package/vendor/harness-ui/src/acp-agent.mjs +350 -0
- package/vendor/harness-ui/src/agent-service.mjs +2188 -0
- package/vendor/harness-ui/src/agui-events.mjs +452 -0
- package/vendor/harness-ui/src/ambiente-solo-server.mjs +121 -0
- package/vendor/harness-ui/src/artifact-store.mjs +39 -0
- package/vendor/harness-ui/src/assistenza.mjs +123 -0
- package/vendor/harness-ui/src/automation-scheduler.mjs +69 -0
- package/vendor/harness-ui/src/automation-store.mjs +145 -0
- package/vendor/harness-ui/src/browser-annota.mjs +639 -0
- package/vendor/harness-ui/src/browser-frame.mjs +211 -0
- package/vendor/harness-ui/src/browser-proxy-universale.mjs +519 -0
- package/vendor/harness-ui/src/browser-proxy.mjs +87 -0
- package/vendor/harness-ui/src/browser-sessione-viva.mjs +329 -0
- package/vendor/harness-ui/src/browser-stream.mjs +445 -0
- package/vendor/harness-ui/src/browser-vivo.mjs +694 -0
- package/vendor/harness-ui/src/chat-image-attachments.mjs +72 -0
- package/vendor/harness-ui/src/config.mjs +697 -0
- package/vendor/harness-ui/src/contesto-del-progetto.mjs +385 -0
- package/vendor/harness-ui/src/context-asset-adapter.mjs +72 -0
- package/vendor/harness-ui/src/context-desktop-service.mjs +253 -0
- package/vendor/harness-ui/src/context-embedding-runtime.mjs +252 -0
- package/vendor/harness-ui/src/context-inference-scheduler.mjs +81 -0
- package/vendor/harness-ui/src/context-native-compaction.mjs +75 -0
- package/vendor/harness-ui/src/context-provider-adapter.mjs +141 -0
- package/vendor/harness-ui/src/context-runtime.mjs +118 -0
- package/vendor/harness-ui/src/context-token-counters.mjs +184 -0
- package/vendor/harness-ui/src/context-tool-catalog.mjs +86 -0
- package/vendor/harness-ui/src/context-tool-output.mjs +72 -0
- package/vendor/harness-ui/src/costo-elenco.mjs +252 -0
- package/vendor/harness-ui/src/custom-task.mjs +171 -0
- package/vendor/harness-ui/src/doctor.mjs +142 -0
- package/vendor/harness-ui/src/document-filename.mjs +97 -0
- package/vendor/harness-ui/src/document-generator.mjs +493 -0
- package/vendor/harness-ui/src/document-report.mjs +331 -0
- package/vendor/harness-ui/src/duckduckgo-search.mjs +155 -0
- package/vendor/harness-ui/src/elenco-profondo.mjs +337 -0
- package/vendor/harness-ui/src/favicon-proxy.mjs +113 -0
- package/vendor/harness-ui/src/forge-contract.mjs +221 -0
- package/vendor/harness-ui/src/frequent-dirs.mjs +134 -0
- package/vendor/harness-ui/src/generated-image-store.mjs +147 -0
- package/vendor/harness-ui/src/generation-idle.mjs +332 -0
- package/vendor/harness-ui/src/gguf-header.mjs +207 -0
- package/vendor/harness-ui/src/git-service.mjs +626 -0
- package/vendor/harness-ui/src/gitignore-elenco.mjs +604 -0
- package/vendor/harness-ui/src/harness-receipt-keypair.mjs +207 -0
- package/vendor/harness-ui/src/hf-direct-transfer.mjs +170 -0
- package/vendor/harness-ui/src/hf-hub-client.mjs +106 -0
- package/vendor/harness-ui/src/hf-image-proxy.mjs +105 -0
- package/vendor/harness-ui/src/hf-model-transfer.mjs +245 -0
- package/vendor/harness-ui/src/hook-registry.mjs +186 -0
- package/vendor/harness-ui/src/http-app.mjs +6259 -0
- package/vendor/harness-ui/src/http-lifecycle.mjs +132 -0
- package/vendor/harness-ui/src/id-archivio.mjs +27 -0
- package/vendor/harness-ui/src/image-generator.mjs +143 -0
- package/vendor/harness-ui/src/istruzioni-di-progetto.mjs +234 -0
- package/vendor/harness-ui/src/kernel/dist/kernelPerIlBanco.js +518 -0
- package/vendor/harness-ui/src/kernel/talosHarness.mjs +10437 -0
- package/vendor/harness-ui/src/library-policy-store.mjs +175 -0
- package/vendor/harness-ui/src/library-store.mjs +652 -0
- package/vendor/harness-ui/src/llama-server-supervisor.mjs +629 -0
- package/vendor/harness-ui/src/local-model-store.mjs +339 -0
- package/vendor/harness-ui/src/local-runtime-contract.mjs +66 -0
- package/vendor/harness-ui/src/local-runtime-events.mjs +44 -0
- package/vendor/harness-ui/src/local-runtime-llama-server.mjs +244 -0
- package/vendor/harness-ui/src/local-runtime-probe.mjs +401 -0
- package/vendor/harness-ui/src/machine-capacity.mjs +66 -0
- package/vendor/harness-ui/src/mappa-cartelle.mjs +491 -0
- package/vendor/harness-ui/src/mcp-client.mjs +98 -0
- package/vendor/harness-ui/src/mcp-registry.mjs +157 -0
- package/vendor/harness-ui/src/mcp-session.mjs +177 -0
- package/vendor/harness-ui/src/memory-store.mjs +227 -0
- package/vendor/harness-ui/src/model-catalog-models-dev.mjs +276 -0
- package/vendor/harness-ui/src/model-catalog.mjs +129 -0
- package/vendor/harness-ui/src/model-destination.mjs +189 -0
- package/vendor/harness-ui/src/modifica-ancorata.mjs +177 -0
- package/vendor/harness-ui/src/native-provider-adapter.mjs +205 -0
- package/vendor/harness-ui/src/notes-store.mjs +250 -0
- package/vendor/harness-ui/src/openai-compatible-runtime.mjs +428 -0
- package/vendor/harness-ui/src/openrouter-oauth.mjs +339 -0
- package/vendor/harness-ui/src/path-policy.mjs +442 -0
- package/vendor/harness-ui/src/plugin-registry.mjs +780 -0
- package/vendor/harness-ui/src/plugin-session.mjs +180 -0
- package/vendor/harness-ui/src/process-policy.mjs +345 -0
- package/vendor/harness-ui/src/prompt-enhancer-provider.mjs +94 -0
- package/vendor/harness-ui/src/provider-auth-cloud.mjs +95 -0
- package/vendor/harness-ui/src/provider-credential-store.mjs +541 -0
- package/vendor/harness-ui/src/provider-probe.mjs +582 -0
- package/vendor/harness-ui/src/provider-registry.mjs +1633 -0
- package/vendor/harness-ui/src/pty-terminal.mjs +312 -0
- package/vendor/harness-ui/src/public-problem.mjs +109 -0
- package/vendor/harness-ui/src/research/card.mjs +235 -0
- package/vendor/harness-ui/src/research/citations.mjs +142 -0
- package/vendor/harness-ui/src/research/collector.mjs +275 -0
- package/vendor/harness-ui/src/research/deposito-a-pezzi.mjs +139 -0
- package/vendor/harness-ui/src/research/dossier.mjs +114 -0
- package/vendor/harness-ui/src/research/esportazioni.mjs +560 -0
- package/vendor/harness-ui/src/research/fetch-cache.mjs +465 -0
- package/vendor/harness-ui/src/research/fidelity.mjs +122 -0
- package/vendor/harness-ui/src/research/independence.mjs +159 -0
- package/vendor/harness-ui/src/research/ledger.mjs +166 -0
- package/vendor/harness-ui/src/research/markdown-server.mjs +565 -0
- package/vendor/harness-ui/src/research/narration.mjs +181 -0
- package/vendor/harness-ui/src/research/open-cards.mjs +131 -0
- package/vendor/harness-ui/src/research/opposing.mjs +305 -0
- package/vendor/harness-ui/src/research/outline.mjs +111 -0
- package/vendor/harness-ui/src/research/page-budget.mjs +209 -0
- package/vendor/harness-ui/src/research/pdf.mjs +291 -0
- package/vendor/harness-ui/src/research/plan.mjs +301 -0
- package/vendor/harness-ui/src/research/raccolta-viva.mjs +452 -0
- package/vendor/harness-ui/src/research/recheck-document.mjs +69 -0
- package/vendor/harness-ui/src/research/recheck-history.mjs +192 -0
- package/vendor/harness-ui/src/research/recheck.mjs +194 -0
- package/vendor/harness-ui/src/research/report.mjs +203 -0
- package/vendor/harness-ui/src/research/run.mjs +527 -0
- package/vendor/harness-ui/src/research/synthesis.mjs +318 -0
- package/vendor/harness-ui/src/research/verification.mjs +572 -0
- package/vendor/harness-ui/src/research-orchestrator.mjs +2679 -0
- package/vendor/harness-ui/src/research-store.mjs +1133 -0
- package/vendor/harness-ui/src/runtime-build-manifest.mjs +26 -0
- package/vendor/harness-ui/src/runtime-contract.mjs +59 -0
- package/vendor/harness-ui/src/runtime-owner-adapter.mjs +1348 -0
- package/vendor/harness-ui/src/runtime-owner-contract.mjs +32 -0
- package/vendor/harness-ui/src/scheda-di-lavoro.mjs +249 -0
- package/vendor/harness-ui/src/search-source-store.mjs +172 -0
- package/vendor/harness-ui/src/session-registry.mjs +6095 -0
- package/vendor/harness-ui/src/session-store.mjs +220 -0
- package/vendor/harness-ui/src/sessione-pronta.mjs +73 -0
- package/vendor/harness-ui/src/setup-stato.mjs +31 -0
- package/vendor/harness-ui/src/sezioni-istruzioni.mjs +204 -0
- package/vendor/harness-ui/src/skill-registry.mjs +120 -0
- package/vendor/harness-ui/src/sse-replay-coalescente.mjs +0 -0
- package/vendor/harness-ui/src/static-files.mjs +96 -0
- package/vendor/harness-ui/src/stream-partition.mjs +123 -0
- package/vendor/harness-ui/src/subagent-orchestrator.mjs +453 -0
- package/vendor/harness-ui/src/task-catalog.mjs +65 -0
- package/vendor/harness-ui/src/tasks-store.mjs +220 -0
- package/vendor/harness-ui/src/terminal-registry.mjs +312 -0
- package/vendor/harness-ui/src/terminal-ws.mjs +170 -0
- package/vendor/harness-ui/src/tool-forge-store.mjs +299 -0
- package/vendor/harness-ui/src/tool-schema-normalize.mjs +100 -0
- package/vendor/harness-ui/src/usage-cache.mjs +315 -0
- package/vendor/harness-ui/src/workspace-browser.mjs +213 -0
- package/vendor/harness-ui/src/workspace-context.mjs +124 -0
- package/vendor/harness-ui/src/workspace-disk.mjs +62 -0
- package/vendor/harness-ui/src/workspace-files.mjs +589 -0
- package/vendor/harness-ui/src/workspace-info.mjs +189 -0
- package/vendor/harness-ui/src/workspace-launch-store.mjs +150 -0
- package/vendor/harness-ui/src/workspace-tree.mjs +67 -0
- package/vendor/harness-ui/src/workspace-watcher.mjs +161 -0
- package/vendor/manifest.json +170 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { t } from "../i18n/index.js";
|
|
2
|
+
import { providerLabel } from "../provider/missing-key.js";
|
|
3
|
+
export { redactObject } from "./redact.js";
|
|
4
|
+
export async function runDoctor(d) {
|
|
5
|
+
const checks = [];
|
|
6
|
+
async function c(id, fn) {
|
|
7
|
+
try {
|
|
8
|
+
const ok = await fn();
|
|
9
|
+
checks.push({ id, ok });
|
|
10
|
+
return ok;
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
checks.push({ id, ok: false, detail: e instanceof Error ? e.message : String(e) });
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
await c('config-path', () => d.fsAccess(d.paths.configRoot));
|
|
18
|
+
await c('data-path', () => d.fsAccess(d.paths.dataRoot));
|
|
19
|
+
await c('cache-path', () => d.fsAccess(d.paths.cacheRoot));
|
|
20
|
+
await c('git', d.gitProbe);
|
|
21
|
+
await c('keyring', d.keyringProbe);
|
|
22
|
+
const probe = async (name, fn) => {
|
|
23
|
+
if (typeof fn !== 'function')
|
|
24
|
+
return { state: 'unknown', detail: name + ' probe unavailable' };
|
|
25
|
+
try {
|
|
26
|
+
return await fn();
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return { state: 'unavailable', detail: error instanceof Error ? error.message : String(error) };
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const sections = {
|
|
33
|
+
terminal: await probe('terminal', d.terminalProbe),
|
|
34
|
+
runtime: await probe('runtime', d.runtimeProbe),
|
|
35
|
+
trust: await probe('trust', d.trustProbe),
|
|
36
|
+
providers: await probe('providers', typeof d.providerProbe === 'function' ? () => d.providerProbe({ active: Boolean(d.profile) }) : undefined),
|
|
37
|
+
broker: await probe('broker', d.brokerProbe),
|
|
38
|
+
context: await probe('context', d.contextProbe),
|
|
39
|
+
sessions: await probe('sessions', d.sessionProbe),
|
|
40
|
+
update: await probe('update', d.updateProbe),
|
|
41
|
+
/* R2 (gate E13): the active credential store, read LAST so that `nativeModuleLoaded` covers every probe above (the providers
|
|
42
|
+
probe composes a runtime, which opens the store). Wording only: `ok` still comes from the checks (Q-R2-9, R4). */
|
|
43
|
+
credentials: await probe('credentials', d.credentialsProbe),
|
|
44
|
+
/* R5b: models.dev on or off, and why (catalog.modelsDev, TALOS_MODELS_DEV). */
|
|
45
|
+
catalog: await probe('catalog', d.catalogProbe),
|
|
46
|
+
};
|
|
47
|
+
const performance = Boolean(d.profile) && typeof d.performanceProbe === 'function' ? await probe('performance', d.performanceProbe) : null;
|
|
48
|
+
return { schema: 'talos.cli.doctor.v1', ok: checks.every(x => x.ok), checks, sections, performance, profiled: Boolean(d.profile) };
|
|
49
|
+
}
|
|
50
|
+
export async function turnReadiness({ catalog, control, model }) {
|
|
51
|
+
const unknown = { ready: false, reasons: [{ code: 'RUNTIME_NOT_AVAILABLE', message: t('firstrun.doctor.unknown') }] };
|
|
52
|
+
if (typeof catalog?.readiness !== 'function')
|
|
53
|
+
return unknown;
|
|
54
|
+
let decision;
|
|
55
|
+
try {
|
|
56
|
+
decision = await catalog.readiness(model ?? '');
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return unknown;
|
|
60
|
+
}
|
|
61
|
+
if (!decision || typeof decision.ready !== 'boolean')
|
|
62
|
+
return unknown;
|
|
63
|
+
if (!decision.ready) {
|
|
64
|
+
const code = String(decision.code ?? 'RUNTIME_NOT_AVAILABLE');
|
|
65
|
+
const message = code === 'PROVIDER_NOT_CHOSEN' ? t('firstrun.doctor.noProvider')
|
|
66
|
+
: code === 'MODEL_NOT_CHOSEN' && decision.provider ? t('firstrun.doctor.noModel', { provider: providerLabel(String(decision.provider)) })
|
|
67
|
+
: String(decision.message ?? t('firstrun.doctor.unknown'));
|
|
68
|
+
return { ready: false, reasons: [{ code, message }] };
|
|
69
|
+
}
|
|
70
|
+
const provider = String(decision.provider ?? '');
|
|
71
|
+
let profile = null;
|
|
72
|
+
try {
|
|
73
|
+
profile = typeof control?.get === 'function' ? control.get(provider) : null;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
profile = null;
|
|
77
|
+
}
|
|
78
|
+
if (profile?.local === true && profile?.auth?.required !== true) {
|
|
79
|
+
let observed = null;
|
|
80
|
+
try {
|
|
81
|
+
observed = typeof control?.probe === 'function' ? await control.probe(provider) : null;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
observed = null;
|
|
85
|
+
}
|
|
86
|
+
if (observed?.lastHealth?.state !== 'available') {
|
|
87
|
+
const address = typeof profile?.endpoint?.host === 'string' && profile.endpoint.host ? profile.endpoint.host : null;
|
|
88
|
+
return { ready: false, reasons: [{ code: 'PROVIDER_UNREACHABLE', message: t(address ? 'firstrun.doctor.localDown' : 'firstrun.doctor.localDownNoAddress', { provider: String(profile?.label ?? provider), address: address ?? '' }) }] };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { ready: true, reasons: [] };
|
|
92
|
+
}
|
|
93
|
+
/** The verdict a person reads first: `ready` only when the checks pass and a turn could run; otherwise the first reason. */
|
|
94
|
+
export function doctorVerdict({ ok, checks, turn }) {
|
|
95
|
+
const failed = checks.find(check => !check.ok);
|
|
96
|
+
const reasons = [...turn.reasons];
|
|
97
|
+
const first = turn.reasons[0]?.message ?? (failed ? t('firstrun.doctor.checkFailed', { check: failed.id }) : null);
|
|
98
|
+
const status = ok && turn.ready ? 'ready' : 'needs attention';
|
|
99
|
+
return {
|
|
100
|
+
ready: turn.ready, status, reasons,
|
|
101
|
+
headline: status === 'ready' ? t('firstrun.doctor.headlineReady') : t('firstrun.doctor.headlineAttention', { reason: first ?? t('firstrun.doctor.unknown') }),
|
|
102
|
+
exitCode: !ok ? 70 : !turn.ready ? 1 : 0,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const SECRET_KEY = /^(?:.*(?:api[-_]?key|authorization|password|secret|token).*)$/iu;
|
|
2
|
+
function marker(value) { return `[REDACTED:${Buffer.byteLength(value, 'utf8')}]`; }
|
|
3
|
+
function escapeRe(value) { return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); }
|
|
4
|
+
function redactAssignments(input) {
|
|
5
|
+
let out = input;
|
|
6
|
+
out = out.replace(/\b(authorization)\b(\s*:\s*)([^\r\n]+)/giu, (_m, key, sep, value) => `${key}${sep}${marker(String(value).trim())}`);
|
|
7
|
+
out = out.replace(/\b(x-api-key|api[-_]?key|token|secret|password)\b(\s*[:=]\s*)("[^"]*"|'[^']*'|[^\s;\r\n,]+)/giu, (_m, key, sep, raw) => { const text = String(raw); const quoted = (text.startsWith('"') && text.endsWith('"')) || (text.startsWith("'") && text.endsWith("'")); const value = quoted ? text.slice(1, -1) : text; return `${key}${sep}${quoted ? text[0] : ''}${marker(value)}${quoted ? text.at(-1) : ''}`; });
|
|
8
|
+
return out;
|
|
9
|
+
}
|
|
10
|
+
/*
|
|
11
|
+
* Gate E12 (owner yes 2026-09-24, v1 output included): secret VALUES recognised by their vendor prefix, additive to the name
|
|
12
|
+
* rules above and to the exact values. Every pattern has a token boundary on both sides (Hermes agent/redact.py:578,
|
|
13
|
+
* 2026-09-23), a length floor and an upper bound on every quantifier (Qwen secret-scanner ReDoS note, test 2026-09-03).
|
|
14
|
+
* Lists: gate §6.1 (Hermes redact.py:148-207, Codex doctor/output.rs:915-945 2026-09-22, GitLab token prefixes doc
|
|
15
|
+
* 2026-09-23). `ASIA` is here because Hermes, the Codex sanitizer and Gemini miss it; `sk-` takes `-`/`_` so `sk-proj-`
|
|
16
|
+
* and `sk-ant-api03-` match (the `[A-Za-z0-9]{20,}` shape of Codex/Qwen misses them), and needs one digit so a
|
|
17
|
+
* kebab-case name such as `sk-learn-compatible-…` stays readable. The mask is the full `[REDACTED:<bytes>]` (Q-R2-11).
|
|
18
|
+
*/
|
|
19
|
+
const T = 'A-Za-z0-9_\\-'; // token characters: a match may not be glued to more of them on either side
|
|
20
|
+
const bounded = (source, flags = 'gu') => new RegExp(`(?<![${T}])(?:${source})(?![${T}])`, flags);
|
|
21
|
+
const DASH5 = '-{5}';
|
|
22
|
+
const PRIVATE_KEY_LABEL = '[A-Z0-9 ]{0,40}PRIVATE KEY(?: BLOCK)?';
|
|
23
|
+
const SECRET_VALUE_PATTERNS = [
|
|
24
|
+
// PEM first: a whole block, then a block cut off before its END line (its base64 body up to the first non-body line).
|
|
25
|
+
new RegExp(`${DASH5}BEGIN ${PRIVATE_KEY_LABEL}${DASH5}(?:(?!${DASH5})[\\s\\S]){0,16384}${DASH5}END ${PRIVATE_KEY_LABEL}${DASH5}`, 'gu'),
|
|
26
|
+
new RegExp(`${DASH5}BEGIN ${PRIVATE_KEY_LABEL}${DASH5}(?:\\r?\\n(?:[A-Za-z0-9+/=]{1,128}|[A-Za-z][A-Za-z-]{0,31}: [^\\r\\n]{0,128})){0,1024}`, 'gu'),
|
|
27
|
+
bounded('eyJ[A-Za-z0-9_-]{8,4096}\\.eyJ[A-Za-z0-9_-]{8,8192}\\.[A-Za-z0-9_-]{10,4096}'), // JWT: three base64url segments
|
|
28
|
+
bounded('sk-(?=[A-Za-z0-9_-]{0,255}\\d)[A-Za-z0-9_-]{20,256}'), // OpenAI (proj/svcacct/admin), Anthropic (ant-api03/admin01), OpenRouter
|
|
29
|
+
bounded('gh[pousr]_[A-Za-z0-9]{36,255}|github_pat_[A-Za-z0-9_]{30,255}'),
|
|
30
|
+
bounded('gl(?:pat|oas|dt|rtr|rt|cbt|ptt|ft|imt|agent|wt|soat|ffct)-[A-Za-z0-9_-]{20,255}'),
|
|
31
|
+
bounded('xox[abprs]-[A-Za-z0-9-]{10,255}|xapp-[A-Za-z0-9-]{10,255}'),
|
|
32
|
+
bounded('AIza[A-Za-z0-9_-]{35,64}'),
|
|
33
|
+
bounded('(?:AKIA|ASIA)[A-Z0-9]{16}'),
|
|
34
|
+
bounded('hf_[A-Za-z0-9]{30,255}|npm_[A-Za-z0-9]{36,255}'),
|
|
35
|
+
];
|
|
36
|
+
// `Bearer <token>`: only the credential is masked, the scheme stays readable; 20+ token68 characters with a digit, so
|
|
37
|
+
// "the bearer of bad news" and "Bearer internationalization" pass (Hermes redact.py:1139, Codex sanitizer tests).
|
|
38
|
+
const BEARER = /(?<![A-Za-z0-9])(bearer[ \t]+)(?=[A-Za-z0-9._~+/-]{0,4095}\d)([A-Za-z0-9._~+/-]{20,4096}=*)(?![A-Za-z0-9._~+/=-])/giu;
|
|
39
|
+
function redactSecretValues(input) {
|
|
40
|
+
let out = input;
|
|
41
|
+
for (const pattern of SECRET_VALUE_PATTERNS)
|
|
42
|
+
out = out.replace(pattern, match => marker(match));
|
|
43
|
+
return out.replace(BEARER, (_m, scheme, token) => `${scheme}${marker(token)}`);
|
|
44
|
+
}
|
|
45
|
+
export function createRedactor(secrets) { const values = [...new Set([...secrets].filter(x => typeof x === 'string' && x.length > 0))].sort((a, b) => b.length - a.length); return { text(input) { let out = redactSecretValues(redactAssignments(String(input))); for (const secret of values)
|
|
46
|
+
out = out.replace(new RegExp(escapeRe(secret), 'gu'), marker(secret)); return out; }, value(input) { return redactObject(input, values); } }; }
|
|
47
|
+
export function redactObject(value, secrets = []) { const r = createRedactor(secrets); function visit(v) { if (Array.isArray(v))
|
|
48
|
+
return v.map(visit); if (v && typeof v === 'object') {
|
|
49
|
+
const out = {};
|
|
50
|
+
for (const [k, x] of Object.entries(v)) {
|
|
51
|
+
if (SECRET_KEY.test(k)) {
|
|
52
|
+
out[k] = typeof x === 'string' ? marker(x) : '[REDACTED]';
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
out[k] = visit(x);
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
} if (typeof v === 'string')
|
|
59
|
+
return r.text(v); return v; } return visit(value); }
|
|
60
|
+
export function secretValuesFromEnvironment(env) { const rows = []; for (const [k, v] of Object.entries(env))
|
|
61
|
+
if (v && SECRET_KEY.test(k))
|
|
62
|
+
rows.push(v); return rows; }
|
|
63
|
+
export function createPathPseudonymizer(paths) {
|
|
64
|
+
const canonical = [...new Set([...paths].filter((value) => typeof value === 'string' && value.length > 1))].sort((a, b) => b.length - a.length);
|
|
65
|
+
const rows = canonical.flatMap((value, index) => {
|
|
66
|
+
const label = '[PATH:' + String(index + 1) + ']';
|
|
67
|
+
const variants = [value, value.replace(/\\/gu, '/'), value.replace(/\//gu, '\\')];
|
|
68
|
+
return [...new Set(variants.filter(v => v.length > 1))].map(pattern => ({ pattern, label }));
|
|
69
|
+
}).sort((a, b) => b.pattern.length - a.pattern.length);
|
|
70
|
+
const text = (input) => { let out = String(input); for (const row of rows)
|
|
71
|
+
out = out.replace(new RegExp(escapeRe(row.pattern), process.platform === 'win32' ? 'giu' : 'gu'), () => row.label); return out; };
|
|
72
|
+
const value = (input) => {
|
|
73
|
+
if (Array.isArray(input))
|
|
74
|
+
return input.map(value);
|
|
75
|
+
if (input && typeof input === 'object')
|
|
76
|
+
return Object.fromEntries(Object.entries(input).map(([k, v]) => [k, value(v)]));
|
|
77
|
+
return typeof input === 'string' ? text(input) : input;
|
|
78
|
+
};
|
|
79
|
+
return { text, value };
|
|
80
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
function crcTable() { const t = new Uint32Array(256); for (let n = 0; n < 256; n++) {
|
|
3
|
+
let c = n;
|
|
4
|
+
for (let k = 0; k < 8; k++)
|
|
5
|
+
c = (c & 1) ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
6
|
+
t[n] = c >>> 0;
|
|
7
|
+
} return t; }
|
|
8
|
+
const TABLE = crcTable();
|
|
9
|
+
export function crc32(buf) { let c = 0xffffffff; for (const b of buf)
|
|
10
|
+
c = TABLE[(c ^ b) & 0xff] ^ (c >>> 8); return (c ^ 0xffffffff) >>> 0; }
|
|
11
|
+
function dosDateTime(d = new Date()) { const year = Math.max(1980, d.getFullYear()); const time = (d.getHours() << 11) | (d.getMinutes() << 5) | (d.getSeconds() >> 1); const date = ((year - 1980) << 9) | ((d.getMonth() + 1) << 5) | d.getDate(); return { time, date }; }
|
|
12
|
+
export function createStoredZip(entries) { const locals = []; const centrals = []; let offset = 0; const dt = dosDateTime(); for (const e of entries) {
|
|
13
|
+
const name = Buffer.from(e.name.replace(/\\/gu, '/'), 'utf8');
|
|
14
|
+
if (e.name.startsWith('/') || e.name.split(/[\\/]/u).includes('..'))
|
|
15
|
+
throw new Error('ZIP_ENTRY_INVALID');
|
|
16
|
+
const data = Buffer.isBuffer(e.data) ? e.data : Buffer.from(e.data, 'utf8');
|
|
17
|
+
const crc = crc32(data);
|
|
18
|
+
const local = Buffer.alloc(30);
|
|
19
|
+
local.writeUInt32LE(0x04034b50, 0);
|
|
20
|
+
local.writeUInt16LE(20, 4);
|
|
21
|
+
local.writeUInt16LE(0x800, 6);
|
|
22
|
+
local.writeUInt16LE(0, 8);
|
|
23
|
+
local.writeUInt16LE(dt.time, 10);
|
|
24
|
+
local.writeUInt16LE(dt.date, 12);
|
|
25
|
+
local.writeUInt32LE(crc, 14);
|
|
26
|
+
local.writeUInt32LE(data.length, 18);
|
|
27
|
+
local.writeUInt32LE(data.length, 22);
|
|
28
|
+
local.writeUInt16LE(name.length, 26);
|
|
29
|
+
local.writeUInt16LE(0, 28);
|
|
30
|
+
locals.push(local, name, data);
|
|
31
|
+
const central = Buffer.alloc(46);
|
|
32
|
+
central.writeUInt32LE(0x02014b50, 0);
|
|
33
|
+
central.writeUInt16LE(20, 4);
|
|
34
|
+
central.writeUInt16LE(20, 6);
|
|
35
|
+
central.writeUInt16LE(0x800, 8);
|
|
36
|
+
central.writeUInt16LE(0, 10);
|
|
37
|
+
central.writeUInt16LE(dt.time, 12);
|
|
38
|
+
central.writeUInt16LE(dt.date, 14);
|
|
39
|
+
central.writeUInt32LE(crc, 16);
|
|
40
|
+
central.writeUInt32LE(data.length, 20);
|
|
41
|
+
central.writeUInt32LE(data.length, 24);
|
|
42
|
+
central.writeUInt16LE(name.length, 28);
|
|
43
|
+
central.writeUInt16LE(0, 30);
|
|
44
|
+
central.writeUInt16LE(0, 32);
|
|
45
|
+
central.writeUInt16LE(0, 34);
|
|
46
|
+
central.writeUInt16LE(0, 36);
|
|
47
|
+
central.writeUInt32LE(0, 38);
|
|
48
|
+
central.writeUInt32LE(offset, 42);
|
|
49
|
+
centrals.push(central, name);
|
|
50
|
+
offset += local.length + name.length + data.length;
|
|
51
|
+
} const centralBuf = Buffer.concat(centrals); const end = Buffer.alloc(22); end.writeUInt32LE(0x06054b50, 0); end.writeUInt16LE(0, 4); end.writeUInt16LE(0, 6); end.writeUInt16LE(entries.length, 8); end.writeUInt16LE(entries.length, 10); end.writeUInt32LE(centralBuf.length, 12); end.writeUInt32LE(offset, 16); end.writeUInt16LE(0, 20); return Buffer.concat([...locals, centralBuf, end]); }
|
|
52
|
+
export async function writeStoredZip(file, entries) { await writeFile(file, createStoredZip(entries), { mode: 0o600 }); }
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { redactObject, secretValuesFromEnvironment } from "./diagnostics/redact.js";
|
|
3
|
+
import { describeError } from "./i18n/error-view.js";
|
|
4
|
+
import { t } from "./i18n/index.js";
|
|
5
|
+
function serializeCause(cause) {
|
|
6
|
+
if (cause instanceof Error)
|
|
7
|
+
return { name: cause.name, message: cause.message, ...(typeof cause.code === 'string' ? { code: cause.code } : {}) };
|
|
8
|
+
if (cause === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
return { name: 'Error', message: String(cause) };
|
|
11
|
+
}
|
|
12
|
+
export class TalosError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
component;
|
|
15
|
+
retryable;
|
|
16
|
+
hint;
|
|
17
|
+
docs;
|
|
18
|
+
traceId;
|
|
19
|
+
constructor(fields, cause) {
|
|
20
|
+
super(fields.code, { cause });
|
|
21
|
+
this.name = 'TalosError';
|
|
22
|
+
this.code = fields.code;
|
|
23
|
+
this.component = fields.component;
|
|
24
|
+
this.retryable = fields.retryable;
|
|
25
|
+
this.traceId = fields.traceId;
|
|
26
|
+
if (fields.hint !== undefined)
|
|
27
|
+
this.hint = fields.hint;
|
|
28
|
+
if (fields.docs !== undefined)
|
|
29
|
+
this.docs = fields.docs;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const CODE_TOKEN = /^(?:([A-Z][A-Z0-9_]*)$|([A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+):)/u;
|
|
33
|
+
function isCliUsageMessage(message) {
|
|
34
|
+
return /^(?:Unsupported\b|Invalid\b|Unknown option:)/u.test(message)
|
|
35
|
+
|| /(?:must be a positive integer|mutually exclusive)$/u.test(message)
|
|
36
|
+
|| message === 'Subcommand required'
|
|
37
|
+
|| message === 'A prompt is required for headless mode';
|
|
38
|
+
}
|
|
39
|
+
/** A stable code is assigned before exit-code classification. Free-form prose stays INTERNAL_ERROR;
|
|
40
|
+
* CLI usage prose receives CLI_USAGE_ERROR so the envelope and process exit can no longer disagree. */
|
|
41
|
+
export function codeForError(error) {
|
|
42
|
+
const declared = error?.code;
|
|
43
|
+
if (typeof declared === 'string' && declared.length > 0)
|
|
44
|
+
return declared;
|
|
45
|
+
const message = error instanceof Error ? error.message : typeof error?.message === 'string' ? error.message : '';
|
|
46
|
+
const token = CODE_TOKEN.exec(message);
|
|
47
|
+
if (token?.[1] || token?.[2])
|
|
48
|
+
return token[1] ?? token[2];
|
|
49
|
+
if (isCliUsageMessage(message))
|
|
50
|
+
return 'CLI_USAGE_ERROR';
|
|
51
|
+
return 'INTERNAL_ERROR';
|
|
52
|
+
}
|
|
53
|
+
function stringField(record, key) { const value = record?.[key]; return typeof value === 'string' && value.length > 0 ? value : undefined; }
|
|
54
|
+
export function toTalosErrorEnvelope(error, fallback = {}) {
|
|
55
|
+
if (error instanceof TalosError) {
|
|
56
|
+
const cause = serializeCause(error.cause);
|
|
57
|
+
return { code: error.code, component: error.component, retryable: error.retryable, ...(cause ? { cause } : {}), ...(error.hint !== undefined ? { hint: error.hint } : {}), ...(error.docs !== undefined ? { docs: error.docs } : {}), traceId: error.traceId };
|
|
58
|
+
}
|
|
59
|
+
const record = error && typeof error === 'object' ? error : null;
|
|
60
|
+
const cause = error instanceof Error ? serializeCause(error) : (record?.cause !== undefined ? serializeCause(record.cause) : undefined);
|
|
61
|
+
const component = stringField(record, 'component') ?? fallback.component ?? 'cli';
|
|
62
|
+
const retryable = typeof record?.retryable === 'boolean' ? record.retryable : fallback.retryable ?? false;
|
|
63
|
+
const hint = stringField(record, 'hint');
|
|
64
|
+
const docs = stringField(record, 'docs');
|
|
65
|
+
const traceId = stringField(record, 'traceId') ?? fallback.traceId ?? 'untraced';
|
|
66
|
+
return { code: codeForError(error), component, retryable, ...(cause ? { cause } : {}), ...(hint ? { hint } : {}), ...(docs ? { docs } : {}), traceId };
|
|
67
|
+
}
|
|
68
|
+
export function exitCodeForEnvelope(envelope) {
|
|
69
|
+
const code = String(envelope.code ?? '');
|
|
70
|
+
if (code === 'INTERRUPTED' || code === 'CANCELLED' || code === 'ABORT_ERR')
|
|
71
|
+
return 130;
|
|
72
|
+
if (/PERMISSION|APPROVAL|DENIED|SANDBOX|PATH_NOT_ALLOWED|PLAN_MODE_READ_ONLY/u.test(code))
|
|
73
|
+
return 10;
|
|
74
|
+
if (/KEY|AUTH|CREDENTIAL/u.test(code))
|
|
75
|
+
return 11;
|
|
76
|
+
if (/PROVIDER|MODEL_DESTINATION|OPENROUTER|OLLAMA|GEMINI|ANTHROPIC|OPENAI/u.test(code))
|
|
77
|
+
return 12;
|
|
78
|
+
if (/MCP|HOOK|PLUGIN|EXTENSION|TOOL/u.test(code))
|
|
79
|
+
return 13;
|
|
80
|
+
if (/TIMEOUT/u.test(code))
|
|
81
|
+
return 14;
|
|
82
|
+
if (/SESSION|RESEARCH_NOT_FOUND|AUTOMATION_NOT_FOUND/u.test(code))
|
|
83
|
+
return 15;
|
|
84
|
+
if (/UPDATE/u.test(code))
|
|
85
|
+
return 16;
|
|
86
|
+
if (/CLI_USAGE_ERROR|ERR_PARSE_ARGS|REQUIRED|INVALID|UNKNOWN|CONFIG|QUERY|USAGE|STDIN|TALOS_RUNTIME_NOT_FOUND/u.test(code))
|
|
87
|
+
return 2;
|
|
88
|
+
return 70;
|
|
89
|
+
}
|
|
90
|
+
export function exitCodeForError(error) { return exitCodeForEnvelope(toTalosErrorEnvelope(error)); }
|
|
91
|
+
const INHERITED_TRACE_ID = /^[\x21-\x7e]{1,128}$/u;
|
|
92
|
+
export function traceIdForFailure(env = process.env) { const inherited = env.TALOS_TRACE_ID; return inherited !== undefined && INHERITED_TRACE_ID.test(inherited) ? inherited : randomUUID(); }
|
|
93
|
+
function messageForFailure(error, envelope) {
|
|
94
|
+
if (error instanceof TalosError)
|
|
95
|
+
return envelope.cause?.message ?? envelope.code;
|
|
96
|
+
if (error instanceof Error)
|
|
97
|
+
return error.message;
|
|
98
|
+
if (error && typeof error === 'object' && typeof error.message === 'string')
|
|
99
|
+
return String(error.message);
|
|
100
|
+
return envelope.code;
|
|
101
|
+
}
|
|
102
|
+
function fixedFailure(component = 'cli') { return { envelope: { code: 'INTERNAL_ERROR', component, retryable: false, traceId: randomUUID() }, message: 'The failure could not be rendered safely', exitCode: 70 }; }
|
|
103
|
+
export function safeTalosFailure(error, fallback = {}, secrets = secretValuesFromEnvironment(process.env)) {
|
|
104
|
+
const traceId = fallback.traceId ?? traceIdForFailure();
|
|
105
|
+
try {
|
|
106
|
+
const envelope = toTalosErrorEnvelope(error, { ...fallback, traceId });
|
|
107
|
+
const raw = { envelope, message: messageForFailure(error, envelope), exitCode: exitCodeForEnvelope(envelope) };
|
|
108
|
+
return redactObject(raw, secrets);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return fixedFailure(fallback.component ?? 'cli');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** C0, DEL, C1, bidi controls, zero-width controls, BOM and lone surrogates cannot drive the human terminal. */
|
|
115
|
+
const TERMINAL_CONTROL = /[\x00-\x1f\x7f-\x9f\u061c\u200b-\u200d\u202a-\u202e\u2028\u2029\u2066-\u2069\ufeff\ud800-\udfff]/gu;
|
|
116
|
+
export function inertTerminalText(value) { return String(value).replace(TERMINAL_CONTROL, c => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`); }
|
|
117
|
+
/*
|
|
118
|
+
* R2 lane E (Q-R2-4, gate E6): the human failure is three lines — what happened · what to do · "Details: <cause> (CODE) ·
|
|
119
|
+
* where to look" — worded by `describeError` from the CODE, so the code appears once and the kernel's Italian never does
|
|
120
|
+
* (Q-R2-2). Trace id and component are for JSON and `verbose` only. Every field is inert: no value can forge a line.
|
|
121
|
+
* Before R2 this was one line, `Error [CODE]: message; hint (component, trace)`, and a `CODE: prose` message printed the
|
|
122
|
+
* code twice (review D-06, s02).
|
|
123
|
+
*/
|
|
124
|
+
export function renderTalosFailureLine(failure, options = {}) {
|
|
125
|
+
const { envelope } = failure;
|
|
126
|
+
const view = describeError(failure);
|
|
127
|
+
const details = [view.detail, view.code ? `(${view.code})` : null, view.where].filter(Boolean).map(inertTerminalText).join(' · ');
|
|
128
|
+
const rows = [`${t('error.prefix')}: ${inertTerminalText(view.what)}`, ...(view.todo ? [inertTerminalText(view.todo)] : []), ...(details ? [`${t('common.details')}: ${details}`] : [])];
|
|
129
|
+
if (options.verbose)
|
|
130
|
+
rows.push(t('error.trace', { trace: inertTerminalText(envelope.traceId), component: inertTerminalText(envelope.component) }));
|
|
131
|
+
return `${rows.join('\n')}\n`;
|
|
132
|
+
}
|
|
133
|
+
function renderTalosFailure(format, failure, notices, verbose = false) {
|
|
134
|
+
if (format === 'json')
|
|
135
|
+
return { toStderr: false, text: `${JSON.stringify({ schema: 'talos.cli.result.v1', ok: false, sessionId: null, error: { code: failure.envelope.code, message: failure.message, details: failure.envelope }, warnings: notices.map(notice => notice.message) })}\n` };
|
|
136
|
+
if (format === 'stream-json') {
|
|
137
|
+
const events = [...notices.map((notice, index) => ({ schema: 'talos.cli.event.v1', seq: index + 1, ts: new Date().toISOString(), sessionId: '', type: 'warning', data: { code: notice.code, message: notice.message } })), { schema: 'talos.cli.event.v1', seq: notices.length + 1, ts: new Date().toISOString(), sessionId: '', type: 'run.failed', data: { ...failure.envelope, message: failure.message } }];
|
|
138
|
+
return { toStderr: false, text: events.map(event => `${JSON.stringify(event)}\n`).join('') };
|
|
139
|
+
}
|
|
140
|
+
return { toStderr: true, text: renderTalosFailureLine(failure, { verbose }) };
|
|
141
|
+
}
|
|
142
|
+
export function renderSafeTalosFailure(format, error, options = {}) {
|
|
143
|
+
const component = options.component ?? 'cli';
|
|
144
|
+
const secrets = secretValuesFromEnvironment(process.env);
|
|
145
|
+
try {
|
|
146
|
+
const failure = safeTalosFailure(error, { component, ...(options.retryable !== undefined ? { retryable: options.retryable } : {}), ...(options.traceId !== undefined ? { traceId: options.traceId } : {}) }, secrets);
|
|
147
|
+
const notices = redactObject(options.notices ?? [], secrets);
|
|
148
|
+
const rendered = renderTalosFailure(format, failure, notices, options.verbose === true);
|
|
149
|
+
return { ...rendered, failure, exitCode: failure.exitCode };
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
const failure = fixedFailure(component);
|
|
153
|
+
const rendered = renderTalosFailure(format, failure, []);
|
|
154
|
+
return { ...rendered, failure, exitCode: failure.exitCode };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createRedactor } from "../diagnostics/redact.js";
|
|
2
|
+
const MAP = { RunStarted: 'run.started', TextMessageContent: 'message.delta', ReasoningMessageContent: 'reasoning.delta', ToolCallStart: 'tool.started', ToolCallArgs: 'tool.args', ToolCallOutput: 'tool.completed', ApprovalRequested: 'approval.required', ApprovalResolved: 'approval.resolved', RunFinished: 'run.completed', RunError: 'run.failed' };
|
|
3
|
+
const SECRET = /api[_-]?key|authorization|password|secret|token/iu;
|
|
4
|
+
const FAILED_RECEIPT_STATUSES = new Set(['denied', 'premise_absent', 'failed', 'refused_busy']);
|
|
5
|
+
function clean(v, redactText) {
|
|
6
|
+
if (Array.isArray(v))
|
|
7
|
+
return v.map(value => clean(value, redactText));
|
|
8
|
+
if (v && typeof v === 'object') {
|
|
9
|
+
const o = {};
|
|
10
|
+
for (const [k, x] of Object.entries(v)) {
|
|
11
|
+
if (SECRET.test(k))
|
|
12
|
+
continue;
|
|
13
|
+
o[k] = clean(x, redactText);
|
|
14
|
+
}
|
|
15
|
+
return o;
|
|
16
|
+
}
|
|
17
|
+
return typeof v === 'string' ? redactText(v) : v;
|
|
18
|
+
}
|
|
19
|
+
function objectValue(value) { return value && typeof value === 'object' && !Array.isArray(value) ? value : null; }
|
|
20
|
+
function stringValue(value) { return typeof value === 'string' && value.length > 0 ? value : null; }
|
|
21
|
+
function numberValue(value) { return typeof value === 'number' && Number.isFinite(value) ? value : null; }
|
|
22
|
+
function booleanValue(value) { return typeof value === 'boolean' ? value : null; }
|
|
23
|
+
export function normalizeToolOutcome(raw) {
|
|
24
|
+
const toolCallId = stringValue(raw.toolCallId);
|
|
25
|
+
if (!toolCallId)
|
|
26
|
+
return null;
|
|
27
|
+
const receipt = objectValue(raw.receipt);
|
|
28
|
+
const evidence = objectValue(receipt?.evidence);
|
|
29
|
+
const receiptStatus = stringValue(receipt?.status);
|
|
30
|
+
const explicitCancelled = raw.outcome === 'cancelled';
|
|
31
|
+
const status = explicitCancelled
|
|
32
|
+
? 'cancelled'
|
|
33
|
+
: receiptStatus === 'effect_unknown'
|
|
34
|
+
? 'unknown'
|
|
35
|
+
: receiptStatus === 'succeeded'
|
|
36
|
+
? 'completed'
|
|
37
|
+
: receiptStatus && FAILED_RECEIPT_STATUSES.has(receiptStatus)
|
|
38
|
+
? 'failed'
|
|
39
|
+
: 'completed';
|
|
40
|
+
return {
|
|
41
|
+
toolCallId,
|
|
42
|
+
status,
|
|
43
|
+
content: String(raw.content ?? ''),
|
|
44
|
+
receiptStatus,
|
|
45
|
+
exitCode: numberValue(evidence?.exitCode),
|
|
46
|
+
enforcement: stringValue(evidence?.sandboxEnforcement),
|
|
47
|
+
allowed: booleanValue(receipt?.consentito),
|
|
48
|
+
permissionVia: stringValue(receipt?.via),
|
|
49
|
+
permissionReason: stringValue(receipt?.motivo),
|
|
50
|
+
risk: stringValue(receipt?.risk),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const HIDDEN_TOOL_OUTCOMES = Symbol.for('talos.cli.toolOutcomes');
|
|
54
|
+
const HIDDEN_TOOL_OUTCOME_CARRIER = Symbol.for('talos.cli.toolOutcomeCarrier');
|
|
55
|
+
function attachToolOutcomeCarrier(event, carrier) {
|
|
56
|
+
Object.defineProperty(event.data, HIDDEN_TOOL_OUTCOME_CARRIER, { value: carrier, enumerable: false, configurable: false, writable: false });
|
|
57
|
+
return event;
|
|
58
|
+
}
|
|
59
|
+
function hiddenToolOutcomes(event, outcomes) {
|
|
60
|
+
if (outcomes.length === 0)
|
|
61
|
+
return event;
|
|
62
|
+
const snapshot = [...outcomes];
|
|
63
|
+
Object.defineProperty(event, 'toolOutcomes', { value: snapshot, enumerable: false, configurable: false, writable: false });
|
|
64
|
+
Object.defineProperty(event.data, HIDDEN_TOOL_OUTCOMES, { value: snapshot, enumerable: false, configurable: false, writable: false });
|
|
65
|
+
return event;
|
|
66
|
+
}
|
|
67
|
+
export function hasToolOutcomeCarrier(event) {
|
|
68
|
+
if (Array.isArray(event.toolOutcomes))
|
|
69
|
+
return true;
|
|
70
|
+
const data = event.data;
|
|
71
|
+
return Array.isArray(data[HIDDEN_TOOL_OUTCOMES]) || data[HIDDEN_TOOL_OUTCOME_CARRIER] instanceof Map;
|
|
72
|
+
}
|
|
73
|
+
export function toolOutcomesFromCliEvent(event) {
|
|
74
|
+
const direct = event.toolOutcomes;
|
|
75
|
+
if (Array.isArray(direct))
|
|
76
|
+
return direct;
|
|
77
|
+
const data = event.data;
|
|
78
|
+
const snapshot = data[HIDDEN_TOOL_OUTCOMES];
|
|
79
|
+
if (Array.isArray(snapshot))
|
|
80
|
+
return snapshot;
|
|
81
|
+
const carrier = data[HIDDEN_TOOL_OUTCOME_CARRIER];
|
|
82
|
+
return carrier instanceof Map ? [...carrier.values()] : [];
|
|
83
|
+
}
|
|
84
|
+
export function createEventBridge(sessionId, clock = () => new Date().toISOString(), secretValues = []) {
|
|
85
|
+
let seq = 0;
|
|
86
|
+
const redactor = createRedactor(secretValues);
|
|
87
|
+
const pendingToolOutcomes = new Map();
|
|
88
|
+
return { translate(raw) {
|
|
89
|
+
if (!raw || typeof raw !== 'object')
|
|
90
|
+
return null;
|
|
91
|
+
const r = raw;
|
|
92
|
+
if (r.type === 'ToolCallResult') {
|
|
93
|
+
const sanitized = clean(r, redactor.text);
|
|
94
|
+
const outcome = normalizeToolOutcome(sanitized);
|
|
95
|
+
if (outcome) {
|
|
96
|
+
const previous = pendingToolOutcomes.get(outcome.toolCallId);
|
|
97
|
+
const shouldReplace = !previous
|
|
98
|
+
|| (previous.receiptStatus === null && outcome.receiptStatus !== null)
|
|
99
|
+
|| (previous.status === 'completed' && outcome.status !== 'completed');
|
|
100
|
+
if (shouldReplace)
|
|
101
|
+
pendingToolOutcomes.set(outcome.toolCallId, outcome);
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
let type = MAP[String(r.type)];
|
|
106
|
+
let source = { ...r };
|
|
107
|
+
if (r.type === 'StateDelta' && Array.isArray(r.delta)) {
|
|
108
|
+
const usage = r.delta.find(d => d.path === '/usage');
|
|
109
|
+
if (usage) {
|
|
110
|
+
type = 'usage.updated';
|
|
111
|
+
source = { ...source, value: usage.value };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!type)
|
|
115
|
+
return null;
|
|
116
|
+
const data = clean(source, redactor.text);
|
|
117
|
+
delete data.type;
|
|
118
|
+
if (type === 'approval.required')
|
|
119
|
+
data.requestId = r.requestId;
|
|
120
|
+
seq += 1;
|
|
121
|
+
const event = attachToolOutcomeCarrier({ schema: 'talos.cli.event.v1', seq, ts: clock(), sessionId, type, data }, pendingToolOutcomes);
|
|
122
|
+
if (type === 'run.completed' || type === 'run.failed') {
|
|
123
|
+
const outcomes = [...pendingToolOutcomes.values()];
|
|
124
|
+
const terminal = hiddenToolOutcomes(event, outcomes);
|
|
125
|
+
pendingToolOutcomes.clear();
|
|
126
|
+
return terminal;
|
|
127
|
+
}
|
|
128
|
+
return event;
|
|
129
|
+
} };
|
|
130
|
+
}
|