talos-code 0.0.1 → 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/LICENSE +661 -0
- package/README.md +111 -3
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/archive/zip.js +73 -0
- package/dist/args.js +97 -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 +185 -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 +43 -0
- package/dist/i18n/en/common.js +9 -0
- package/dist/i18n/en/credentials.js +82 -0
- package/dist/i18n/en/errors.js +246 -0
- package/dist/i18n/en/firstrun.js +89 -0
- package/dist/i18n/en/providers.js +37 -0
- package/dist/i18n/en/screen.js +736 -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 +330 -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/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-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 +262 -0
- package/dist/runtime/talos-composition.js +1006 -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/app.js +3761 -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 +559 -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 +32 -0
- package/dist/tui/components/terminal-shell.js +205 -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/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 +139 -0
- package/dist/tui/line-diff.js +57 -0
- package/dist/tui/live-activity.js +45 -0
- package/dist/tui/metrics.js +123 -0
- package/dist/tui/onboarding.js +36 -0
- package/dist/tui/overlays/agent-tree.js +39 -0
- package/dist/tui/overlays/approval-dialog.js +640 -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 +72 -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 +145 -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 +287 -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 +778 -0
- package/dist/tui/session-export.js +54 -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 +80 -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 +25 -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 +63 -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,187 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* R3 lane RD — the ONE tool row (gate E1), owner decisions of 2026-09-24 (ledger "R3 — tools and approvals"):
|
|
3
|
+
*
|
|
4
|
+
* <Label> <target> · <isolation> · <why it ran> · <result> · <duration> (Q-R3-1)
|
|
5
|
+
* <detail lines: output tail / diff / reason>
|
|
6
|
+
*
|
|
7
|
+
* - isolation: commands only (file tools are governed by permissions, R0 decision 3), from the CLI's own annotation as
|
|
8
|
+
* structured `facts.isolation` (gate E6), never kernel prose;
|
|
9
|
+
* - why it ran: the decision kinds (Q-R3-3); a person's `!` command is `typed by you`; nothing without a decision;
|
|
10
|
+
* - result: commands `exit N` (receipt or facts, gate E3), reads `N lines`, lists `N entries`, searches `N results`,
|
|
11
|
+
* writes `new file · N lines` or `+a −r`, edits `+a −r`; nothing to say is `done`;
|
|
12
|
+
* - duration: the kernel's measured `durationMs` only (never the CLI clock, which includes the approval wait): always
|
|
13
|
+
* for commands, from 1 s for other tools (Q-R3-2);
|
|
14
|
+
* - a state other than done replaces result and duration with its word (`waiting for you`, `running 12 s`, `denied`,
|
|
15
|
+
* `interrupted after 4.2 s`, `failed` + the exit code or the reason) — dictionary words, never the enum (E2);
|
|
16
|
+
* - too wide: the target is cut in the middle, then the duration goes, then the isolation word leaves its glyph; the
|
|
17
|
+
* glyph, the why field and the state word or exit code are never dropped. If even that does not fit, the target
|
|
18
|
+
* shrinks to `…`, then an `allow:` rule is cut in the middle, and whatever remains wraps (the estimate counts the
|
|
19
|
+
* same wrap, because it measures this same line).
|
|
20
|
+
*/
|
|
21
|
+
import { t } from "../../i18n/index.js";
|
|
22
|
+
import { displayWidth, truncateDisplay, truncateMiddle } from "../text-width.js";
|
|
23
|
+
import { boundedLines, detailWidth, formatDuration, labelFor, sanitizeDisplayText, withoutKernelExitLine } from "./shared.js";
|
|
24
|
+
const SEPARATOR = ' · ';
|
|
25
|
+
/* The target keeps at least this many columns while facts are still being shortened (then it may shrink to `…`). */
|
|
26
|
+
const TARGET_MIN = 12;
|
|
27
|
+
/** Q-R3-3: why a tool was allowed to run, in the owner's words; null when no decision was involved. */
|
|
28
|
+
function whyFact(row) {
|
|
29
|
+
const decision = row.decision ?? (row.origin === 'person' ? { kind: 'typed' } : null);
|
|
30
|
+
if (!decision)
|
|
31
|
+
return null;
|
|
32
|
+
if (decision.kind === 'rule') {
|
|
33
|
+
const rule = sanitizeDisplayText(String(decision.rule ?? '')).replace(/\s*\n\s*/gu, ' ');
|
|
34
|
+
return { role: 'why', text: t('tool.why.rule', { rule }), rule };
|
|
35
|
+
}
|
|
36
|
+
return { role: 'why', text: t(`tool.why.${decision.kind}`) };
|
|
37
|
+
}
|
|
38
|
+
/* A target is one line: its first line, and `…` when it had more (Q-R2-3). Shown as data (escaped controls). */
|
|
39
|
+
function oneLineTarget(value) { const [first = '', ...more] = sanitizeDisplayText(String(value ?? '')).split('\n'); const shown = first.trim(); return more.some(line => line.trim()) ? `${shown} …`.trim() : shown; }
|
|
40
|
+
function composeLine(label, target, facts) { return { title: label + (target ? ' ' + target : ''), statusLabel: facts.map(fact => fact.text).join(SEPARATOR) }; }
|
|
41
|
+
function widthOf(label, target, facts) { const { title, statusLabel } = composeLine(label, target, facts); return displayWidth(title + SEPARATOR + statusLabel); }
|
|
42
|
+
function fit(label, target, facts, width) {
|
|
43
|
+
if (!Number.isFinite(width) || widthOf(label, target, facts) <= width)
|
|
44
|
+
return { target, facts };
|
|
45
|
+
const cut = (current, minimum) => {
|
|
46
|
+
if (!target)
|
|
47
|
+
return '';
|
|
48
|
+
const budget = Math.max(Math.min(minimum, displayWidth(target)), width - widthOf(label, '', current) - 1);
|
|
49
|
+
return displayWidth(target) <= budget ? target : truncateMiddle(target, Math.max(1, budget));
|
|
50
|
+
};
|
|
51
|
+
const fits = (shown, current) => widthOf(label, shown, current) <= width;
|
|
52
|
+
let current = facts, shown = cut(current, TARGET_MIN);
|
|
53
|
+
if (fits(shown, current))
|
|
54
|
+
return { target: shown, facts: current };
|
|
55
|
+
current = current.filter(fact => fact.role !== 'duration');
|
|
56
|
+
shown = cut(current, TARGET_MIN);
|
|
57
|
+
if (fits(shown, current))
|
|
58
|
+
return { target: shown, facts: current };
|
|
59
|
+
current = current.map(fact => fact.role === 'isolation' && fact.short ? { ...fact, text: fact.short } : fact);
|
|
60
|
+
shown = cut(current, TARGET_MIN);
|
|
61
|
+
if (fits(shown, current))
|
|
62
|
+
return { target: shown, facts: current };
|
|
63
|
+
shown = cut(current, 1);
|
|
64
|
+
if (fits(shown, current))
|
|
65
|
+
return { target: shown, facts: current };
|
|
66
|
+
const why = current.find(fact => fact.role === 'why' && fact.rule !== undefined);
|
|
67
|
+
if (why) {
|
|
68
|
+
const others = current.filter(fact => fact !== why);
|
|
69
|
+
const room = width - widthOf(label, shown, others) - displayWidth(SEPARATOR) - displayWidth(t('tool.why.rule', { rule: '' }));
|
|
70
|
+
const rule = truncateMiddle(why.rule, Math.max(1, room));
|
|
71
|
+
current = current.map(fact => fact === why ? { ...fact, text: t('tool.why.rule', { rule }) } : fact);
|
|
72
|
+
}
|
|
73
|
+
return { target: shown, facts: current };
|
|
74
|
+
}
|
|
75
|
+
function evidenceLines(row, width) {
|
|
76
|
+
const outcome = row.outcome;
|
|
77
|
+
if (!outcome)
|
|
78
|
+
return [];
|
|
79
|
+
const rows = [];
|
|
80
|
+
if (outcome.receiptStatus)
|
|
81
|
+
rows.push(`receipt ${outcome.receiptStatus}`);
|
|
82
|
+
if (outcome.exitCode !== null)
|
|
83
|
+
rows.push(`exit ${outcome.exitCode}`);
|
|
84
|
+
if (outcome.enforcement !== null)
|
|
85
|
+
rows.push(`enforcement ${outcome.enforcement}`);
|
|
86
|
+
if (outcome.allowed !== null || outcome.permissionVia !== null) {
|
|
87
|
+
const decision = outcome.allowed === true ? 'allowed' : outcome.allowed === false ? 'denied' : 'not reported';
|
|
88
|
+
rows.push(`permission ${decision}${outcome.permissionVia ? ` via ${outcome.permissionVia}` : ''}`);
|
|
89
|
+
}
|
|
90
|
+
if (outcome.permissionReason)
|
|
91
|
+
rows.push(`permission reason ${outcome.permissionReason}`);
|
|
92
|
+
if (outcome.risk)
|
|
93
|
+
rows.push(`risk ${outcome.risk}`);
|
|
94
|
+
return rows.map(text => truncateDisplay(sanitizeDisplayText(text), detailWidth(width)));
|
|
95
|
+
}
|
|
96
|
+
function firstLine(text) { return String(text ?? '').split(/\r?\n/u).map(line => line.trim()).find(Boolean) ?? ''; }
|
|
97
|
+
export function composeToolRow(row, view, context) {
|
|
98
|
+
const label = sanitizeDisplayText(view.label ?? labelFor(row));
|
|
99
|
+
const target = oneLineTarget(view.target);
|
|
100
|
+
const facts = [];
|
|
101
|
+
if (view.command && row.facts?.isolation) {
|
|
102
|
+
const kind = row.facts.isolation;
|
|
103
|
+
facts.push({ role: 'isolation', text: t(`tool.isolation.${kind}`), short: t(`tool.isolation.${kind}.glyph`) });
|
|
104
|
+
}
|
|
105
|
+
const why = whyFact(row);
|
|
106
|
+
if (why)
|
|
107
|
+
facts.push(why);
|
|
108
|
+
const exit = row.facts?.exitCode ?? row.outcome?.exitCode ?? null;
|
|
109
|
+
const duration = typeof row.facts?.durationMs === 'number' && Number.isFinite(row.facts.durationMs) ? row.facts.durationMs : null;
|
|
110
|
+
const state = (text) => facts.push({ role: 'state', text });
|
|
111
|
+
let tone;
|
|
112
|
+
switch (row.status) {
|
|
113
|
+
case 'approval':
|
|
114
|
+
tone = 'waiting';
|
|
115
|
+
state(t('tool.state.waiting'));
|
|
116
|
+
break;
|
|
117
|
+
case 'queued':
|
|
118
|
+
case 'running':
|
|
119
|
+
case 'streaming': {
|
|
120
|
+
tone = 'running';
|
|
121
|
+
const elapsed = row.startedAt === null ? 0 : Math.max(0, context.now - row.startedAt);
|
|
122
|
+
state(view.liveTail || elapsed < 1000 ? t('tool.state.running') : t('tool.state.runningFor', { duration: formatDuration(elapsed) }));
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case 'completed': {
|
|
126
|
+
if (view.command) {
|
|
127
|
+
tone = exit !== null && exit !== 0 ? 'failed' : 'done';
|
|
128
|
+
if (exit !== null)
|
|
129
|
+
facts.push({ role: 'exit', text: t('tool.exit', { code: exit }) });
|
|
130
|
+
else
|
|
131
|
+
state(t('tool.state.done'));
|
|
132
|
+
if (duration !== null)
|
|
133
|
+
facts.push({ role: 'duration', text: formatDuration(duration) });
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
tone = 'done';
|
|
137
|
+
if (view.result.length)
|
|
138
|
+
for (const text of view.result)
|
|
139
|
+
facts.push({ role: 'result', text });
|
|
140
|
+
else
|
|
141
|
+
state(t('tool.state.done'));
|
|
142
|
+
if (duration !== null && duration >= 1000)
|
|
143
|
+
facts.push({ role: 'duration', text: formatDuration(duration) });
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case 'failed':
|
|
148
|
+
tone = 'failed';
|
|
149
|
+
state(t('tool.state.failed'));
|
|
150
|
+
if (exit !== null)
|
|
151
|
+
facts.push({ role: 'exit', text: t('tool.exit', { code: exit }) });
|
|
152
|
+
if (view.command && duration !== null)
|
|
153
|
+
facts.push({ role: 'duration', text: formatDuration(duration) });
|
|
154
|
+
break;
|
|
155
|
+
case 'denied':
|
|
156
|
+
tone = 'denied';
|
|
157
|
+
state(t('tool.state.denied'));
|
|
158
|
+
break;
|
|
159
|
+
case 'cancelled':
|
|
160
|
+
case 'interrupted': {
|
|
161
|
+
tone = 'interrupted';
|
|
162
|
+
const ran = row.startedAt !== null && row.endedAt !== null ? row.endedAt - row.startedAt : 0;
|
|
163
|
+
state(ran >= 1000 ? t('tool.state.interruptedAfter', { duration: formatDuration(ran) }) : t('tool.state.interrupted'));
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
default:
|
|
167
|
+
tone = 'unknown';
|
|
168
|
+
state(t('tool.state.unknown'));
|
|
169
|
+
}
|
|
170
|
+
const fitted = fit(label, target, facts, context.width);
|
|
171
|
+
const { title, statusLabel } = composeLine(label, fitted.target, fitted.facts);
|
|
172
|
+
const detail = [];
|
|
173
|
+
if (row.status === 'denied') {
|
|
174
|
+
/* E9: the refusal's English reason (transcript-model.ts puts describeRefusal's sentence in finalOutput). */
|
|
175
|
+
detail.push(truncateDisplay(sanitizeDisplayText(firstLine(row.finalOutput) || t('error.refused.generic')), detailWidth(context.width)));
|
|
176
|
+
}
|
|
177
|
+
else if (row.status === 'failed' && !view.showsOutput) {
|
|
178
|
+
detail.push(...boundedLines(withoutKernelExitLine(row.finalOutput).trim(), context.width, 2));
|
|
179
|
+
}
|
|
180
|
+
detail.push(...view.detail);
|
|
181
|
+
if (context.expanded) {
|
|
182
|
+
detail.push(...evidenceLines(row, context.width));
|
|
183
|
+
// Q-R2-3: the raw kernel name is shown only here, in the expanded detail, as the secondary identifier.
|
|
184
|
+
detail.push(truncateDisplay(sanitizeDisplayText(t('tool.detail.raw', { name: row.name })), detailWidth(context.width)));
|
|
185
|
+
}
|
|
186
|
+
return { title, statusLabel, line: title + SEPARATOR + statusLabel, detailLines: detail, tone, label, target: fitted.target, facts: fitted.facts.map(fact => fact.text) };
|
|
187
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { argumentLine, boundedLines, outputText, parseArgs } from "./shared.js";
|
|
2
|
+
import { tn } from "../../i18n/index.js";
|
|
3
|
+
/* R2 lane T: the kernel's `cerca` sends `testo` (text inside files) and/or `nome` (a path fragment), talosHarness.mjs:1586-1599.
|
|
4
|
+
R3 (Q-R3-1): `N results` on the row, counted from the kernel's own result shape (cercaNelProgetto, talosHarness.mjs:3630):
|
|
5
|
+
one match per line, `no file matches. …` for none, `… and N[+] more matches not shown …` for the cut, `⚠` notices apart.
|
|
6
|
+
These exact templates are pinned by r3-rd-tool-rows.test.ts; an answer of another shape gets no count. */
|
|
7
|
+
const NO_MATCH = /^no file matches\. Scanned /u;
|
|
8
|
+
const MISSING_ARGUMENTS = /^give at least one of "/u;
|
|
9
|
+
const MORE = /^… and (\d+)(\+?) more matches not shown — narrow the search\.$/u;
|
|
10
|
+
function searchCount(text) {
|
|
11
|
+
const value = String(text).trim();
|
|
12
|
+
if (MISSING_ARGUMENTS.test(value))
|
|
13
|
+
return null;
|
|
14
|
+
if (value === '' || NO_MATCH.test(value))
|
|
15
|
+
return { count: 0, atLeast: false };
|
|
16
|
+
let count = 0, atLeast = false;
|
|
17
|
+
for (const line of value.split(/\r?\n/u)) {
|
|
18
|
+
if (!line.trim() || line.startsWith('⚠'))
|
|
19
|
+
continue;
|
|
20
|
+
const more = MORE.exec(line);
|
|
21
|
+
if (more) {
|
|
22
|
+
count += Number(more[1]);
|
|
23
|
+
atLeast ||= more[2] === '+';
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
count++;
|
|
27
|
+
}
|
|
28
|
+
return { count, atLeast };
|
|
29
|
+
}
|
|
30
|
+
export const renderSearch = (row, context) => {
|
|
31
|
+
const a = parseArgs(row);
|
|
32
|
+
const query = String(a.testo ?? a.nome ?? a.query ?? a.pattern ?? a.term ?? a.raw ?? '').trim();
|
|
33
|
+
const path = String(a.path ?? a.root ?? '').trim();
|
|
34
|
+
const found = searchCount(outputText(row));
|
|
35
|
+
const result = found ? [tn('tool.search.results', found.count, found.atLeast ? { count: `${found.count}+` } : {})] : [];
|
|
36
|
+
const detail = [...(path ? boundedLines(argumentLine('path', path), context.width, 1) : []), ...(row.status === 'denied' || found?.count === 0 ? [] : boundedLines(outputText(row), context.width, context.expanded ? 12 : 3))];
|
|
37
|
+
return { target: query, result, detail, showsOutput: true };
|
|
38
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { t, tn } from "../../i18n/index.js";
|
|
2
|
+
import { truncateDisplay } from "../text-width.js";
|
|
3
|
+
import { argumentLabel, toolDisplay } from "../tool-display.js";
|
|
4
|
+
/*
|
|
5
|
+
* What reaches a terminal from a tool (its arguments, its output, a file's lines) is data: control characters, line and
|
|
6
|
+
* paragraph separators and bidi controls are shown escaped, never interpreted. The one implementation; transcript-model.ts
|
|
7
|
+
* re-exports it as `sanitizeTranscriptText` (kept here so the tool rows need no import of the transcript model).
|
|
8
|
+
*/
|
|
9
|
+
const UNSAFE_DISPLAY = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f\u2028\u2029\p{Bidi_Control}]/gu;
|
|
10
|
+
export function visibleEscape(character) { const code = character.codePointAt(0); return code > 0xffff ? '\\u{' + code.toString(16) + '}' : '\\u' + code.toString(16).padStart(4, '0'); }
|
|
11
|
+
export function sanitizeDisplayText(value) { return String(value).replace(/\r\n?/gu, '\n').replace(UNSAFE_DISPLAY, visibleEscape); }
|
|
12
|
+
/*
|
|
13
|
+
* R2 lane T (review D-07): arguments arrive as JSON text, streamed. A JSON object that is still arriving is repaired for
|
|
14
|
+
* display by closing its open string and braces; if that fails nothing is shown — partial JSON never reaches the screen.
|
|
15
|
+
* Text that is not JSON at all is a value, and stays one (`raw`).
|
|
16
|
+
*/
|
|
17
|
+
const CLOSERS = ['', '"}', '}', '"]}', ']}', '"}]}', '}]}', '"}}', '}}'];
|
|
18
|
+
export function parseArgs(row) {
|
|
19
|
+
const text = String(row.argsText || '').trim();
|
|
20
|
+
if (!text)
|
|
21
|
+
return {};
|
|
22
|
+
if (!text.startsWith('{'))
|
|
23
|
+
return { raw: row.argsText };
|
|
24
|
+
for (const closer of CLOSERS) {
|
|
25
|
+
try {
|
|
26
|
+
const value = JSON.parse(text + closer);
|
|
27
|
+
if (value && typeof value === 'object' && !Array.isArray(value))
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
catch { }
|
|
31
|
+
}
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
export function outputText(row) { return row.finalOutput || row.liveOutput || ''; }
|
|
35
|
+
export function detailWidth(width) { return Math.max(16, Math.min(240, width - 4)); }
|
|
36
|
+
export function boundedLines(text, width, maxLines = 8) { const cap = detailWidth(width); const rows = String(text).split(/\r?\n/u).slice(0, maxLines).map(line => truncateDisplay(sanitizeDisplayText(line), cap)); if (String(text).split(/\r?\n/u).length > maxLines)
|
|
37
|
+
rows.push('…'); return rows.filter(Boolean); }
|
|
38
|
+
/** The English label of a row's tool (tool-display.ts), whatever renderer draws it. */
|
|
39
|
+
export function labelFor(row) { return toolDisplay(row.name).label; }
|
|
40
|
+
export function textSize(text) { return { bytes: Buffer.byteLength(text, 'utf8'), lines: text ? text.split(/\r?\n/u).length : 0 }; }
|
|
41
|
+
/** Lines of a text as a person counts them: a final line break does not start a new line. */
|
|
42
|
+
export function lineCount(text) { const value = String(text); if (value === '')
|
|
43
|
+
return 0; const n = value.split('\n').length; return value.endsWith('\n') ? n - 1 : n; }
|
|
44
|
+
/*
|
|
45
|
+
* R3 gate E3: a command's result content starts with the kernel's own line `exit <n> [sandbox: <enforcement>]` (the model's
|
|
46
|
+
* shell, talosHarness.mjs:8662; a `!` command, agent-service.mjs:2166) or `exit <n>` (`prova`, talosHarness.mjs:8554/8564).
|
|
47
|
+
* The row states the exit code and the isolation from structured facts, so that exact first line is hidden on screen; the
|
|
48
|
+
* model's content is untouched (it stays in `outcome.content`). The templates are pinned by r3-rd-tool-rows.test.ts.
|
|
49
|
+
*/
|
|
50
|
+
const KERNEL_EXIT_LINE = /^exit (?:-?\d+|null|undefined)(?: \[sandbox: [^\n]*\])?$/u;
|
|
51
|
+
export function withoutKernelExitLine(text) { const value = String(text); const cut = value.indexOf('\n'); const first = cut < 0 ? value : value.slice(0, cut); return KERNEL_EXIT_LINE.test(first) ? (cut < 0 ? '' : value.slice(cut + 1)) : value; }
|
|
52
|
+
/* The transcript keeps the END of a long output behind this marker (transcript-model.ts `tail`). */
|
|
53
|
+
export function truncatedMarker() { return t('tool.transcript.truncated'); }
|
|
54
|
+
/** The last `max` lines of an output and how many lines stand above them (`atLeast` when the model kept only the end). */
|
|
55
|
+
export function outputTail(text, max) {
|
|
56
|
+
let value = String(text).replace(/\n+$/u, '');
|
|
57
|
+
const marker = truncatedMarker() + '\n', atLeast = value.startsWith(marker);
|
|
58
|
+
if (atLeast)
|
|
59
|
+
value = value.slice(marker.length);
|
|
60
|
+
if (value === '')
|
|
61
|
+
return { lines: [], hidden: 0, atLeast: false };
|
|
62
|
+
const all = value.split('\n');
|
|
63
|
+
const lines = all.slice(-max);
|
|
64
|
+
return { lines, hidden: all.length - lines.length, atLeast: atLeast && all.length > lines.length };
|
|
65
|
+
}
|
|
66
|
+
/** `+N lines` (or `+N+ lines` when the start of the output was dropped). */
|
|
67
|
+
export function moreLines(hidden, atLeast) { return tn('tool.output.more', hidden, atLeast ? { count: `${hidden}+` } : {}); }
|
|
68
|
+
/** Q-R3-2 words: `0.1 s`, `4.2 s` under ten seconds, `12 s`, then `1 min 15 s`. */
|
|
69
|
+
export function formatDuration(ms) {
|
|
70
|
+
const value = Math.max(0, Number(ms) || 0);
|
|
71
|
+
if (value < 10_000)
|
|
72
|
+
return t('tool.duration.seconds', { seconds: (value / 1000).toFixed(1) });
|
|
73
|
+
const seconds = Math.round(value / 1000);
|
|
74
|
+
if (seconds < 60)
|
|
75
|
+
return t('tool.duration.seconds', { seconds });
|
|
76
|
+
return t('tool.duration.minutes', { minutes: Math.floor(seconds / 60), seconds: seconds % 60 });
|
|
77
|
+
}
|
|
78
|
+
/*
|
|
79
|
+
* One argument as one line, `label: value`. A value is data and is shown as it is (strings, numbers, booleans); a text
|
|
80
|
+
* of several lines is counted (`content: 7 bytes · 2 lines`); an array or object is counted, never printed as JSON
|
|
81
|
+
* (review D-07: `args {"percorso":…}`).
|
|
82
|
+
*/
|
|
83
|
+
export function argumentLine(key, value) {
|
|
84
|
+
const label = argumentLabel(key);
|
|
85
|
+
if (typeof value === 'string') {
|
|
86
|
+
if (value === '')
|
|
87
|
+
return `${label}: ${t('tool.value.empty')}`;
|
|
88
|
+
return /\r|\n/u.test(value) ? `${label}: ${t('tool.value.bytes', textSize(value))}` : `${label}: ${value}`;
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
91
|
+
return `${label}: ${String(value)}`;
|
|
92
|
+
if (value === null || value === undefined)
|
|
93
|
+
return `${label}: ${t('tool.value.empty')}`;
|
|
94
|
+
if (Array.isArray(value))
|
|
95
|
+
return `${label}: ${tn('common.item', value.length)}`;
|
|
96
|
+
return `${label}: ${tn('tool.value.fields', Object.keys(value).length)}`;
|
|
97
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { argumentLine, lineCount, parseArgs } from "./shared.js";
|
|
2
|
+
import { changeDiff, changeSummaryOf, diffDetail, resultOfChange } from "./change.js";
|
|
3
|
+
import { t, tn } from "../../i18n/index.js";
|
|
4
|
+
/* R2 lane T: the kernel's `scrivi` sends `percorso`, `contenuto` and an optional `mode:"append"` (talosHarness.mjs:1653-1668).
|
|
5
|
+
R3 (Q-R3-4, gate E10): the row states the change the kernel reported (`file.changed`: `new file · N lines`, or `+a −r`
|
|
6
|
+
when it replaced a file); before that is known, the size of what was sent. The full diff is the expanded view (Ctrl+O). */
|
|
7
|
+
export const renderWrite = (row, context) => {
|
|
8
|
+
const a = parseArgs(row);
|
|
9
|
+
const path = String(a.percorso ?? a.path ?? a.file ?? a.filename ?? '').trim();
|
|
10
|
+
const content = String(a.contenuto ?? a.content ?? a.text ?? '');
|
|
11
|
+
const summary = changeSummaryOf(row);
|
|
12
|
+
const result = summary ? resultOfChange(summary) : [tn('tool.result.lines', lineCount(content)), ...(a.mode === 'append' ? [t('tool.result.appended')] : [])];
|
|
13
|
+
const detail = !context.expanded ? [] : row.change ? diffDetail(changeDiff(row.change), context.width) : [argumentLine('contenuto', content)];
|
|
14
|
+
return { target: path, result, detail };
|
|
15
|
+
};
|