@armadra/agent 0.5.1 → 0.6.1
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 +203 -304
- package/CHANGELOG.zh-CN.md +462 -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/discovered-cache.d.ts +48 -0
- package/dist/ai/providers/discovered-cache.js +102 -0
- package/dist/ai/providers/enrich.js +2 -7
- package/dist/ai/providers/model-visibility.d.ts +33 -0
- package/dist/ai/providers/model-visibility.js +70 -0
- 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/registry.d.ts +2 -0
- package/dist/ai/providers/registry.js +6 -1
- 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 +35 -0
- package/dist/auth/chatgpt/cli.js +279 -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 +26532 -11045
- 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 +6 -0
- package/dist/cli/compose-providers.js +38 -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 +145 -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 +4 -0
- package/dist/cli/subcommands/models-discover.js +60 -21
- package/dist/cli/subcommands/models-enable.d.ts +13 -0
- package/dist/cli/subcommands/models-enable.js +145 -0
- package/dist/cli/subcommands/models.d.ts +3 -1
- package/dist/cli/subcommands/models.js +39 -24
- 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 +102 -69
- 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 +12 -4
- 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 +81 -0
- package/dist/config/settings-registry.js +185 -0
- package/dist/config/types-w5.d.ts +7 -0
- package/dist/config/types-w5.js +2 -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 +2209 -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 +189 -0
- package/dist/i18n/messages/auth.js +201 -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 +248 -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 +293 -0
- package/dist/i18n/messages/config-keys.js +296 -0
- package/dist/i18n/messages/config.d.ts +508 -0
- package/dist/i18n/messages/config.js +241 -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 +99 -0
- package/dist/i18n/messages/interactive-startup.js +100 -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 +489 -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 +233 -0
- package/dist/i18n/messages/panels.js +232 -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 +355 -0
- package/dist/i18n/messages/settings.js +343 -0
- package/dist/i18n/messages/subcommands-config.d.ts +113 -0
- package/dist/i18n/messages/subcommands-config.js +129 -0
- package/dist/i18n/messages/subcommands-models.d.ts +34 -0
- package/dist/i18n/messages/subcommands-models.js +34 -0
- package/dist/i18n/messages/subcommands.d.ts +576 -0
- package/dist/i18n/messages/subcommands.js +477 -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 +22 -1
- package/dist/modes/interactive/commands.js +100 -49
- 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 +21 -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/model-items.d.ts +45 -0
- package/dist/modes/interactive/model-items.js +134 -0
- package/dist/modes/interactive/model-picker.d.ts +57 -0
- package/dist/modes/interactive/model-picker.js +191 -0
- 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.d.ts +3 -9
- package/dist/modes/interactive/startup-ui.js +44 -88
- 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/select-list.d.ts +2 -0
- package/dist/tui/components/select-list.js +7 -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 +627 -0
- package/docs/en/rpc.md +361 -0
- package/docs/en/sessions.md +219 -0
- package/docs/en/tui.md +534 -0
- package/docs/host-api.md +18 -17
- package/docs/memory.md +172 -0
- package/docs/permissions.md +2 -2
- package/docs/providers.md +73 -1
- package/docs/rpc.md +31 -3
- package/docs/session-format.md +8 -2
- package/docs/sessions.md +29 -1
- package/docs/tui.md +140 -4
- package/package.json +8 -3
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - 着色:`✻` accent、标题粗体;键列 dim;模型 accent;已信任 success / 未信任 warning;Bypass 模式 warning;
|
|
8
8
|
* 按键提示 dim。路径过长时从左截断(`…/armadra-agent`)。宽度变化时按新宽重算是否去框。
|
|
9
9
|
*/
|
|
10
|
+
import { msg } from "../../i18n/index.js";
|
|
10
11
|
import { permissionModeLabel } from "../../permissions/modes.js";
|
|
11
12
|
import { Box, KeyValue, padToWidth, truncateToWidth, visibleWidth, } from "../../tui.js";
|
|
12
13
|
/** 画框的最小宽度;更窄时去框去键列。 */
|
|
@@ -58,7 +59,8 @@ export class StartupHeader {
|
|
|
58
59
|
}
|
|
59
60
|
trustText(withSource) {
|
|
60
61
|
const { trusted, trustSource } = this.info;
|
|
61
|
-
const
|
|
62
|
+
const m = msg().interactive.startup.header;
|
|
63
|
+
const text = `${trusted ? m.trusted : m.untrusted}${withSource ? m.trustSource(trustSource) : ""}`;
|
|
62
64
|
return this.theme.fg(trusted ? "success" : "warning", text);
|
|
63
65
|
}
|
|
64
66
|
loadedText() {
|
|
@@ -69,7 +71,7 @@ export class StartupHeader {
|
|
|
69
71
|
if (skills > 0)
|
|
70
72
|
parts.push(`${skills} Skill`);
|
|
71
73
|
if (prompts > 0)
|
|
72
|
-
parts.push(
|
|
74
|
+
parts.push(msg().interactive.startup.header.templates(prompts));
|
|
73
75
|
if (hooks > 0)
|
|
74
76
|
parts.push(`${hooks} Hook`);
|
|
75
77
|
return parts.length === 0 ? undefined : parts.join(" · ");
|
|
@@ -114,51 +116,48 @@ export class StartupHeader {
|
|
|
114
116
|
const loaded = this.loadedText();
|
|
115
117
|
if (loaded !== undefined)
|
|
116
118
|
lines.push(loaded);
|
|
119
|
+
const m = msg().interactive.startup.header;
|
|
117
120
|
if (info.host !== undefined)
|
|
118
|
-
lines.push(
|
|
121
|
+
lines.push(m.host(info.host));
|
|
119
122
|
if (info.warnings > 0)
|
|
120
|
-
lines.push(t.fg("warning",
|
|
121
|
-
lines.push(t.fg("dim",
|
|
123
|
+
lines.push(t.fg("warning", m.warnings(info.warnings)));
|
|
124
|
+
lines.push(t.fg("dim", m.hintCompact));
|
|
122
125
|
return lines.map((line) => truncateToWidth(line, width));
|
|
123
126
|
}
|
|
124
127
|
boxLines(width) {
|
|
125
128
|
const t = this.theme;
|
|
126
129
|
const sep = t.fg("dim", " · ");
|
|
127
130
|
const { info } = this;
|
|
131
|
+
const m = msg().interactive.startup.header;
|
|
128
132
|
const boxWidth = Math.min(width, HEADER_BOX_MAX_WIDTH);
|
|
129
|
-
|
|
130
|
-
const
|
|
133
|
+
// 键列至少 6 列(「已加载」的宽度),没有这一行时也对齐;英文键更宽时按最宽的键
|
|
134
|
+
const keyWidth = Math.max(6, ...[m.keyModel, m.keyDir, m.keyMode, m.keyLoaded, m.keyHost, m.keyWarnings].map((k) => visibleWidth(k)));
|
|
135
|
+
/** 框内文本宽:边框 2 + 内边距 2;键列 + 间隔 1。 */
|
|
136
|
+
const valueWidth = boxWidth - 4 - keyWidth - 1;
|
|
131
137
|
const trust = this.trustText(true);
|
|
132
138
|
const cwdRoom = Math.max(4, valueWidth - visibleWidth(trust) - 3);
|
|
133
139
|
const rows = [
|
|
134
|
-
{ key:
|
|
135
|
-
{ key:
|
|
140
|
+
{ key: m.keyModel, value: t.fg("accent", info.model) + sep + m.thinking(info.thinking) },
|
|
141
|
+
{ key: m.keyDir, value: truncateLeft(info.cwd, cwdRoom, t.glyphs.ellipsis) + sep + trust },
|
|
136
142
|
{
|
|
137
|
-
key:
|
|
138
|
-
value: [this.modeText(),
|
|
143
|
+
key: m.keyMode,
|
|
144
|
+
value: [this.modeText(), m.preset(info.preset), this.codemodeText()]
|
|
139
145
|
.filter((p) => p !== undefined)
|
|
140
146
|
.join(sep),
|
|
141
147
|
},
|
|
142
148
|
];
|
|
143
149
|
const loaded = this.loadedText();
|
|
144
150
|
if (loaded !== undefined)
|
|
145
|
-
rows.push({ key:
|
|
151
|
+
rows.push({ key: m.keyLoaded, value: loaded });
|
|
146
152
|
if (info.host !== undefined)
|
|
147
|
-
rows.push({ key:
|
|
153
|
+
rows.push({ key: m.keyHost, value: info.host });
|
|
148
154
|
if (info.warnings > 0) {
|
|
149
|
-
rows.push({ key:
|
|
155
|
+
rows.push({ key: m.keyWarnings, value: t.fg("warning", m.warningsValue(info.warnings)) });
|
|
150
156
|
}
|
|
151
|
-
|
|
152
|
-
const padded = rows.map((row) => ({ ...row, key: padToWidth(row.key, 6) }));
|
|
157
|
+
const padded = rows.map((row) => ({ ...row, key: padToWidth(row.key, keyWidth) }));
|
|
153
158
|
const kv = new KeyValue(padded, { theme: t, gap: 1, maxKeyRatio: 1 });
|
|
154
159
|
const body = {
|
|
155
|
-
render: (inner) => [
|
|
156
|
-
this.title(),
|
|
157
|
-
"",
|
|
158
|
-
...kv.render(inner),
|
|
159
|
-
"",
|
|
160
|
-
t.fg("dim", "/help 命令 · Shift+Tab 切模式 · Ctrl+O 展开工具输出"),
|
|
161
|
-
],
|
|
160
|
+
render: (inner) => [this.title(), "", ...kv.render(inner), "", t.fg("dim", m.hint)],
|
|
162
161
|
invalidate: () => kv.invalidate(),
|
|
163
162
|
};
|
|
164
163
|
return new Box(body, { theme: t }).render(boxWidth);
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
* 选择列表 / 输入框的 `TUI`;答完把问答收成一行再 `stop()`——不清屏,问答留在回滚里。
|
|
6
6
|
* 取消(Esc / Ctrl+C)按各回调的约定返回 undefined(bootstrap 据此给退出码)。
|
|
7
7
|
*
|
|
8
|
-
* `modelItems
|
|
8
|
+
* `modelItems`(model-items.ts)/ `sessionItems` 同时供交互模式里的选择器(pickers.ts)使用。启动选择器只列
|
|
9
|
+
* 已配置的模型,一个都没有时列全部。
|
|
9
10
|
*/
|
|
10
|
-
import type { Model, ProviderRegistryApi } from "../../ai/types.js";
|
|
11
11
|
import type { InteractiveUi } from "../../cli/deps.js";
|
|
12
12
|
import type { SessionListItem } from "../../session/types.js";
|
|
13
13
|
import { type Keybindings, type SelectItem, type Terminal, type Theme } from "../../tui.js";
|
|
14
|
+
export { modelDescription, modelItems } from "./model-items.js";
|
|
14
15
|
export interface StartupUiOptions {
|
|
15
16
|
/** 每次问答新建的终端;缺省 `new ProcessTerminal()`。 */
|
|
16
17
|
terminal?: () => Terminal;
|
|
@@ -19,13 +20,6 @@ export interface StartupUiOptions {
|
|
|
19
20
|
/** 会话列表的相对时间基准(测试注入)。 */
|
|
20
21
|
now?: () => number;
|
|
21
22
|
}
|
|
22
|
-
/** 选择器里模型的说明:名称(与 id 不同时)、上下文、`img`(收图片)。 */
|
|
23
|
-
export declare function modelDescription(model: Model): string | undefined;
|
|
24
|
-
/**
|
|
25
|
-
* 模型按「供应商 · 渠道」分组;有 key(或本地)的供应商排前,组标题标 key 状态。多渠道供应商的模型在
|
|
26
|
-
* 每个挂载的渠道下各出现一次,非首选渠道的值带 `@渠道`。
|
|
27
|
-
*/
|
|
28
|
-
export declare function modelItems(providers: ProviderRegistryApi): Promise<SelectItem[]>;
|
|
29
23
|
/** `刚刚 / 5 分钟前 / 3 小时前 / 2 天前 / 2026-09-01`。 */
|
|
30
24
|
export declare function relativeTime(iso: string, now: number): string;
|
|
31
25
|
/** 会话:标签 = 名字或首条提示,描述 = 相对时间 · 消息数。 */
|
|
@@ -5,11 +5,15 @@
|
|
|
5
5
|
* 选择列表 / 输入框的 `TUI`;答完把问答收成一行再 `stop()`——不清屏,问答留在回滚里。
|
|
6
6
|
* 取消(Esc / Ctrl+C)按各回调的约定返回 undefined(bootstrap 据此给退出码)。
|
|
7
7
|
*
|
|
8
|
-
* `modelItems
|
|
8
|
+
* `modelItems`(model-items.ts)/ `sessionItems` 同时供交互模式里的选择器(pickers.ts)使用。启动选择器只列
|
|
9
|
+
* 已配置的模型,一个都没有时列全部。
|
|
9
10
|
*/
|
|
11
|
+
import { msg } from "../../i18n/index.js";
|
|
10
12
|
import { existsSync, statSync } from "node:fs";
|
|
11
13
|
import { resolve } from "node:path";
|
|
12
14
|
import { Container, Editor, ProcessTerminal, SelectList, TUI, Text, createTheme, defaultKeybindings, detectCapabilities, } from "../../tui.js";
|
|
15
|
+
import { loadModelCatalog, catalogItems } from "./model-items.js";
|
|
16
|
+
export { modelDescription, modelItems } from "./model-items.js";
|
|
13
17
|
function resolveOptions(options) {
|
|
14
18
|
return {
|
|
15
19
|
terminal: options.terminal ?? (() => new ProcessTerminal()),
|
|
@@ -49,7 +53,7 @@ function askSelect(r, prompt) {
|
|
|
49
53
|
done(item);
|
|
50
54
|
},
|
|
51
55
|
onCancel: () => {
|
|
52
|
-
finish(
|
|
56
|
+
finish(msg().interactive.startup.ui.cancelled);
|
|
53
57
|
done(undefined);
|
|
54
58
|
},
|
|
55
59
|
});
|
|
@@ -57,10 +61,10 @@ function askSelect(r, prompt) {
|
|
|
57
61
|
list.selectValue(prompt.selected);
|
|
58
62
|
body.addChild(list);
|
|
59
63
|
body.addChild(new Text(r.theme.fg("dim", prompt.filterable === true
|
|
60
|
-
? "
|
|
64
|
+
? msg().interactive.startup.ui.hintFilter("↑↓")
|
|
61
65
|
: prompt.numberKeys === true
|
|
62
|
-
?
|
|
63
|
-
: "↑↓
|
|
66
|
+
? msg().interactive.startup.ui.hintNumbers("↑↓", prompt.items.length)
|
|
67
|
+
: msg().interactive.startup.ui.hint("↑↓"))));
|
|
64
68
|
tui.start();
|
|
65
69
|
tui.setFocus(list);
|
|
66
70
|
});
|
|
@@ -92,7 +96,7 @@ function askText(r, prompt) {
|
|
|
92
96
|
body.addChild(error);
|
|
93
97
|
tui.addInputListener((data) => {
|
|
94
98
|
if (r.keys.matches(data, "tui.select.cancel") && !editor.isCompletionOpen) {
|
|
95
|
-
finish(
|
|
99
|
+
finish(msg().interactive.startup.ui.cancelled);
|
|
96
100
|
done(undefined);
|
|
97
101
|
return true;
|
|
98
102
|
}
|
|
@@ -105,80 +109,23 @@ function askText(r, prompt) {
|
|
|
105
109
|
// ---------------------------------------------------------------------------
|
|
106
110
|
// 列表项(选择器共用)
|
|
107
111
|
// ---------------------------------------------------------------------------
|
|
108
|
-
/** 选择器里模型的说明:名称(与 id 不同时)、上下文、`img`(收图片)。 */
|
|
109
|
-
export function modelDescription(model) {
|
|
110
|
-
const ctx = model.contextWindow;
|
|
111
|
-
const parts = [
|
|
112
|
-
model.name !== "" && model.name !== model.id ? model.name : undefined,
|
|
113
|
-
ctx === undefined
|
|
114
|
-
? undefined
|
|
115
|
-
: ctx >= 1_000_000
|
|
116
|
-
? `${Math.round(ctx / 100_000) / 10}M`
|
|
117
|
-
: `${Math.round(ctx / 1000)}k`,
|
|
118
|
-
model.input.includes("image") ? "img" : undefined,
|
|
119
|
-
].filter((x) => x !== undefined);
|
|
120
|
-
return parts.length > 0 ? parts.join(" · ") : undefined;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* 模型按「供应商 · 渠道」分组;有 key(或本地)的供应商排前,组标题标 key 状态。多渠道供应商的模型在
|
|
124
|
-
* 每个挂载的渠道下各出现一次,非首选渠道的值带 `@渠道`。
|
|
125
|
-
*/
|
|
126
|
-
export async function modelItems(providers) {
|
|
127
|
-
const groups = [];
|
|
128
|
-
for (const provider of providers.list()) {
|
|
129
|
-
if (provider.models.length === 0)
|
|
130
|
-
continue;
|
|
131
|
-
let status;
|
|
132
|
-
let ready = true;
|
|
133
|
-
if (!provider.requiresApiKey)
|
|
134
|
-
status = "本地";
|
|
135
|
-
else {
|
|
136
|
-
const key = await providers.resolveApiKey(provider.id).catch(() => ({ apiKey: undefined }));
|
|
137
|
-
ready = key.apiKey !== undefined;
|
|
138
|
-
status = ready ? "key ✓" : "无 key";
|
|
139
|
-
}
|
|
140
|
-
const item = (model, group, channel) => {
|
|
141
|
-
const suffix = channel !== undefined && channel !== model.channel ? `@${channel}` : "";
|
|
142
|
-
const out = {
|
|
143
|
-
value: `${provider.id}/${model.id}${suffix}`,
|
|
144
|
-
label: `${model.id}${suffix}`,
|
|
145
|
-
group,
|
|
146
|
-
};
|
|
147
|
-
const description = modelDescription(model);
|
|
148
|
-
if (description !== undefined)
|
|
149
|
-
out.description = description;
|
|
150
|
-
return out;
|
|
151
|
-
};
|
|
152
|
-
if (provider.channels === undefined) {
|
|
153
|
-
const group = `${provider.id} · ${status}`;
|
|
154
|
-
groups.push({ ready, items: provider.models.map((model) => item(model, group)) });
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
for (const channel of provider.channels) {
|
|
158
|
-
const group = `${provider.id} · ${channel.name} · ${status}`;
|
|
159
|
-
const models = provider.models.filter((m) => m.channels?.includes(channel.name));
|
|
160
|
-
if (models.length > 0)
|
|
161
|
-
groups.push({ ready, items: models.map((model) => item(model, group, channel.name)) });
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return [...groups.filter((g) => g.ready), ...groups.filter((g) => !g.ready)].flatMap((g) => g.items);
|
|
165
|
-
}
|
|
166
112
|
/** `刚刚 / 5 分钟前 / 3 小时前 / 2 天前 / 2026-09-01`。 */
|
|
167
113
|
export function relativeTime(iso, now) {
|
|
168
114
|
const at = Date.parse(iso);
|
|
169
115
|
if (!Number.isFinite(at))
|
|
170
116
|
return "";
|
|
117
|
+
const m = msg().interactive.startup.ui;
|
|
171
118
|
const minutes = Math.floor((now - at) / 60_000);
|
|
172
119
|
if (minutes < 1)
|
|
173
|
-
return
|
|
120
|
+
return m.justNow;
|
|
174
121
|
if (minutes < 60)
|
|
175
|
-
return
|
|
122
|
+
return m.minutesAgo(minutes);
|
|
176
123
|
const hours = Math.floor(minutes / 60);
|
|
177
124
|
if (hours < 24)
|
|
178
|
-
return
|
|
125
|
+
return m.hoursAgo(hours);
|
|
179
126
|
const days = Math.floor(hours / 24);
|
|
180
127
|
if (days < 30)
|
|
181
|
-
return
|
|
128
|
+
return m.daysAgo(days);
|
|
182
129
|
return iso.slice(0, 10);
|
|
183
130
|
}
|
|
184
131
|
function oneLine(text, max = 60) {
|
|
@@ -192,18 +139,21 @@ export function sessionItems(items, now) {
|
|
|
192
139
|
.map((item) => ({
|
|
193
140
|
value: item.id,
|
|
194
141
|
label: oneLine(item.name ?? item.firstPrompt ?? item.id.slice(0, 8)),
|
|
195
|
-
description: `${relativeTime(item.modifiedAt, now)} · ${item.messageCount}
|
|
142
|
+
description: `${relativeTime(item.modifiedAt, now)} · ${msg().interactive.startup.ui.messages(item.messageCount)}`,
|
|
196
143
|
}));
|
|
197
144
|
}
|
|
198
145
|
// ---------------------------------------------------------------------------
|
|
199
146
|
// InteractiveUi
|
|
200
147
|
// ---------------------------------------------------------------------------
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
148
|
+
function trustChoices() {
|
|
149
|
+
const m = msg().interactive.startup.ui;
|
|
150
|
+
return [
|
|
151
|
+
{ value: "trust", label: m.trustRemember, answer: { trusted: true, remember: true } },
|
|
152
|
+
{ value: "once", label: m.trustOnce, answer: { trusted: true, remember: false } },
|
|
153
|
+
{ value: "skip", label: m.trustSkip, answer: { trusted: false, remember: false } },
|
|
154
|
+
{ value: "never", label: m.trustNever, answer: { trusted: false, remember: true } },
|
|
155
|
+
];
|
|
156
|
+
}
|
|
207
157
|
function isDirectory(path) {
|
|
208
158
|
try {
|
|
209
159
|
return statSync(path).isDirectory();
|
|
@@ -216,35 +166,40 @@ export function createStartupUi(options = {}) {
|
|
|
216
166
|
const r = resolveOptions(options);
|
|
217
167
|
return {
|
|
218
168
|
async promptTrust(cwd, resources) {
|
|
169
|
+
const m = msg().interactive.startup.ui;
|
|
170
|
+
const choices = trustChoices();
|
|
219
171
|
const shown = resources.slice(0, 6).map((p) => ` ${p}`);
|
|
220
172
|
if (resources.length > shown.length)
|
|
221
|
-
shown.push(
|
|
173
|
+
shown.push(m.moreResources(resources.length - shown.length));
|
|
222
174
|
const picked = await askSelect(r, {
|
|
223
|
-
title:
|
|
175
|
+
title: m.trustTitle,
|
|
224
176
|
lines: [cwd, ...shown],
|
|
225
|
-
items:
|
|
177
|
+
items: choices.map(({ value, label }) => ({ value, label })),
|
|
226
178
|
selected: "once",
|
|
227
179
|
numberKeys: true,
|
|
228
180
|
});
|
|
229
|
-
const choice =
|
|
181
|
+
const choice = choices.find((c) => c.value === picked?.value);
|
|
230
182
|
return choice?.answer ?? { trusted: false, remember: false };
|
|
231
183
|
},
|
|
232
184
|
async pickSession(items) {
|
|
233
185
|
if (items.length === 0)
|
|
234
186
|
return undefined;
|
|
235
187
|
const picked = await askSelect(r, {
|
|
236
|
-
title:
|
|
188
|
+
title: msg().interactive.startup.ui.resumeTitle,
|
|
237
189
|
items: sessionItems(items, r.now()),
|
|
238
190
|
filterable: true,
|
|
239
191
|
});
|
|
240
192
|
return picked?.value;
|
|
241
193
|
},
|
|
242
194
|
async pickModel(providers, reason) {
|
|
243
|
-
const
|
|
195
|
+
const catalog = await loadModelCatalog(providers);
|
|
196
|
+
let items = catalogItems(catalog, { hints: false });
|
|
197
|
+
if (items.length === 0)
|
|
198
|
+
items = catalogItems(catalog, { view: "all", hints: false });
|
|
244
199
|
if (items.length === 0)
|
|
245
200
|
return undefined;
|
|
246
201
|
const picked = await askSelect(r, {
|
|
247
|
-
title:
|
|
202
|
+
title: msg().interactive.startup.ui.modelTitle,
|
|
248
203
|
lines: [reason],
|
|
249
204
|
items,
|
|
250
205
|
filterable: true,
|
|
@@ -252,18 +207,19 @@ export function createStartupUi(options = {}) {
|
|
|
252
207
|
return picked?.value;
|
|
253
208
|
},
|
|
254
209
|
askCwd(missing) {
|
|
210
|
+
const m = msg().interactive.startup.ui;
|
|
255
211
|
return askText(r, {
|
|
256
|
-
title:
|
|
257
|
-
lines: [missing,
|
|
258
|
-
placeholder:
|
|
212
|
+
title: m.cwdTitle,
|
|
213
|
+
lines: [missing, m.cwdPrompt],
|
|
214
|
+
placeholder: m.cwdPlaceholder,
|
|
259
215
|
validate: (text) => {
|
|
260
216
|
if (text === "")
|
|
261
|
-
return
|
|
217
|
+
return m.cwdEmpty;
|
|
262
218
|
const abs = resolve(text);
|
|
263
219
|
if (!existsSync(abs))
|
|
264
|
-
return
|
|
220
|
+
return m.cwdMissing(abs);
|
|
265
221
|
if (!isDirectory(abs))
|
|
266
|
-
return
|
|
222
|
+
return m.cwdNotDir(abs);
|
|
267
223
|
return undefined;
|
|
268
224
|
},
|
|
269
225
|
});
|
|
@@ -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;
|