@armadra/agent 0.5.1 → 0.6.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 +177 -304
- package/CHANGELOG.zh-CN.md +442 -0
- package/README.md +408 -364
- package/README.zh-CN.md +705 -0
- package/dist/agent/session-plan.js +2 -2
- package/dist/agent/session-state.d.ts +3 -0
- package/dist/agent/session-state.js +20 -0
- package/dist/agent/session-subagent.d.ts +15 -1
- package/dist/agent/session-subagent.js +26 -3
- package/dist/agent/session-telemetry.d.ts +16 -2
- package/dist/agent/session-telemetry.js +29 -7
- package/dist/agent/session-tools.js +5 -2
- package/dist/agent/session-trace-writer.d.ts +27 -0
- package/dist/agent/session-trace-writer.js +253 -0
- package/dist/agent/session.d.ts +2 -0
- package/dist/agent/session.js +12 -0
- package/dist/agent/subagent-direct.d.ts +20 -0
- package/dist/agent/subagent-direct.js +76 -0
- package/dist/agent/subagent-registry.d.ts +8 -1
- package/dist/agent/subagent-registry.js +28 -1
- package/dist/agent/system-prompt.d.ts +3 -1
- package/dist/agent/system-prompt.js +3 -0
- package/dist/agent/tool-runner.d.ts +2 -1
- package/dist/agent/tool-runner.js +5 -4
- package/dist/agent/types-w6.d.ts +39 -0
- package/dist/agent/types-w6.js +4 -0
- package/dist/agent/types.d.ts +5 -2
- package/dist/agents/external.js +1 -1
- package/dist/agents/task-record.d.ts +74 -1
- package/dist/agents/task-record.js +100 -0
- package/dist/ai/apis/cache-params.js +2 -1
- package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
- package/dist/ai/apis/chatgpt-backend.js +224 -0
- package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
- package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
- package/dist/ai/apis/openai-responses-request.d.ts +2 -1
- package/dist/ai/apis/openai-responses-request.js +8 -2
- package/dist/ai/apis/openai-responses.d.ts +2 -0
- package/dist/ai/apis/openai-responses.js +51 -16
- package/dist/ai/overflow.d.ts +1 -1
- package/dist/ai/overflow.js +10 -7
- package/dist/ai/providers/auth.d.ts +15 -2
- package/dist/ai/providers/auth.js +69 -2
- package/dist/ai/providers/builtin.js +27 -0
- package/dist/ai/providers/catalog-data.js +1 -0
- package/dist/ai/providers/enrich.js +2 -7
- package/dist/ai/providers/models-dev-cache.js +15 -19
- package/dist/ai/providers/models-dev-snapshot.js +8 -7
- package/dist/ai/providers/models-dev.js +5 -15
- package/dist/ai/providers/suggest.js +2 -16
- package/dist/ai/types.d.ts +27 -1
- package/dist/auth/chatgpt/backend-client.d.ts +26 -0
- package/dist/auth/chatgpt/backend-client.js +74 -0
- package/dist/auth/chatgpt/claims.d.ts +17 -0
- package/dist/auth/chatgpt/claims.js +46 -0
- package/dist/auth/chatgpt/cli.d.ts +33 -0
- package/dist/auth/chatgpt/cli.js +252 -0
- package/dist/auth/chatgpt/doctor.d.ts +17 -0
- package/dist/auth/chatgpt/doctor.js +36 -0
- package/dist/auth/chatgpt/host-id.d.ts +7 -0
- package/dist/auth/chatgpt/host-id.js +26 -0
- package/dist/auth/chatgpt/login.d.ts +30 -0
- package/dist/auth/chatgpt/login.js +130 -0
- package/dist/auth/chatgpt/presets.d.ts +66 -0
- package/dist/auth/chatgpt/presets.js +120 -0
- package/dist/auth/chatgpt/quota-text.d.ts +13 -0
- package/dist/auth/chatgpt/quota-text.js +36 -0
- package/dist/auth/oauth/browser.d.ts +12 -0
- package/dist/auth/oauth/browser.js +27 -0
- package/dist/auth/oauth/callback-server.d.ts +47 -0
- package/dist/auth/oauth/callback-server.js +147 -0
- package/dist/auth/oauth/flows.d.ts +62 -0
- package/dist/auth/oauth/flows.js +113 -0
- package/dist/auth/oauth/jwt.d.ts +24 -0
- package/dist/auth/oauth/jwt.js +81 -0
- package/dist/auth/oauth/live.d.ts +21 -0
- package/dist/auth/oauth/live.js +25 -0
- package/dist/auth/oauth/oidc.d.ts +26 -0
- package/dist/auth/oauth/oidc.js +72 -0
- package/dist/auth/oauth/pkce.d.ts +15 -0
- package/dist/auth/oauth/pkce.js +20 -0
- package/dist/auth/oauth/refresh.d.ts +35 -0
- package/dist/auth/oauth/refresh.js +129 -0
- package/dist/auth/oauth/token-client.d.ts +33 -0
- package/dist/auth/oauth/token-client.js +121 -0
- package/dist/auth/oauth/token-store.d.ts +23 -0
- package/dist/auth/oauth/token-store.js +125 -0
- package/dist/auth/testing/fake-oauth.d.ts +73 -0
- package/dist/auth/testing/fake-oauth.js +271 -0
- package/dist/auth/testing/refresh-child.d.ts +5 -0
- package/dist/auth/testing/refresh-child.js +16 -0
- package/dist/bundle/ama.cjs +25928 -11144
- package/dist/checkpoints/backend.js +6 -5
- package/dist/checkpoints/restore.js +3 -2
- package/dist/checkpoints/settings.js +2 -1
- package/dist/checkpoints/shadow-git.js +7 -6
- package/dist/checkpoints/shadow-restore.js +3 -2
- package/dist/checkpoints/tracker.js +4 -3
- package/dist/cli/args.d.ts +9 -2
- package/dist/cli/args.js +74 -27
- package/dist/cli/bootstrap.js +53 -31
- package/dist/cli/choice-prompt.js +8 -6
- package/dist/cli/codemode-notice.js +2 -2
- package/dist/cli/compose-agents.js +2 -1
- package/dist/cli/compose-extensions.js +2 -0
- package/dist/cli/compose-memory.d.ts +53 -0
- package/dist/cli/compose-memory.js +127 -0
- package/dist/cli/compose-providers.d.ts +5 -0
- package/dist/cli/compose-providers.js +32 -2
- package/dist/cli/compose-session.d.ts +5 -0
- package/dist/cli/compose-session.js +27 -13
- package/dist/cli/compose-store.d.ts +2 -0
- package/dist/cli/compose-store.js +9 -5
- package/dist/cli/compose.d.ts +2 -0
- package/dist/cli/compose.js +13 -5
- package/dist/cli/default-model.d.ts +0 -2
- package/dist/cli/default-model.js +5 -8
- package/dist/cli/deps.d.ts +5 -1
- package/dist/cli/exit-codes.d.ts +1 -1
- package/dist/cli/exit-codes.js +7 -16
- package/dist/cli/from-prompt.js +3 -2
- package/dist/cli/help-text.d.ts +2 -1
- package/dist/cli/help-text.js +5 -99
- package/dist/cli/main.d.ts +5 -0
- package/dist/cli/main.js +21 -2
- package/dist/cli/proxy.js +14 -9
- package/dist/cli/runtime.d.ts +5 -0
- package/dist/cli/startup-screen.js +20 -27
- package/dist/cli/startup-steps.js +6 -8
- package/dist/cli/subcommands/auth.d.ts +6 -3
- package/dist/cli/subcommands/auth.js +52 -22
- package/dist/cli/subcommands/config-set.d.ts +21 -0
- package/dist/cli/subcommands/config-set.js +137 -0
- package/dist/cli/subcommands/config.d.ts +2 -1
- package/dist/cli/subcommands/config.js +51 -37
- package/dist/cli/subcommands/doctor.d.ts +2 -1
- package/dist/cli/subcommands/doctor.js +97 -58
- package/dist/cli/subcommands/init.d.ts +1 -1
- package/dist/cli/subcommands/init.js +8 -7
- package/dist/cli/subcommands/memory.d.ts +18 -0
- package/dist/cli/subcommands/memory.js +189 -0
- package/dist/cli/subcommands/model-meta.js +11 -9
- package/dist/cli/subcommands/models-cache-probe.js +23 -20
- package/dist/cli/subcommands/models-discover.d.ts +3 -0
- package/dist/cli/subcommands/models-discover.js +44 -21
- package/dist/cli/subcommands/models.d.ts +1 -1
- package/dist/cli/subcommands/models.js +29 -22
- package/dist/cli/subcommands/probe-runner.js +8 -7
- package/dist/cli/subcommands/providers-list.js +32 -21
- package/dist/cli/subcommands/providers-plan.js +24 -25
- package/dist/cli/subcommands/providers-probe.js +5 -6
- package/dist/cli/subcommands/providers.d.ts +1 -1
- package/dist/cli/subcommands/providers.js +45 -50
- package/dist/cli/subcommands/sessions-export.d.ts +1 -1
- package/dist/cli/subcommands/sessions-export.js +10 -9
- package/dist/cli/subcommands/sessions-search.d.ts +1 -1
- package/dist/cli/subcommands/sessions-search.js +11 -10
- package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
- package/dist/cli/subcommands/sessions-trace.js +156 -0
- package/dist/cli/subcommands/sessions.d.ts +4 -3
- package/dist/cli/subcommands/sessions.js +40 -37
- package/dist/cli/subcommands/stats.d.ts +1 -1
- package/dist/cli/subcommands/stats.js +49 -30
- package/dist/cli/system-prompt-arg.js +3 -2
- package/dist/codemode/capability.js +3 -2
- package/dist/compaction/post-compact.d.ts +1 -0
- package/dist/compaction/post-compact.js +15 -1
- package/dist/compaction/prune-tier.d.ts +1 -1
- package/dist/compaction/prune-tier.js +3 -3
- package/dist/compaction/serialize.js +2 -1
- package/dist/config/auth-file.d.ts +12 -2
- package/dist/config/auth-file.js +32 -10
- package/dist/config/checker.js +12 -11
- package/dist/config/context-files.js +3 -2
- package/dist/config/edit.d.ts +106 -0
- package/dist/config/edit.js +350 -0
- package/dist/config/init.d.ts +4 -3
- package/dist/config/init.js +10 -18
- package/dist/config/json-schema.d.ts +2 -1
- package/dist/config/json-schema.js +101 -68
- package/dist/config/key-docs.d.ts +18 -7
- package/dist/config/key-docs.js +43 -128
- package/dist/config/load.js +7 -6
- package/dist/config/merge.d.ts +4 -1
- package/dist/config/merge.js +42 -22
- package/dist/config/paths.js +6 -5
- package/dist/config/profile.d.ts +5 -1
- package/dist/config/profile.js +7 -2
- package/dist/config/schema-w5.js +3 -2
- package/dist/config/schema-w6.d.ts +19 -0
- package/dist/config/schema-w6.js +115 -0
- package/dist/config/schema.js +34 -20
- package/dist/config/settings-registry.d.ts +78 -0
- package/dist/config/settings-registry.js +184 -0
- package/dist/config/types-w6.d.ts +109 -0
- package/dist/config/types-w6.js +19 -0
- package/dist/config/types.d.ts +11 -8
- package/dist/config/types.js +1 -0
- package/dist/drivers/acp/client.js +1 -1
- package/dist/drivers/acp/driver.js +13 -8
- package/dist/drivers/agents.js +4 -3
- package/dist/drivers/base.js +3 -2
- package/dist/drivers/host-runners.js +2 -1
- package/dist/drivers/native/claude-stream.js +12 -11
- package/dist/drivers/native/codex-app-server.js +17 -12
- package/dist/drivers/native/oneshot.js +8 -7
- package/dist/drivers/pool.js +1 -1
- package/dist/drivers/runner.d.ts +3 -1
- package/dist/drivers/runner.js +68 -20
- package/dist/drivers/turn.js +1 -1
- package/dist/hooks/config.js +3 -2
- package/dist/hooks/protocol.js +18 -12
- package/dist/host/api-impl.js +11 -10
- package/dist/host/loader.js +9 -8
- package/dist/host/types.d.ts +3 -0
- package/dist/i18n/catalog.d.ts +2169 -0
- package/dist/i18n/catalog.js +72 -0
- package/dist/i18n/format.d.ts +21 -0
- package/dist/i18n/format.js +58 -0
- package/dist/i18n/index.d.ts +58 -0
- package/dist/i18n/index.js +72 -0
- package/dist/i18n/messages/agents.d.ts +84 -0
- package/dist/i18n/messages/agents.js +85 -0
- package/dist/i18n/messages/approval.d.ts +99 -0
- package/dist/i18n/messages/approval.js +100 -0
- package/dist/i18n/messages/auth.d.ts +187 -0
- package/dist/i18n/messages/auth.js +189 -0
- package/dist/i18n/messages/cli-args.d.ts +46 -0
- package/dist/i18n/messages/cli-args.js +46 -0
- package/dist/i18n/messages/cli-help.d.ts +12 -0
- package/dist/i18n/messages/cli-help.js +244 -0
- package/dist/i18n/messages/cli.d.ts +336 -0
- package/dist/i18n/messages/cli.js +311 -0
- package/dist/i18n/messages/config-keys.d.ts +289 -0
- package/dist/i18n/messages/config-keys.js +292 -0
- package/dist/i18n/messages/config.d.ts +502 -0
- package/dist/i18n/messages/config.js +239 -0
- package/dist/i18n/messages/drivers.d.ts +123 -0
- package/dist/i18n/messages/drivers.js +124 -0
- package/dist/i18n/messages/errors.d.ts +83 -0
- package/dist/i18n/messages/errors.js +171 -0
- package/dist/i18n/messages/interactive-line.d.ts +61 -0
- package/dist/i18n/messages/interactive-line.js +69 -0
- package/dist/i18n/messages/interactive-startup.d.ts +103 -0
- package/dist/i18n/messages/interactive-startup.js +104 -0
- package/dist/i18n/messages/interactive-view.d.ts +140 -0
- package/dist/i18n/messages/interactive-view.js +141 -0
- package/dist/i18n/messages/interactive.d.ts +493 -0
- package/dist/i18n/messages/interactive.js +248 -0
- package/dist/i18n/messages/memory.d.ts +123 -0
- package/dist/i18n/messages/memory.js +128 -0
- package/dist/i18n/messages/panels.d.ts +190 -0
- package/dist/i18n/messages/panels.js +189 -0
- package/dist/i18n/messages/permissions.d.ts +126 -0
- package/dist/i18n/messages/permissions.js +151 -0
- package/dist/i18n/messages/plan.d.ts +123 -0
- package/dist/i18n/messages/plan.js +124 -0
- package/dist/i18n/messages/print.d.ts +86 -0
- package/dist/i18n/messages/print.js +91 -0
- package/dist/i18n/messages/report.d.ts +391 -0
- package/dist/i18n/messages/report.js +490 -0
- package/dist/i18n/messages/rewind.d.ts +198 -0
- package/dist/i18n/messages/rewind.js +217 -0
- package/dist/i18n/messages/session.d.ts +230 -0
- package/dist/i18n/messages/session.js +258 -0
- package/dist/i18n/messages/settings.d.ts +348 -0
- package/dist/i18n/messages/settings.js +336 -0
- package/dist/i18n/messages/subcommands-config.d.ts +111 -0
- package/dist/i18n/messages/subcommands-config.js +127 -0
- package/dist/i18n/messages/subcommands.d.ts +548 -0
- package/dist/i18n/messages/subcommands.js +474 -0
- package/dist/i18n/messages/trace.d.ts +243 -0
- package/dist/i18n/messages/trace.js +238 -0
- package/dist/i18n/types.d.ts +15 -0
- package/dist/i18n/types.js +7 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/dist/memory/edit.d.ts +24 -0
- package/dist/memory/edit.js +63 -0
- package/dist/memory/frontmatter.d.ts +37 -0
- package/dist/memory/frontmatter.js +79 -0
- package/dist/memory/index.d.ts +28 -0
- package/dist/memory/index.js +126 -0
- package/dist/memory/lock.d.ts +17 -0
- package/dist/memory/lock.js +62 -0
- package/dist/memory/paths.d.ts +57 -0
- package/dist/memory/paths.js +175 -0
- package/dist/memory/report.d.ts +36 -0
- package/dist/memory/report.js +86 -0
- package/dist/memory/runtime.d.ts +42 -0
- package/dist/memory/runtime.js +36 -0
- package/dist/memory/secrets.d.ts +8 -0
- package/dist/memory/secrets.js +27 -0
- package/dist/memory/section.d.ts +28 -0
- package/dist/memory/section.js +59 -0
- package/dist/memory/store.d.ts +70 -0
- package/dist/memory/store.js +284 -0
- package/dist/memory/tool.d.ts +31 -0
- package/dist/memory/tool.js +94 -0
- package/dist/modes/acp/acp-events.js +2 -1
- package/dist/modes/acp/acp-server.js +13 -12
- package/dist/modes/commands-core.d.ts +11 -0
- package/dist/modes/commands-core.js +93 -62
- package/dist/modes/image-input.js +20 -6
- package/dist/modes/interactive/agent-bar.d.ts +95 -0
- package/dist/modes/interactive/agent-bar.js +248 -0
- package/dist/modes/interactive/agent-panels.js +27 -26
- package/dist/modes/interactive/agent-transcript.d.ts +47 -0
- package/dist/modes/interactive/agent-transcript.js +191 -0
- package/dist/modes/interactive/agent-ui.d.ts +36 -1
- package/dist/modes/interactive/agent-ui.js +180 -14
- package/dist/modes/interactive/agent-view.d.ts +72 -0
- package/dist/modes/interactive/agent-view.js +281 -0
- package/dist/modes/interactive/approval-dialog.js +46 -34
- package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
- package/dist/modes/interactive/clipboard-paste.js +9 -4
- package/dist/modes/interactive/commands.d.ts +19 -1
- package/dist/modes/interactive/commands.js +84 -40
- package/dist/modes/interactive/completion.js +2 -1
- package/dist/modes/interactive/config-panel.d.ts +70 -0
- package/dist/modes/interactive/config-panel.js +319 -0
- package/dist/modes/interactive/config-ui.d.ts +96 -0
- package/dist/modes/interactive/config-ui.js +397 -0
- package/dist/modes/interactive/confirm-dialog.js +6 -7
- package/dist/modes/interactive/event-notices.js +11 -9
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.js +19 -22
- package/dist/modes/interactive/key-dispatch.d.ts +12 -0
- package/dist/modes/interactive/key-dispatch.js +24 -9
- package/dist/modes/interactive/line/line-editor.js +2 -1
- package/dist/modes/interactive/line/line-mode.js +18 -7
- package/dist/modes/interactive/line/line-render.js +25 -24
- package/dist/modes/interactive/memory-panel.d.ts +64 -0
- package/dist/modes/interactive/memory-panel.js +221 -0
- package/dist/modes/interactive/message-view.d.ts +4 -2
- package/dist/modes/interactive/message-view.js +42 -33
- package/dist/modes/interactive/panels.js +39 -31
- package/dist/modes/interactive/pickers.d.ts +2 -1
- package/dist/modes/interactive/pickers.js +10 -6
- package/dist/modes/interactive/plan-command.d.ts +1 -1
- package/dist/modes/interactive/plan-command.js +24 -27
- package/dist/modes/interactive/plan-dialog.js +18 -17
- package/dist/modes/interactive/plan-flow.js +6 -5
- package/dist/modes/interactive/rewind-command.d.ts +1 -1
- package/dist/modes/interactive/rewind-command.js +18 -16
- package/dist/modes/interactive/rewind-flow.d.ts +0 -1
- package/dist/modes/interactive/rewind-flow.js +13 -14
- package/dist/modes/interactive/rewind-list.js +7 -6
- package/dist/modes/interactive/rewind-panel.js +40 -40
- package/dist/modes/interactive/rewind-text.d.ts +5 -3
- package/dist/modes/interactive/rewind-text.js +48 -38
- package/dist/modes/interactive/run-indicator.js +15 -12
- package/dist/modes/interactive/session-events.js +3 -2
- package/dist/modes/interactive/startup-header.js +22 -23
- package/dist/modes/interactive/startup-ui.js +38 -30
- package/dist/modes/interactive/status-area.d.ts +2 -0
- package/dist/modes/interactive/status-area.js +8 -2
- package/dist/modes/interactive/status-bar.js +4 -3
- package/dist/modes/interactive/subagent-view.js +9 -7
- package/dist/modes/interactive/tasks-report.d.ts +6 -0
- package/dist/modes/interactive/tasks-report.js +28 -31
- package/dist/modes/interactive/terminal-setup.d.ts +9 -0
- package/dist/modes/interactive/terminal-setup.js +23 -0
- package/dist/modes/interactive/tool-summary.js +19 -17
- package/dist/modes/interactive/tool-view.js +7 -4
- package/dist/modes/interactive/trace-view.d.ts +89 -0
- package/dist/modes/interactive/trace-view.js +332 -0
- package/dist/modes/print/print-mode.js +14 -15
- package/dist/modes/rpc/commands.js +7 -3
- package/dist/modes/rpc/rpc-mode.js +9 -3
- package/dist/modes/session-report.d.ts +2 -0
- package/dist/modes/session-report.js +101 -105
- package/dist/modes/startup-ui-text.js +11 -6
- package/dist/permissions/bypass.d.ts +8 -10
- package/dist/permissions/bypass.js +19 -10
- package/dist/permissions/memory-class.d.ts +23 -0
- package/dist/permissions/memory-class.js +54 -0
- package/dist/permissions/modes.d.ts +3 -3
- package/dist/permissions/modes.js +21 -16
- package/dist/permissions/pipeline.d.ts +1 -1
- package/dist/permissions/pipeline.js +9 -2
- package/dist/permissions/preview.js +49 -42
- package/dist/permissions/rules.js +5 -2
- package/dist/permissions/types.d.ts +4 -0
- package/dist/plan/store.js +2 -1
- package/dist/rpc.d.ts +39 -1
- package/dist/rpc.js +3 -0
- package/dist/sandbox/bash.js +11 -8
- package/dist/sandbox/detect.js +14 -11
- package/dist/sdk.d.ts +17 -1
- package/dist/sdk.js +29 -7
- package/dist/session/export.js +31 -30
- package/dist/session/manager.d.ts +1 -1
- package/dist/session/manager.js +5 -3
- package/dist/session/reuse.js +5 -4
- package/dist/session/scan.js +3 -2
- package/dist/session/stats-aggregate.d.ts +3 -1
- package/dist/session/stats-aggregate.js +5 -1
- package/dist/session/stats-index.js +2 -1
- package/dist/session/stats-scan.d.ts +4 -1
- package/dist/session/stats-scan.js +6 -2
- package/dist/session/store.d.ts +11 -0
- package/dist/session/store.js +48 -1
- package/dist/session/types.d.ts +2 -0
- package/dist/skills/builtin.js +2 -1
- package/dist/tools/image-file.d.ts +26 -1
- package/dist/tools/image-file.js +55 -13
- package/dist/tools/presets.d.ts +14 -1
- package/dist/tools/presets.js +3 -3
- package/dist/tools/registry.js +1 -1
- package/dist/tools/truncate.d.ts +1 -1
- package/dist/tools/truncate.js +2 -2
- package/dist/tools/types.d.ts +17 -1
- package/dist/trace/build-index.d.ts +91 -0
- package/dist/trace/build-index.js +127 -0
- package/dist/trace/build-nodes.d.ts +24 -0
- package/dist/trace/build-nodes.js +279 -0
- package/dist/trace/build-util.d.ts +43 -0
- package/dist/trace/build-util.js +120 -0
- package/dist/trace/build.d.ts +82 -0
- package/dist/trace/build.js +382 -0
- package/dist/trace/detail.d.ts +35 -0
- package/dist/trace/detail.js +205 -0
- package/dist/trace/flatten.d.ts +69 -0
- package/dist/trace/flatten.js +173 -0
- package/dist/trace/format.d.ts +47 -0
- package/dist/trace/format.js +329 -0
- package/dist/trace/html-template.d.ts +19 -0
- package/dist/trace/html-template.js +150 -0
- package/dist/trace/html.d.ts +104 -0
- package/dist/trace/html.js +292 -0
- package/dist/trace/preview.d.ts +29 -0
- package/dist/trace/preview.js +59 -0
- package/dist/trace/query-session.d.ts +14 -0
- package/dist/trace/query-session.js +38 -0
- package/dist/trace/query.d.ts +55 -0
- package/dist/trace/query.js +188 -0
- package/dist/trace/session.d.ts +40 -0
- package/dist/trace/session.js +168 -0
- package/dist/trace/types.d.ts +243 -0
- package/dist/trace/types.js +13 -0
- package/dist/tui/components/editor-paste.d.ts +2 -0
- package/dist/tui/components/editor-paste.js +6 -3
- package/dist/tui/components/editor.js +2 -2
- package/dist/tui/components/loader.d.ts +3 -0
- package/dist/tui/components/loader.js +14 -0
- package/dist/tui/components/settings-list.d.ts +61 -0
- package/dist/tui/components/settings-list.js +135 -0
- package/dist/tui/keybindings.d.ts +5 -0
- package/dist/tui/keybindings.js +17 -5
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +2 -0
- package/docs/en/host-api.md +167 -0
- package/docs/en/permissions.md +214 -0
- package/docs/en/providers.md +625 -0
- package/docs/en/rpc.md +361 -0
- package/docs/en/sessions.md +219 -0
- package/docs/en/tui.md +527 -0
- package/docs/host-api.md +18 -17
- package/docs/memory.md +172 -0
- package/docs/permissions.md +2 -2
- package/docs/providers.md +67 -1
- package/docs/rpc.md +31 -3
- package/docs/session-format.md +8 -2
- package/docs/sessions.md +29 -1
- package/docs/tui.md +132 -3
- package/package.json +8 -3
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* `modelItems` / `sessionItems` 同时供交互模式里的选择器(pickers.ts)使用。
|
|
9
9
|
*/
|
|
10
|
+
import { msg } from "../../i18n/index.js";
|
|
10
11
|
import { existsSync, statSync } from "node:fs";
|
|
11
12
|
import { resolve } from "node:path";
|
|
12
13
|
import { Container, Editor, ProcessTerminal, SelectList, TUI, Text, createTheme, defaultKeybindings, detectCapabilities, } from "../../tui.js";
|
|
@@ -49,7 +50,7 @@ function askSelect(r, prompt) {
|
|
|
49
50
|
done(item);
|
|
50
51
|
},
|
|
51
52
|
onCancel: () => {
|
|
52
|
-
finish(
|
|
53
|
+
finish(msg().interactive.startup.ui.cancelled);
|
|
53
54
|
done(undefined);
|
|
54
55
|
},
|
|
55
56
|
});
|
|
@@ -57,10 +58,10 @@ function askSelect(r, prompt) {
|
|
|
57
58
|
list.selectValue(prompt.selected);
|
|
58
59
|
body.addChild(list);
|
|
59
60
|
body.addChild(new Text(r.theme.fg("dim", prompt.filterable === true
|
|
60
|
-
? "
|
|
61
|
+
? msg().interactive.startup.ui.hintFilter("↑↓")
|
|
61
62
|
: prompt.numberKeys === true
|
|
62
|
-
?
|
|
63
|
-
: "↑↓
|
|
63
|
+
? msg().interactive.startup.ui.hintNumbers("↑↓", prompt.items.length)
|
|
64
|
+
: msg().interactive.startup.ui.hint("↑↓"))));
|
|
64
65
|
tui.start();
|
|
65
66
|
tui.setFocus(list);
|
|
66
67
|
});
|
|
@@ -92,7 +93,7 @@ function askText(r, prompt) {
|
|
|
92
93
|
body.addChild(error);
|
|
93
94
|
tui.addInputListener((data) => {
|
|
94
95
|
if (r.keys.matches(data, "tui.select.cancel") && !editor.isCompletionOpen) {
|
|
95
|
-
finish(
|
|
96
|
+
finish(msg().interactive.startup.ui.cancelled);
|
|
96
97
|
done(undefined);
|
|
97
98
|
return true;
|
|
98
99
|
}
|
|
@@ -131,11 +132,11 @@ export async function modelItems(providers) {
|
|
|
131
132
|
let status;
|
|
132
133
|
let ready = true;
|
|
133
134
|
if (!provider.requiresApiKey)
|
|
134
|
-
status =
|
|
135
|
+
status = msg().interactive.startup.ui.local;
|
|
135
136
|
else {
|
|
136
137
|
const key = await providers.resolveApiKey(provider.id).catch(() => ({ apiKey: undefined }));
|
|
137
138
|
ready = key.apiKey !== undefined;
|
|
138
|
-
status = ready ? "key ✓" :
|
|
139
|
+
status = ready ? "key ✓" : msg().interactive.startup.ui.noKey;
|
|
139
140
|
}
|
|
140
141
|
const item = (model, group, channel) => {
|
|
141
142
|
const suffix = channel !== undefined && channel !== model.channel ? `@${channel}` : "";
|
|
@@ -168,17 +169,18 @@ export function relativeTime(iso, now) {
|
|
|
168
169
|
const at = Date.parse(iso);
|
|
169
170
|
if (!Number.isFinite(at))
|
|
170
171
|
return "";
|
|
172
|
+
const m = msg().interactive.startup.ui;
|
|
171
173
|
const minutes = Math.floor((now - at) / 60_000);
|
|
172
174
|
if (minutes < 1)
|
|
173
|
-
return
|
|
175
|
+
return m.justNow;
|
|
174
176
|
if (minutes < 60)
|
|
175
|
-
return
|
|
177
|
+
return m.minutesAgo(minutes);
|
|
176
178
|
const hours = Math.floor(minutes / 60);
|
|
177
179
|
if (hours < 24)
|
|
178
|
-
return
|
|
180
|
+
return m.hoursAgo(hours);
|
|
179
181
|
const days = Math.floor(hours / 24);
|
|
180
182
|
if (days < 30)
|
|
181
|
-
return
|
|
183
|
+
return m.daysAgo(days);
|
|
182
184
|
return iso.slice(0, 10);
|
|
183
185
|
}
|
|
184
186
|
function oneLine(text, max = 60) {
|
|
@@ -192,18 +194,21 @@ export function sessionItems(items, now) {
|
|
|
192
194
|
.map((item) => ({
|
|
193
195
|
value: item.id,
|
|
194
196
|
label: oneLine(item.name ?? item.firstPrompt ?? item.id.slice(0, 8)),
|
|
195
|
-
description: `${relativeTime(item.modifiedAt, now)} · ${item.messageCount}
|
|
197
|
+
description: `${relativeTime(item.modifiedAt, now)} · ${msg().interactive.startup.ui.messages(item.messageCount)}`,
|
|
196
198
|
}));
|
|
197
199
|
}
|
|
198
200
|
// ---------------------------------------------------------------------------
|
|
199
201
|
// InteractiveUi
|
|
200
202
|
// ---------------------------------------------------------------------------
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
function trustChoices() {
|
|
204
|
+
const m = msg().interactive.startup.ui;
|
|
205
|
+
return [
|
|
206
|
+
{ value: "trust", label: m.trustRemember, answer: { trusted: true, remember: true } },
|
|
207
|
+
{ value: "once", label: m.trustOnce, answer: { trusted: true, remember: false } },
|
|
208
|
+
{ value: "skip", label: m.trustSkip, answer: { trusted: false, remember: false } },
|
|
209
|
+
{ value: "never", label: m.trustNever, answer: { trusted: false, remember: true } },
|
|
210
|
+
];
|
|
211
|
+
}
|
|
207
212
|
function isDirectory(path) {
|
|
208
213
|
try {
|
|
209
214
|
return statSync(path).isDirectory();
|
|
@@ -216,24 +221,26 @@ export function createStartupUi(options = {}) {
|
|
|
216
221
|
const r = resolveOptions(options);
|
|
217
222
|
return {
|
|
218
223
|
async promptTrust(cwd, resources) {
|
|
224
|
+
const m = msg().interactive.startup.ui;
|
|
225
|
+
const choices = trustChoices();
|
|
219
226
|
const shown = resources.slice(0, 6).map((p) => ` ${p}`);
|
|
220
227
|
if (resources.length > shown.length)
|
|
221
|
-
shown.push(
|
|
228
|
+
shown.push(m.moreResources(resources.length - shown.length));
|
|
222
229
|
const picked = await askSelect(r, {
|
|
223
|
-
title:
|
|
230
|
+
title: m.trustTitle,
|
|
224
231
|
lines: [cwd, ...shown],
|
|
225
|
-
items:
|
|
232
|
+
items: choices.map(({ value, label }) => ({ value, label })),
|
|
226
233
|
selected: "once",
|
|
227
234
|
numberKeys: true,
|
|
228
235
|
});
|
|
229
|
-
const choice =
|
|
236
|
+
const choice = choices.find((c) => c.value === picked?.value);
|
|
230
237
|
return choice?.answer ?? { trusted: false, remember: false };
|
|
231
238
|
},
|
|
232
239
|
async pickSession(items) {
|
|
233
240
|
if (items.length === 0)
|
|
234
241
|
return undefined;
|
|
235
242
|
const picked = await askSelect(r, {
|
|
236
|
-
title:
|
|
243
|
+
title: msg().interactive.startup.ui.resumeTitle,
|
|
237
244
|
items: sessionItems(items, r.now()),
|
|
238
245
|
filterable: true,
|
|
239
246
|
});
|
|
@@ -244,7 +251,7 @@ export function createStartupUi(options = {}) {
|
|
|
244
251
|
if (items.length === 0)
|
|
245
252
|
return undefined;
|
|
246
253
|
const picked = await askSelect(r, {
|
|
247
|
-
title:
|
|
254
|
+
title: msg().interactive.startup.ui.modelTitle,
|
|
248
255
|
lines: [reason],
|
|
249
256
|
items,
|
|
250
257
|
filterable: true,
|
|
@@ -252,18 +259,19 @@ export function createStartupUi(options = {}) {
|
|
|
252
259
|
return picked?.value;
|
|
253
260
|
},
|
|
254
261
|
askCwd(missing) {
|
|
262
|
+
const m = msg().interactive.startup.ui;
|
|
255
263
|
return askText(r, {
|
|
256
|
-
title:
|
|
257
|
-
lines: [missing,
|
|
258
|
-
placeholder:
|
|
264
|
+
title: m.cwdTitle,
|
|
265
|
+
lines: [missing, m.cwdPrompt],
|
|
266
|
+
placeholder: m.cwdPlaceholder,
|
|
259
267
|
validate: (text) => {
|
|
260
268
|
if (text === "")
|
|
261
|
-
return
|
|
269
|
+
return m.cwdEmpty;
|
|
262
270
|
const abs = resolve(text);
|
|
263
271
|
if (!existsSync(abs))
|
|
264
|
-
return
|
|
272
|
+
return m.cwdMissing(abs);
|
|
265
273
|
if (!isDirectory(abs))
|
|
266
|
-
return
|
|
274
|
+
return m.cwdNotDir(abs);
|
|
267
275
|
return undefined;
|
|
268
276
|
},
|
|
269
277
|
});
|
|
@@ -53,6 +53,8 @@ export declare class StatusArea {
|
|
|
53
53
|
private bashSandbox;
|
|
54
54
|
constructor(deps: StatusAreaDeps);
|
|
55
55
|
layout(): StatusLineMode;
|
|
56
|
+
/** [W6-A] 界面配置(Agent 栏开关、子 Agent 视图的消息显示选项)。 */
|
|
57
|
+
ui(): NonNullable<Runtime["config"]["ui"]>;
|
|
56
58
|
setLayout(mode: StatusLineMode): void;
|
|
57
59
|
toggle(): StatusLineMode;
|
|
58
60
|
refresh(): void;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - [W5-U] `model_fallback` 之后状态栏模型项显示 `主模型 → 回退模型`,切回主模型(`model_changed`)后消失。
|
|
10
10
|
* - `telemetry_tick`(流式中 ≤ 2 Hz)只重取统计并重画(速率行),状态栏的内容这时不变。
|
|
11
11
|
*/
|
|
12
|
+
import { msg } from "../../i18n/index.js";
|
|
12
13
|
import { basename } from "node:path";
|
|
13
14
|
import { sandboxCapabilityFor } from "../../codemode/capability.js";
|
|
14
15
|
import { formatModelRef } from "../../ai/providers/channels.js";
|
|
@@ -86,6 +87,10 @@ export class StatusArea {
|
|
|
86
87
|
layout() {
|
|
87
88
|
return this.mode;
|
|
88
89
|
}
|
|
90
|
+
/** [W6-A] 界面配置(Agent 栏开关、子 Agent 视图的消息显示选项)。 */
|
|
91
|
+
ui() {
|
|
92
|
+
return this.deps.runtime.config.ui ?? {};
|
|
93
|
+
}
|
|
89
94
|
setLayout(mode) {
|
|
90
95
|
if (mode === this.mode)
|
|
91
96
|
return;
|
|
@@ -179,12 +184,13 @@ export function statusLineSlash(area, line, notice) {
|
|
|
179
184
|
else if (value === "full" || value === "compact")
|
|
180
185
|
area.setLayout(value);
|
|
181
186
|
else {
|
|
182
|
-
notice("error",
|
|
187
|
+
notice("error", msg().interactive.statusLine.usage);
|
|
183
188
|
return true;
|
|
184
189
|
}
|
|
185
190
|
notice("info", statusLineText(area.layout()));
|
|
186
191
|
return true;
|
|
187
192
|
}
|
|
188
193
|
export function statusLineText(mode) {
|
|
189
|
-
|
|
194
|
+
const m = msg().interactive.statusLine;
|
|
195
|
+
return mode === "full" ? m.full : m.compact;
|
|
190
196
|
}
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* - 宽度不够时按优先级丢弃(数字大的先丢,表见 §1.2);会变的数字按最宽形状占位(`reserve`),
|
|
27
27
|
* 数字变化不会让某项时有时无(40 列不抖动)。
|
|
28
28
|
*/
|
|
29
|
+
import { msg } from "../../i18n/index.js";
|
|
29
30
|
import { permissionModeLabel } from "../../permissions/modes.js";
|
|
30
31
|
import { formatModelRef } from "../../ai/providers/channels.js";
|
|
31
32
|
import { Meter, levelColor, truncateToWidth, visibleWidth, } from "../../tui.js";
|
|
@@ -57,7 +58,7 @@ export function formatDuration(ms) {
|
|
|
57
58
|
export function cacheText(cache, warm = "♨") {
|
|
58
59
|
const rate = cache.lastHitRate ?? cache.hitRate;
|
|
59
60
|
const value = cache.reporting === "silent"
|
|
60
|
-
?
|
|
61
|
+
? msg().interactive.statusLine.cacheSilent
|
|
61
62
|
: cache.reporting === "reported" && rate !== undefined
|
|
62
63
|
? `${Math.round(rate * 100)}%`
|
|
63
64
|
: "—";
|
|
@@ -178,7 +179,7 @@ export function usageItems(stats, queue, source, theme) {
|
|
|
178
179
|
out.codemode = strict ? label : `${label} ${theme.fg("error", "net!")}`;
|
|
179
180
|
}
|
|
180
181
|
if (source.bashSandbox?.() === true)
|
|
181
|
-
out.sandbox = dim(
|
|
182
|
+
out.sandbox = dim(msg().interactive.statusLine.sandbox);
|
|
182
183
|
const preset = source.preset();
|
|
183
184
|
if (preset !== "default")
|
|
184
185
|
out.preset = dim(`preset ${preset}`);
|
|
@@ -262,7 +263,7 @@ export class StatusBar {
|
|
|
262
263
|
});
|
|
263
264
|
if (width >= 40) {
|
|
264
265
|
parts.push({
|
|
265
|
-
text: dim(
|
|
266
|
+
text: dim(msg().interactive.statusLine.cycleHint),
|
|
266
267
|
priority: full ? FULL_HINT : COMPACT.hint,
|
|
267
268
|
zone: "left",
|
|
268
269
|
});
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* 完成后父会话收到的 `<task-notification>` 只显示一行(`notificationSummary`),失败 / 停止另有一行提示。
|
|
14
14
|
* 外部 runner(claude / codex)同一组事件,用量可能缺。
|
|
15
15
|
*/
|
|
16
|
+
import { msg } from "../../i18n/index.js";
|
|
16
17
|
import { formatElapsed } from "../../tui.js";
|
|
17
18
|
import { formatTokenCount } from "../session-report.js";
|
|
18
19
|
import { taskStatusText } from "./tasks-report.js";
|
|
@@ -96,10 +97,12 @@ export function subagentLine(state, theme, now) {
|
|
|
96
97
|
const g = theme.glyphs;
|
|
97
98
|
const end = state.endedAt ?? now;
|
|
98
99
|
const elapsed = formatElapsed(end - state.startedAt);
|
|
99
|
-
const status = state.status === "running"
|
|
100
|
+
const status = state.status === "running"
|
|
101
|
+
? msg().interactive.subagent.running(elapsed)
|
|
102
|
+
: `${taskStatusText(state.status)} ${elapsed}`;
|
|
100
103
|
const facts = [status];
|
|
101
104
|
if (state.turns > 0)
|
|
102
|
-
facts.push(
|
|
105
|
+
facts.push(msg().panels.tasks.turns(state.turns));
|
|
103
106
|
if (state.tools.length > 0)
|
|
104
107
|
facts.push(state.tools.join(" "));
|
|
105
108
|
const usage = state.usage;
|
|
@@ -113,14 +116,13 @@ export function subagentLine(state, theme, now) {
|
|
|
113
116
|
? "error"
|
|
114
117
|
: "warning";
|
|
115
118
|
const agent = state.runner !== "ama" && state.runner !== state.agent
|
|
116
|
-
?
|
|
119
|
+
? msg().panels.tasks.agentRunner(state.agent, state.runner)
|
|
117
120
|
: state.agent;
|
|
118
121
|
return theme.fg("tool", agent) + theme.fg("dim", " · ") + theme.fg(color, facts.join(" · "));
|
|
119
122
|
}
|
|
120
123
|
/** 后台任务结束的一行提示。 */
|
|
121
124
|
export function backgroundEndText(state) {
|
|
122
|
-
|
|
123
|
-
return `后台任务 ${state.taskId}(${state.agent})${taskStatusText(state.status)}${turns} · /tasks 查看输出`;
|
|
125
|
+
return msg().interactive.subagent.backgroundEnd(state.taskId, state.agent, taskStatusText(state.status), state.turns);
|
|
124
126
|
}
|
|
125
127
|
/**
|
|
126
128
|
* 父会话收到的 `<task-notification …>`(origin `task` 的用户消息)在消息区只显示一行:
|
|
@@ -141,8 +143,8 @@ export function notificationSummary(text) {
|
|
|
141
143
|
];
|
|
142
144
|
const turns = attrs.get("turns");
|
|
143
145
|
if (turns !== undefined)
|
|
144
|
-
parts.push(
|
|
145
|
-
parts.push(
|
|
146
|
+
parts.push(msg().interactive.subagent.notificationTurns(turns));
|
|
147
|
+
parts.push(msg().interactive.subagent.viewOutput);
|
|
146
148
|
return parts.join(" · ");
|
|
147
149
|
}
|
|
148
150
|
const STATUS_KEYS = {
|
|
@@ -23,5 +23,11 @@ export declare function describeTasks(sessionId: string, now: number): string;
|
|
|
23
23
|
export declare function describeTaskOutput(sessionId: string, taskId: string, now: number): string;
|
|
24
24
|
/** 类型一行的状态:外部 Agent 写安装与版本。 */
|
|
25
25
|
export declare function agentFacts(agent: AgentInfo): string[];
|
|
26
|
+
/** [W6-C0] 带状态的事实项:界面按 `state` 上色,不按文案判断(文案会随界面语言变)。 */
|
|
27
|
+
export interface AgentFact {
|
|
28
|
+
text: string;
|
|
29
|
+
state?: "missing" | "installed";
|
|
30
|
+
}
|
|
31
|
+
export declare function agentFactItems(agent: AgentInfo): AgentFact[];
|
|
26
32
|
/** `/agents` 的纯文本(line 模式)。 */
|
|
27
33
|
export declare function describeAgents(sessionId: string): string;
|
|
@@ -7,18 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { cachedAgentInfos } from "../../agents/external.js";
|
|
9
9
|
import { registryOf, sessionAgents, taskRegistryView } from "../../agent/subagent-registry.js";
|
|
10
|
+
import { msg } from "../../i18n/index.js";
|
|
10
11
|
import { formatTokenCount, formatUsd } from "../session-report.js";
|
|
11
12
|
import { formatDuration } from "./tool-summary.js";
|
|
12
|
-
const STATUS = {
|
|
13
|
-
running: "运行中",
|
|
14
|
-
completed: "完成",
|
|
15
|
-
failed: "失败",
|
|
16
|
-
aborted: "已停止",
|
|
17
|
-
max_turns: "轮数耗尽",
|
|
18
|
-
interrupted: "已中断",
|
|
19
|
-
};
|
|
20
13
|
export function taskStatusText(status) {
|
|
21
|
-
return
|
|
14
|
+
return msg().panels.tasks.status[status];
|
|
22
15
|
}
|
|
23
16
|
export function listTasks(sessionId) {
|
|
24
17
|
return taskRegistryView(sessionId)?.list() ?? [];
|
|
@@ -41,7 +34,7 @@ export function taskFacts(task, now) {
|
|
|
41
34
|
const end = task.endedAt ?? now;
|
|
42
35
|
const facts = [taskStatusText(task.status), formatDuration(end - task.startedAt)];
|
|
43
36
|
if (task.turns !== undefined && task.turns > 0)
|
|
44
|
-
facts.push(
|
|
37
|
+
facts.push(msg().panels.tasks.turns(task.turns));
|
|
45
38
|
const usage = task.usage;
|
|
46
39
|
if (usage !== undefined && usage.input + usage.output + usage.cacheRead > 0)
|
|
47
40
|
facts.push(`↑${formatTokenCount(usage.input + usage.cacheRead + usage.cacheWrite)} ↓${formatTokenCount(usage.output)}`);
|
|
@@ -55,60 +48,64 @@ function oneLine(text, max = 60) {
|
|
|
55
48
|
}
|
|
56
49
|
/** `t1 explore · 运行中 · 1m05s · 7 轮 · 描述` */
|
|
57
50
|
export function taskLine(task, now) {
|
|
51
|
+
const m = msg().panels.tasks;
|
|
58
52
|
const agent = task.runner !== "ama" && task.runner !== task.agent
|
|
59
|
-
?
|
|
53
|
+
? m.agentRunner(task.agent, task.runner)
|
|
60
54
|
: task.agent;
|
|
61
55
|
const parts = [agent, ...taskFacts(task, now)];
|
|
62
56
|
if (task.background)
|
|
63
|
-
parts.push(
|
|
57
|
+
parts.push(m.background);
|
|
64
58
|
const description = oneLine(task.description);
|
|
65
59
|
return `${task.taskId} ${parts.join(" · ")}${description !== "" ? ` ${description}` : ""}`;
|
|
66
60
|
}
|
|
67
61
|
/** `/tasks` 的纯文本(line 模式)。 */
|
|
68
62
|
export function describeTasks(sessionId, now) {
|
|
63
|
+
const m = msg().panels.tasks;
|
|
69
64
|
const tasks = listTasks(sessionId);
|
|
70
65
|
if (tasks.length === 0)
|
|
71
|
-
return
|
|
66
|
+
return m.none;
|
|
72
67
|
return [
|
|
73
|
-
|
|
68
|
+
m.heading(tasks.length),
|
|
74
69
|
...tasks.map((task) => ` ${taskLine(task, now)}`),
|
|
75
|
-
|
|
70
|
+
m.footer,
|
|
76
71
|
].join("\n");
|
|
77
72
|
}
|
|
78
73
|
/** 一个任务的输出全文(line 模式 `/tasks <id>`)。 */
|
|
79
74
|
export function describeTaskOutput(sessionId, taskId, now) {
|
|
75
|
+
const m = msg().panels.tasks;
|
|
80
76
|
const task = taskRegistryView(sessionId)?.get(taskId);
|
|
81
77
|
if (task === undefined)
|
|
82
|
-
return
|
|
78
|
+
return m.notFound(taskId);
|
|
83
79
|
const output = taskOutput(sessionId, taskId) ?? "";
|
|
84
|
-
const file = task.outputFile !== undefined ? `\n
|
|
85
|
-
return `${taskLine(task, now)}${file}\n${output.trim() === "" ?
|
|
80
|
+
const file = task.outputFile !== undefined ? `\n${m.fullOutput(task.outputFile)}` : "";
|
|
81
|
+
return `${taskLine(task, now)}${file}\n${output.trim() === "" ? m.noOutput : output.trimEnd()}`;
|
|
82
|
+
}
|
|
83
|
+
function sourceText(source) {
|
|
84
|
+
const table = msg().panels.agents.source;
|
|
85
|
+
return table[source] ?? source;
|
|
86
86
|
}
|
|
87
|
-
const SOURCE = {
|
|
88
|
-
builtin: "内置",
|
|
89
|
-
cli: "命令行",
|
|
90
|
-
profile: "profile",
|
|
91
|
-
user: "用户",
|
|
92
|
-
project: "项目",
|
|
93
|
-
host: "宿主",
|
|
94
|
-
};
|
|
95
87
|
/** 类型一行的状态:外部 Agent 写安装与版本。 */
|
|
96
88
|
export function agentFacts(agent) {
|
|
97
|
-
|
|
89
|
+
return agentFactItems(agent).map((fact) => fact.text);
|
|
90
|
+
}
|
|
91
|
+
export function agentFactItems(agent) {
|
|
92
|
+
const m = msg().panels.agents;
|
|
93
|
+
const facts = [{ text: agent.runner }, { text: sourceText(agent.source) }];
|
|
98
94
|
if (agent.installed === false)
|
|
99
|
-
facts.push("
|
|
95
|
+
facts.push({ text: m.notInstalled, state: "missing" });
|
|
100
96
|
else if (agent.installed === true)
|
|
101
|
-
facts.push(
|
|
97
|
+
facts.push({ text: m.installed(agent.version), state: "installed" });
|
|
102
98
|
return facts;
|
|
103
99
|
}
|
|
104
100
|
/** `/agents` 的纯文本(line 模式)。 */
|
|
105
101
|
export function describeAgents(sessionId) {
|
|
102
|
+
const m = msg().panels.agents;
|
|
106
103
|
const agents = listAgents(sessionId);
|
|
107
104
|
if (agents.length === 0)
|
|
108
|
-
return
|
|
105
|
+
return m.none;
|
|
109
106
|
const width = Math.max(...agents.map((a) => a.name.length));
|
|
110
107
|
return [
|
|
111
|
-
|
|
108
|
+
m.typesHeading(agents.length),
|
|
112
109
|
...agents.map((a) => ` ${a.name.padEnd(width)} ${agentFacts(a).join(" · ")} ${oneLine(a.description)}`),
|
|
113
110
|
].join("\n");
|
|
114
111
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 交互模式装配用到的两个小工具(从 interactive-mode.ts 拆出,控制单文件行数):真实终端与 keybindings.json。
|
|
3
|
+
*/
|
|
4
|
+
import type { Runtime } from "../../cli/runtime.js";
|
|
5
|
+
import { Keybindings, type Terminal } from "../../tui.js";
|
|
6
|
+
/** stdin / stdout 都是 TTY 才用真实终端;否则抛 `terminal_init_failed`(调用方降级到行式界面)。 */
|
|
7
|
+
export declare function processTerminal(): Terminal;
|
|
8
|
+
/** 读 `<configDir>/keybindings.json`;问题逐条交给 `warn`。 */
|
|
9
|
+
export declare function loadKeys(runtime: Runtime, warn: (m: string) => void): Keybindings;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 交互模式装配用到的两个小工具(从 interactive-mode.ts 拆出,控制单文件行数):真实终端与 keybindings.json。
|
|
3
|
+
*/
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { KEYBINDINGS_FILE } from "../../config/paths.js";
|
|
6
|
+
import { AmaError } from "../../errors.js";
|
|
7
|
+
import { msg } from "../../i18n/index.js";
|
|
8
|
+
import { Keybindings, ProcessTerminal, loadKeybindingsFile } from "../../tui.js";
|
|
9
|
+
/** stdin / stdout 都是 TTY 才用真实终端;否则抛 `terminal_init_failed`(调用方降级到行式界面)。 */
|
|
10
|
+
export function processTerminal() {
|
|
11
|
+
const stdin = process.stdin;
|
|
12
|
+
if (stdin.isTTY !== true || typeof stdin.setRawMode !== "function" || !process.stdout.isTTY) {
|
|
13
|
+
throw new AmaError("terminal_init_failed", msg().interactive.app.notTty);
|
|
14
|
+
}
|
|
15
|
+
return new ProcessTerminal();
|
|
16
|
+
}
|
|
17
|
+
/** 读 `<configDir>/keybindings.json`;问题逐条交给 `warn`。 */
|
|
18
|
+
export function loadKeys(runtime, warn) {
|
|
19
|
+
const parsed = loadKeybindingsFile(join(runtime.paths.configDir, KEYBINDINGS_FILE));
|
|
20
|
+
for (const w of parsed.warnings)
|
|
21
|
+
warn(msg().interactive.app.keybindingsWarning(w));
|
|
22
|
+
return new Keybindings(parsed.overrides);
|
|
23
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - grep `N 处匹配 · M 个文件`;glob `N 个文件`;codemode `N 个内层调用 · 脚本输出 M 行`;
|
|
9
9
|
* - task `完成 · 耗时 · ↑in ↓out`;其它 `N 行输出`;失败(非 bash)取错误首行。
|
|
10
10
|
*/
|
|
11
|
+
import { msg } from "../../i18n/index.js";
|
|
11
12
|
import { isAbsolute, relative } from "node:path";
|
|
12
13
|
import { stripAnsi } from "../../tui.js";
|
|
13
14
|
import { formatTokens } from "./status-bar.js";
|
|
@@ -135,6 +136,7 @@ export function bashOutput(result) {
|
|
|
135
136
|
/** 完成后的一行结果摘要(已着色,不含 `⎿`)。 */
|
|
136
137
|
export function resultSummary(input, theme) {
|
|
137
138
|
const { name, result, isError, lines } = input;
|
|
139
|
+
const m = msg().interactive.view.tool;
|
|
138
140
|
const details = record(result.details);
|
|
139
141
|
const muted = (s) => theme.fg("muted", s);
|
|
140
142
|
const sep = theme.fg("dim", " · ");
|
|
@@ -146,27 +148,27 @@ export function resultSummary(input, theme) {
|
|
|
146
148
|
const code = num(details["exit_code"]) ?? (isError ? 1 : 0);
|
|
147
149
|
const total = num(details["totalLines"]) ?? count;
|
|
148
150
|
const head = details["aborted"] === true
|
|
149
|
-
?
|
|
151
|
+
? m.interrupted
|
|
150
152
|
: details["timedOut"] === true
|
|
151
|
-
?
|
|
152
|
-
:
|
|
153
|
-
const parts = [head, duration, ...(total > 0 ? [
|
|
153
|
+
? m.timedOut
|
|
154
|
+
: m.exit(code);
|
|
155
|
+
const parts = [head, duration, ...(total > 0 ? [m.lines(total)] : [])];
|
|
154
156
|
const text = parts.join(" · ");
|
|
155
157
|
return isError || code !== 0 ? theme.fg("error", text) : parts.map(muted).join(sep);
|
|
156
158
|
}
|
|
157
159
|
if (isError)
|
|
158
|
-
return theme.fg("error", `${theme.glyphs.fail} ${lines[0] ??
|
|
160
|
+
return theme.fg("error", `${theme.glyphs.fail} ${lines[0] ?? m.failed}`);
|
|
159
161
|
switch (name) {
|
|
160
162
|
case "read": {
|
|
161
163
|
const mime = details["mimeType"];
|
|
162
164
|
if (typeof mime === "string")
|
|
163
|
-
return muted(
|
|
165
|
+
return muted(m.image(mime));
|
|
164
166
|
const first = num(details["firstLine"]);
|
|
165
167
|
const last = num(details["lastLine"]);
|
|
166
168
|
if (num(details["totalLines"]) === 0)
|
|
167
|
-
return muted(
|
|
169
|
+
return muted(m.emptyFile);
|
|
168
170
|
const n = first !== undefined && last !== undefined ? last - first + 1 : count;
|
|
169
|
-
return muted(
|
|
171
|
+
return muted(m.read(n));
|
|
170
172
|
}
|
|
171
173
|
case "edit": {
|
|
172
174
|
const rows = parseDiff(diffOf(result) ?? "");
|
|
@@ -174,7 +176,7 @@ export function resultSummary(input, theme) {
|
|
|
174
176
|
const del = rows.filter((r) => r.kind === "del").length;
|
|
175
177
|
const edits = record(input.args)["edits"];
|
|
176
178
|
const n = num(details["replacements"]) ?? (Array.isArray(edits) ? edits.length : 1);
|
|
177
|
-
return (muted(
|
|
179
|
+
return (muted(m.edits(n)) +
|
|
178
180
|
sep +
|
|
179
181
|
theme.fg("success", `+${add}`) +
|
|
180
182
|
" " +
|
|
@@ -183,23 +185,23 @@ export function resultSummary(input, theme) {
|
|
|
183
185
|
case "write": {
|
|
184
186
|
const content = record(input.args)["content"];
|
|
185
187
|
const n = typeof content === "string" ? cleanLines(content).length : 0;
|
|
186
|
-
return muted(
|
|
188
|
+
return muted(m.write(details["created"] === true, n));
|
|
187
189
|
}
|
|
188
190
|
case "grep": {
|
|
189
191
|
const matches = num(details["matches"]);
|
|
190
192
|
if (matches === 0)
|
|
191
|
-
return muted(
|
|
193
|
+
return muted(m.noMatch);
|
|
192
194
|
if (matches === undefined)
|
|
193
|
-
return muted(
|
|
194
|
-
return muted(
|
|
195
|
+
return muted(m.lines(count));
|
|
196
|
+
return muted(m.matches(matches, num(details["files"])));
|
|
195
197
|
}
|
|
196
198
|
case "glob": {
|
|
197
199
|
const n = num(details["count"]);
|
|
198
|
-
return muted(n === 0 ?
|
|
200
|
+
return muted(n === 0 ? m.noMatch : m.files(n ?? count));
|
|
199
201
|
}
|
|
200
202
|
case "codemode": {
|
|
201
203
|
const calls = num(details["toolCalls"]) ?? input.nestedCount ?? 0;
|
|
202
|
-
return muted(
|
|
204
|
+
return muted(m.codemode(calls, count));
|
|
203
205
|
}
|
|
204
206
|
case "task": {
|
|
205
207
|
const usage = record(details["usage"]);
|
|
@@ -210,9 +212,9 @@ export function resultSummary(input, theme) {
|
|
|
210
212
|
`${theme.glyphs.arrowUp}${formatTokens(input_)} ${theme.glyphs.arrowDown}${formatTokens(output)}`,
|
|
211
213
|
]
|
|
212
214
|
: [];
|
|
213
|
-
return muted([
|
|
215
|
+
return muted([m.done, duration, ...tokens].join(" · "));
|
|
214
216
|
}
|
|
215
217
|
default:
|
|
216
|
-
return muted(count === 0 ?
|
|
218
|
+
return muted(count === 0 ? m.done : m.outputLines(count));
|
|
217
219
|
}
|
|
218
220
|
}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* - 自定义渲染(`ToolDefinition.renderCall / renderResult`):标题摘要优先取 `renderCall` 第一行;成功的结果
|
|
21
21
|
* 正文优先用 `renderResult`;抛错或返回空时回到缺省显示;错误结果始终用缺省显示。
|
|
22
22
|
*/
|
|
23
|
+
import { msg } from "../../i18n/index.js";
|
|
23
24
|
import { formatElapsed, truncateToWidth, wrapTextWithAnsi, } from "../../tui.js";
|
|
24
25
|
import { contentText } from "./message-view.js";
|
|
25
26
|
import { subagentLine } from "./subagent-view.js";
|
|
@@ -159,7 +160,7 @@ export class ToolView {
|
|
|
159
160
|
const g = theme.glyphs;
|
|
160
161
|
const lead = " " + theme.fg("border", g.result) + " ";
|
|
161
162
|
if (this.state === "running" && this.awaiting) {
|
|
162
|
-
return truncateToWidth(lead + theme.fg("dim",
|
|
163
|
+
return truncateToWidth(lead + theme.fg("dim", msg().interactive.view.tool.awaiting(g.spinnerStatic)), width);
|
|
163
164
|
}
|
|
164
165
|
const sub = this.subagentState();
|
|
165
166
|
if (this.state === "running" && sub !== undefined) {
|
|
@@ -170,7 +171,8 @@ export class ToolView {
|
|
|
170
171
|
if (this.state === "running") {
|
|
171
172
|
const frame = this.options.spinner?.() ?? g.spinnerStatic;
|
|
172
173
|
const elapsed = formatElapsed(this.now() - this.startedAt);
|
|
173
|
-
const
|
|
174
|
+
const m = msg().interactive.view.tool;
|
|
175
|
+
const what = this.toolName === "task" ? m.subagentRunning(elapsed) : m.running(elapsed);
|
|
174
176
|
return truncateToWidth(lead + theme.fg("accent", frame) + " " + theme.fg("muted", what), width);
|
|
175
177
|
}
|
|
176
178
|
const result = this.result;
|
|
@@ -251,7 +253,7 @@ export class ToolView {
|
|
|
251
253
|
}
|
|
252
254
|
more(hidden) {
|
|
253
255
|
const { theme } = this.options;
|
|
254
|
-
return BODY + theme.fg("dim",
|
|
256
|
+
return (BODY + theme.fg("dim", msg().interactive.view.tool.moreLines(theme.glyphs.ellipsis, hidden)));
|
|
255
257
|
}
|
|
256
258
|
nestedLines(width) {
|
|
257
259
|
const { theme } = this.options;
|
|
@@ -269,7 +271,8 @@ export class ToolView {
|
|
|
269
271
|
const shown = this.nested.slice(-COLLAPSED_CHILDREN);
|
|
270
272
|
if (this.nested.length > shown.length) {
|
|
271
273
|
const hidden = this.nested.length - shown.length;
|
|
272
|
-
out.push(BODY +
|
|
274
|
+
out.push(BODY +
|
|
275
|
+
theme.fg("dim", msg().interactive.view.tool.earlierCalls(theme.glyphs.ellipsis, hidden)));
|
|
273
276
|
}
|
|
274
277
|
for (const child of shown) {
|
|
275
278
|
out.push(BODY + child.header(inner));
|