@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
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/config` controller (docs/wave6-plan.md §6.3, D24-D26). [W6-S]
|
|
3
|
+
*
|
|
4
|
+
* - `open("")` shows the panel (config-panel.ts); `open("key=value")` / `open("key value")` sets one key
|
|
5
|
+
* in the user config without the panel (same path as `ama config set`).
|
|
6
|
+
* - Every change is written at once (config/edit.ts) and then applied: keys of the "now" tier go to the
|
|
7
|
+
* running session / view (`applySetting`), and `runtime.replaceConfig()` hands the re-merged config to
|
|
8
|
+
* `/new`. `defaultModel`, `thinkingLevel` and `permission.mode` also switch the current session.
|
|
9
|
+
* - `permission.mode: full-auto` in the user config always asks the Bypass confirmation first.
|
|
10
|
+
* - The first change of a cache-prefix key in a conversation that already has replies shows a notice once
|
|
11
|
+
* per panel; closing the panel posts one summary (`from → to (scope)`, plus restart / new-session lists).
|
|
12
|
+
* - `configCommand()` is the line mode `/config` (`CommandContext.extra.config`).
|
|
13
|
+
*/
|
|
14
|
+
import { AgentSessionImpl } from "../../agent/session.js";
|
|
15
|
+
import { currentSession } from "../../cli/compose-session.js";
|
|
16
|
+
import { hideFakeProvider } from "../../cli/fake-visibility.js";
|
|
17
|
+
import { tildePath } from "../../cli/startup-screen.js";
|
|
18
|
+
import { ConfigEditError, formatSettingValue, getConfigValue, parseValue, readSnapshot, setConfigValue, } from "../../config/edit.js";
|
|
19
|
+
import { loadProfile } from "../../config/profile.js";
|
|
20
|
+
import { settingSpec, settingsRegistry } from "../../config/settings-registry.js";
|
|
21
|
+
import { msg } from "../../i18n/index.js";
|
|
22
|
+
import { ConfigPanel, blockedReason } from "./config-panel.js";
|
|
23
|
+
import { bypassChoiceSpec, openChoice } from "./confirm-dialog.js";
|
|
24
|
+
import { modelItems, openPicker, permissionItems, thinkingItems, } from "./pickers.js";
|
|
25
|
+
/** Apply one "now" key to the running session / view; returns false when nothing applies. */
|
|
26
|
+
export async function applySetting(key, value, targets) {
|
|
27
|
+
const session = targets.session();
|
|
28
|
+
const impl = session instanceof AgentSessionImpl ? session : undefined;
|
|
29
|
+
switch (key) {
|
|
30
|
+
case "ui.markdown":
|
|
31
|
+
targets.view?.setOptions({ markdown: value !== false });
|
|
32
|
+
break;
|
|
33
|
+
case "ui.showThinking":
|
|
34
|
+
targets.view?.setOptions({ showThinking: (value ?? "collapsed") });
|
|
35
|
+
break;
|
|
36
|
+
case "ui.compact":
|
|
37
|
+
targets.view?.setOptions({ compact: value === true });
|
|
38
|
+
break;
|
|
39
|
+
case "ui.animation":
|
|
40
|
+
targets.loader?.setAnimation(value !== false);
|
|
41
|
+
break;
|
|
42
|
+
case "ui.statusLine":
|
|
43
|
+
targets.area?.setLayout((value ?? "full"));
|
|
44
|
+
break;
|
|
45
|
+
case "thinkingLevel":
|
|
46
|
+
session.setThinkingLevel((value ?? "medium"));
|
|
47
|
+
return true;
|
|
48
|
+
case "permission.mode":
|
|
49
|
+
session.setPermissionMode((value ?? "default"));
|
|
50
|
+
return true;
|
|
51
|
+
case "defaultModel":
|
|
52
|
+
if (typeof value !== "string")
|
|
53
|
+
return false;
|
|
54
|
+
await session.setModel(value);
|
|
55
|
+
return true;
|
|
56
|
+
case "compaction.enabled":
|
|
57
|
+
impl?.setAutoCompaction(value !== false);
|
|
58
|
+
return impl !== undefined;
|
|
59
|
+
case "retry.enabled":
|
|
60
|
+
impl?.setAutoRetry(value !== false);
|
|
61
|
+
return impl !== undefined;
|
|
62
|
+
case "cache.warming":
|
|
63
|
+
if (typeof value === "string")
|
|
64
|
+
impl?.cache.setWarming(value);
|
|
65
|
+
return impl !== undefined;
|
|
66
|
+
default:
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
targets.redraw?.();
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
/** Layer inputs of this process: user / project files, the profile and the command line flags. */
|
|
73
|
+
export function layerInputFor(runtime, context) {
|
|
74
|
+
const { args, io } = context;
|
|
75
|
+
const cli = {};
|
|
76
|
+
if (args.thinking !== undefined)
|
|
77
|
+
cli.thinkingLevel = args.thinking;
|
|
78
|
+
if (args.permissionMode !== undefined)
|
|
79
|
+
cli.permissionMode = args.permissionMode;
|
|
80
|
+
if (args.allow.length > 0)
|
|
81
|
+
cli.allow = args.allow;
|
|
82
|
+
if (args.deny.length > 0)
|
|
83
|
+
cli.deny = args.deny;
|
|
84
|
+
if (args.quietStartup !== undefined)
|
|
85
|
+
cli.quietStartup = args.quietStartup;
|
|
86
|
+
if (args.tuiMode !== undefined)
|
|
87
|
+
cli.tuiMode = args.tuiMode;
|
|
88
|
+
if (args.toolsPreset !== undefined)
|
|
89
|
+
cli.toolsPreset = args.toolsPreset;
|
|
90
|
+
if (args.codemode !== undefined)
|
|
91
|
+
cli.codemode = args.codemode;
|
|
92
|
+
if (args.memory !== undefined)
|
|
93
|
+
cli.memory = args.memory;
|
|
94
|
+
const input = {
|
|
95
|
+
configDir: runtime.paths.configDir,
|
|
96
|
+
cwd: runtime.paths.cwd,
|
|
97
|
+
env: io.env,
|
|
98
|
+
cli,
|
|
99
|
+
};
|
|
100
|
+
if (args.profile !== undefined) {
|
|
101
|
+
input.profile = { config: loadProfile(args.profile, io.cwd).config };
|
|
102
|
+
input.hasProfile = true;
|
|
103
|
+
}
|
|
104
|
+
return input;
|
|
105
|
+
}
|
|
106
|
+
/** `key=value` / `key value` → [key, raw]. */
|
|
107
|
+
export function splitAssignment(args) {
|
|
108
|
+
const text = args.trim();
|
|
109
|
+
const eq = text.indexOf("=");
|
|
110
|
+
const space = text.search(/\s/);
|
|
111
|
+
const at = eq !== -1 && (space === -1 || eq < space) ? eq : space;
|
|
112
|
+
if (at <= 0)
|
|
113
|
+
return undefined;
|
|
114
|
+
return [text.slice(0, at).trim(), text.slice(at + 1).trim()];
|
|
115
|
+
}
|
|
116
|
+
const PROJECT_FILE = ".ama/config.json";
|
|
117
|
+
const labelOf = (key) => msg().settings.labels[key] ?? key;
|
|
118
|
+
const hasReplies = (session) => session.messages.some((m) => m.role === "assistant");
|
|
119
|
+
export class ConfigUi {
|
|
120
|
+
deps;
|
|
121
|
+
panel;
|
|
122
|
+
handle;
|
|
123
|
+
changes = new Map();
|
|
124
|
+
prefixNoticeShown = false;
|
|
125
|
+
constructor(deps) {
|
|
126
|
+
this.deps = deps;
|
|
127
|
+
}
|
|
128
|
+
input() {
|
|
129
|
+
return layerInputFor(this.deps.runtime, this.deps.context);
|
|
130
|
+
}
|
|
131
|
+
/** `/config [key=value]`. */
|
|
132
|
+
async open(args) {
|
|
133
|
+
if (args.trim() !== "")
|
|
134
|
+
return this.direct(args);
|
|
135
|
+
if (this.panel !== undefined)
|
|
136
|
+
return;
|
|
137
|
+
const snapshot = readSnapshot(this.input());
|
|
138
|
+
const home = this.deps.home;
|
|
139
|
+
this.changes = new Map();
|
|
140
|
+
this.prefixNoticeShown = false;
|
|
141
|
+
const panel = new ConfigPanel(snapshot, {
|
|
142
|
+
theme: this.deps.theme,
|
|
143
|
+
...(this.deps.keybindings !== undefined ? { keybindings: this.deps.keybindings } : {}),
|
|
144
|
+
rows: () => this.deps.rows(),
|
|
145
|
+
// project file is always <cwd>/.ama/config.json; forward slashes on every platform
|
|
146
|
+
paths: {
|
|
147
|
+
user: tildePath(snapshot.userPath, home).replace(/\\/g, "/"),
|
|
148
|
+
project: PROJECT_FILE,
|
|
149
|
+
},
|
|
150
|
+
embedded: this.input().hasProfile === true,
|
|
151
|
+
activate: (key, scope) => this.activate(key, scope),
|
|
152
|
+
unset: (key, scope) => this.write(key, undefined, scope).then(() => undefined),
|
|
153
|
+
commit: (key, text, scope) => this.commitText(key, text, scope),
|
|
154
|
+
close: () => this.close(),
|
|
155
|
+
requestRender: () => this.deps.render(),
|
|
156
|
+
});
|
|
157
|
+
this.panel = panel;
|
|
158
|
+
this.handle = this.deps.showOverlay(panel, { anchor: "bottom" });
|
|
159
|
+
this.deps.render();
|
|
160
|
+
}
|
|
161
|
+
close() {
|
|
162
|
+
this.handle?.hide();
|
|
163
|
+
this.handle = undefined;
|
|
164
|
+
this.panel = undefined;
|
|
165
|
+
const summary = this.summary();
|
|
166
|
+
if (summary !== undefined)
|
|
167
|
+
this.deps.notice("info", summary);
|
|
168
|
+
this.deps.render();
|
|
169
|
+
}
|
|
170
|
+
/** Closing summary (undefined when nothing changed). */
|
|
171
|
+
summary() {
|
|
172
|
+
const s = msg().settings;
|
|
173
|
+
const changed = [...this.changes.values()].filter((c) => c.from !== c.to);
|
|
174
|
+
if (changed.length === 0)
|
|
175
|
+
return undefined;
|
|
176
|
+
const lines = [s.summaryTitle];
|
|
177
|
+
for (const c of changed)
|
|
178
|
+
lines.push(` ${s.summaryLine(labelOf(c.key), c.from, c.to, s.scope[c.scope])}`);
|
|
179
|
+
const tier = (apply) => changed
|
|
180
|
+
.filter((c) => c.spec?.apply === apply)
|
|
181
|
+
.map((c) => labelOf(c.key))
|
|
182
|
+
.join(", ");
|
|
183
|
+
if (tier("restart") !== "")
|
|
184
|
+
lines.push(s.summaryRestart(tier("restart")));
|
|
185
|
+
if (tier("nextSession") !== "")
|
|
186
|
+
lines.push(s.summaryNextSession(tier("nextSession")));
|
|
187
|
+
return lines.join("\n");
|
|
188
|
+
}
|
|
189
|
+
async activate(key, scope) {
|
|
190
|
+
const panel = this.panel;
|
|
191
|
+
const spec = settingSpec(key);
|
|
192
|
+
if (panel === undefined || spec === undefined)
|
|
193
|
+
return;
|
|
194
|
+
const current = getConfigValue(readSnapshot(this.input()), key);
|
|
195
|
+
const blocked = blockedReason(spec, current, scope);
|
|
196
|
+
if (blocked !== undefined)
|
|
197
|
+
return panel.setNotice(blocked, "warning");
|
|
198
|
+
const value = current.value;
|
|
199
|
+
switch (spec.kind) {
|
|
200
|
+
case "bool":
|
|
201
|
+
await this.write(key, value !== true, scope);
|
|
202
|
+
return;
|
|
203
|
+
case "enum": {
|
|
204
|
+
const options = spec.options ?? [];
|
|
205
|
+
if (options.length <= 4) {
|
|
206
|
+
const next = options[(options.indexOf(String(value)) + 1) % options.length];
|
|
207
|
+
await this.write(key, next, scope);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const picked = await this.pick(spec, value);
|
|
211
|
+
if (picked !== undefined)
|
|
212
|
+
await this.write(key, picked === "" ? undefined : picked, scope);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
case "model": {
|
|
216
|
+
const picked = await this.pick(spec, value);
|
|
217
|
+
if (picked !== undefined)
|
|
218
|
+
await this.write(key, picked === "" ? undefined : picked, scope);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
default:
|
|
222
|
+
panel.startEdit(key, value === undefined ? "" : formatSettingValue(value));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async pick(spec, value) {
|
|
226
|
+
const s = msg().settings;
|
|
227
|
+
const current = typeof value === "string" ? value : undefined;
|
|
228
|
+
let items;
|
|
229
|
+
if (spec.key === "permission.mode")
|
|
230
|
+
items = permissionItems((current ?? "default"));
|
|
231
|
+
else if (spec.key.endsWith("thinkingLevel"))
|
|
232
|
+
items = thinkingItems(true);
|
|
233
|
+
else if (spec.kind === "model")
|
|
234
|
+
items = [
|
|
235
|
+
...(await modelItems(hideFakeProvider(this.deps.runtime.providers, this.deps.context.io.env), { current, enabled: this.deps.runtime.config.models?.enabled, hints: false })),
|
|
236
|
+
{ value: "", label: s.defaultChoice },
|
|
237
|
+
];
|
|
238
|
+
else
|
|
239
|
+
items = (spec.options ?? []).map((o) => ({ value: o, label: o }));
|
|
240
|
+
const picked = await openPicker(this.deps, {
|
|
241
|
+
title: s.pickTitle(labelOf(spec.key)),
|
|
242
|
+
items,
|
|
243
|
+
filterable: spec.kind === "model",
|
|
244
|
+
...(current !== undefined ? { selected: current, currentValue: current } : {}),
|
|
245
|
+
...(spec.key === "permission.mode" ? { stacked: true } : {}),
|
|
246
|
+
});
|
|
247
|
+
return picked?.value;
|
|
248
|
+
}
|
|
249
|
+
async commitText(key, text, scope) {
|
|
250
|
+
try {
|
|
251
|
+
await this.write(key, parseValue(key, text), scope, true);
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
return error instanceof Error ? error.message : String(error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Write one key and apply it. Errors become panel notices (or are rethrown with `rethrow`, for the
|
|
260
|
+
* inline editor). Returns the edit result, undefined when refused / cancelled.
|
|
261
|
+
*/
|
|
262
|
+
async write(key, value, scope, rethrow = false) {
|
|
263
|
+
const s = msg().settings;
|
|
264
|
+
if (key === "permission.mode" && value === "full-auto" && scope === "user") {
|
|
265
|
+
const spec = bypassChoiceSpec(this.deps.theme);
|
|
266
|
+
const body = [...spec.body, this.deps.theme.fg("warning", s.bypassPersist)];
|
|
267
|
+
if ((await openChoice(this.deps, { ...spec, body })) !== 0)
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
let result;
|
|
271
|
+
try {
|
|
272
|
+
result = setConfigValue({ ...this.input(), scope, key, value });
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
if (rethrow)
|
|
276
|
+
throw error;
|
|
277
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
278
|
+
if (this.panel !== undefined)
|
|
279
|
+
this.panel.setNotice(text, "error");
|
|
280
|
+
else
|
|
281
|
+
this.deps.notice("error", text);
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
await this.afterWrite(result);
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
async afterWrite(result) {
|
|
288
|
+
const s = msg().settings;
|
|
289
|
+
const spec = settingSpec(result.key);
|
|
290
|
+
const from = formatSettingValue(result.before.value);
|
|
291
|
+
const to = formatSettingValue(result.after.value);
|
|
292
|
+
const previous = this.changes.get(result.key);
|
|
293
|
+
this.changes.set(result.key, {
|
|
294
|
+
key: result.key,
|
|
295
|
+
from: previous?.from ?? from,
|
|
296
|
+
to,
|
|
297
|
+
scope: result.scope,
|
|
298
|
+
spec,
|
|
299
|
+
});
|
|
300
|
+
this.deps.runtime.replaceConfig?.(result.snapshot.config);
|
|
301
|
+
let warning;
|
|
302
|
+
if (result.apply === "now" && result.before.value !== result.after.value)
|
|
303
|
+
await applySetting(result.key, result.after.value, this.deps).catch((error) => {
|
|
304
|
+
warning = error instanceof Error ? error.message : String(error);
|
|
305
|
+
});
|
|
306
|
+
if (result.overriddenBy !== undefined)
|
|
307
|
+
warning ??= s.stillOverridden(result.key, result.after.envName ?? result.overriddenBy);
|
|
308
|
+
if (result.prefixChanged && !this.prefixNoticeShown && hasReplies(this.deps.session())) {
|
|
309
|
+
this.prefixNoticeShown = true;
|
|
310
|
+
warning ??= s.prefixNotice;
|
|
311
|
+
}
|
|
312
|
+
if (this.panel !== undefined) {
|
|
313
|
+
this.panel.refresh(result.snapshot);
|
|
314
|
+
this.panel.setNotice(warning, "warning");
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
const line = s.setDone(result.key, to, s.scope[result.scope]);
|
|
318
|
+
this.deps.notice(warning === undefined ? "info" : "warn", warning === undefined ? line : `${line}\n${warning}`);
|
|
319
|
+
}
|
|
320
|
+
this.deps.render();
|
|
321
|
+
}
|
|
322
|
+
/** `/config key=value`: user scope, no panel. */
|
|
323
|
+
async direct(args) {
|
|
324
|
+
const s = msg().settings;
|
|
325
|
+
const parts = splitAssignment(args);
|
|
326
|
+
if (parts === undefined || parts[1] === "")
|
|
327
|
+
return this.deps.notice("warn", s.slashUsage);
|
|
328
|
+
try {
|
|
329
|
+
const value = parseValue(parts[0], parts[1]);
|
|
330
|
+
await this.write(parts[0], value, "user", true);
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
334
|
+
this.deps.notice(error instanceof ConfigEditError ? "warn" : "error", text);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/** Line mode `/config`: no args lists the settings, `key=value` sets one (user scope). */
|
|
339
|
+
export function configCommand(runtime, context) {
|
|
340
|
+
return async (args, ctx) => {
|
|
341
|
+
const s = msg().settings;
|
|
342
|
+
const input = layerInputFor(runtime, context);
|
|
343
|
+
if (args.trim() === "") {
|
|
344
|
+
const snapshot = readSnapshot(input);
|
|
345
|
+
const lines = settingsRegistry().map((spec) => {
|
|
346
|
+
const value = getConfigValue(snapshot, spec.key);
|
|
347
|
+
return ` ${spec.key} = ${formatSettingValue(value.value)} ${value.envName ?? value.source}`;
|
|
348
|
+
});
|
|
349
|
+
return { kind: "handled", message: [s.cli.listHeader, ...lines].join("\n") };
|
|
350
|
+
}
|
|
351
|
+
const parts = splitAssignment(args);
|
|
352
|
+
if (parts === undefined || parts[1] === "")
|
|
353
|
+
return { kind: "handled", message: s.slashUsage };
|
|
354
|
+
try {
|
|
355
|
+
const value = parseValue(parts[0], parts[1]);
|
|
356
|
+
if (parts[0] === "permission.mode" && value === "full-auto") {
|
|
357
|
+
const confirmed = ctx.confirmPermissionMode === undefined
|
|
358
|
+
? false
|
|
359
|
+
: await ctx.confirmPermissionMode("full-auto");
|
|
360
|
+
if (!confirmed)
|
|
361
|
+
return { kind: "handled", message: s.cli.needYes };
|
|
362
|
+
}
|
|
363
|
+
const result = setConfigValue({ ...input, scope: "user", key: parts[0], value });
|
|
364
|
+
runtime.replaceConfig?.(result.snapshot.config);
|
|
365
|
+
if (result.apply === "now" && result.before.value !== result.after.value)
|
|
366
|
+
await applySetting(result.key, result.after.value, { session: () => ctx.session() });
|
|
367
|
+
const lines = [s.setDone(result.key, formatSettingValue(result.after.value), s.scope.user)];
|
|
368
|
+
if (result.overriddenBy !== undefined)
|
|
369
|
+
lines.push(s.stillOverridden(result.key, result.after.envName ?? result.overriddenBy));
|
|
370
|
+
return { kind: "handled", message: lines.join("\n") };
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
if (error instanceof ConfigEditError)
|
|
374
|
+
return { kind: "handled", message: error.message };
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/** Wiring for interactive-mode.ts (one line there): the session follows `/new` `/resume` `/fork`. */
|
|
380
|
+
export function configUiFor(host, parts) {
|
|
381
|
+
const { runtime, context, tui } = parts;
|
|
382
|
+
const env = context.io.env;
|
|
383
|
+
const home = env["HOME"] ?? env["USERPROFILE"];
|
|
384
|
+
return new ConfigUi({
|
|
385
|
+
...host,
|
|
386
|
+
runtime,
|
|
387
|
+
context,
|
|
388
|
+
view: parts.view,
|
|
389
|
+
loader: parts.loader,
|
|
390
|
+
area: parts.area,
|
|
391
|
+
session: () => currentSession(runtime),
|
|
392
|
+
notice: parts.notice,
|
|
393
|
+
render: () => tui.requestRender(),
|
|
394
|
+
redraw: () => tui.forceFullRedraw(),
|
|
395
|
+
...(home !== undefined ? { home } : {}),
|
|
396
|
+
});
|
|
397
|
+
}
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*
|
|
9
9
|
* 用途:进入 Bypass permissions 前的确认(`confirmBypass`,permissions/bypass.ts)。
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { msg } from "../../i18n/index.js";
|
|
12
|
+
import { BYPASS_DEFAULT_CHOICE, bypassChoices, bypassConfirmTitle, bypassRiskLines, } from "../../permissions/bypass.js";
|
|
12
13
|
import { Box, defaultKeybindings, matchesKey, padToWidth, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "../../tui.js";
|
|
13
14
|
/** 宽度低于它(Box 外宽)时用紧凑布局。 */
|
|
14
15
|
const COMPACT_WIDTH = 56;
|
|
@@ -64,9 +65,7 @@ export class ChoiceDialog {
|
|
|
64
65
|
const g = theme.glyphs;
|
|
65
66
|
const arrows = g.arrowUp + g.arrowDown;
|
|
66
67
|
const n = this.spec.options.length;
|
|
67
|
-
lines.push(theme.fg("dim", compact
|
|
68
|
-
? `${arrows} Enter · 1-${n} · Esc`
|
|
69
|
-
: `${arrows} 选择 · Enter 确认 · 1-${n} 直接选 · Esc 取消`));
|
|
68
|
+
lines.push(theme.fg("dim", compact ? `${arrows} Enter · 1-${n} · Esc` : msg().approval.choiceHint(arrows, n)));
|
|
70
69
|
return lines.map((l) => truncateToWidth(l, width));
|
|
71
70
|
}
|
|
72
71
|
optionLines(width, compact) {
|
|
@@ -108,9 +107,9 @@ export function openChoice(host, spec) {
|
|
|
108
107
|
/** Bypass 确认框的内容(缺省选中「取消」,边框 warning)。 */
|
|
109
108
|
export function bypassChoiceSpec(theme) {
|
|
110
109
|
return {
|
|
111
|
-
title:
|
|
112
|
-
body:
|
|
113
|
-
options:
|
|
110
|
+
title: bypassConfirmTitle(),
|
|
111
|
+
body: bypassRiskLines().map((line, i) => (i === 0 ? theme.fg("warning", line) : line)),
|
|
112
|
+
options: bypassChoices(),
|
|
114
113
|
selected: BYPASS_DEFAULT_CHOICE,
|
|
115
114
|
borderColor: "warning",
|
|
116
115
|
};
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* 合并成一条「已省略 N 张早期图片以符合请求上限」,N 按占位文本数;
|
|
6
6
|
* - W5-H1:`compaction_end.error` 的「compaction did not shrink」换成中文说明(其余错误原样)。
|
|
7
7
|
*/
|
|
8
|
+
import { msg } from "../../i18n/index.js";
|
|
8
9
|
import { IMAGE_OMITTED_FOR_BUDGET, IMAGE_OMITTED_TOO_LARGE, } from "../../compaction/image-budget.js";
|
|
9
10
|
/** `compaction_end.error` 的显示文本。 */
|
|
10
11
|
export function compactionErrorText(error) {
|
|
11
12
|
if (/compaction did not shrink/i.test(error)) {
|
|
12
|
-
return
|
|
13
|
+
return msg().interactive.events.compactionNoShrink;
|
|
13
14
|
}
|
|
14
15
|
return error;
|
|
15
16
|
}
|
|
@@ -43,7 +44,7 @@ export class ImageBudgetNotices {
|
|
|
43
44
|
const n = this.pending;
|
|
44
45
|
this.pending = 0;
|
|
45
46
|
this.scheduled = false;
|
|
46
|
-
this.notify(
|
|
47
|
+
this.notify(msg().interactive.events.imagesOmitted(n));
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -54,26 +55,27 @@ export class ImageBudgetNotices {
|
|
|
54
55
|
export const LIMIT_WARNING = "limit_reached";
|
|
55
56
|
/** `limit_reached`:回合 / 费用到限(每次运行每类一次)。 */
|
|
56
57
|
export function limitReachedText(event) {
|
|
58
|
+
const m = msg().interactive.events;
|
|
57
59
|
if (event.kind === "turns")
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
return `已到费用上限 $${event.limit.toFixed(2)}(本次运行已用 ${spent}),本次运行停止;发新消息继续(--max-cost / limits.maxCostUsd)`;
|
|
60
|
+
return m.limitTurns(event.limit);
|
|
61
|
+
return m.limitCost(`$${event.limit.toFixed(2)}`, `$${event.value.toFixed(2)}`);
|
|
61
62
|
}
|
|
62
63
|
/** `model_fallback`:主模型失败后改用回退模型重试一次。 */
|
|
63
64
|
export function modelFallbackText(event) {
|
|
64
65
|
const ref = (m) => `${m.provider}/${m.id}`;
|
|
65
|
-
return
|
|
66
|
+
return msg().interactive.events.modelFallback(ref(event.from), event.reason, ref(event.to));
|
|
66
67
|
}
|
|
67
68
|
/** `background_job`:后台命令启动 / 退出 / 停止。 */
|
|
68
69
|
export function backgroundJobText(event) {
|
|
69
70
|
const command = event.command.replace(/\s+/g, " ").trim();
|
|
70
71
|
const short = command.length > 60 ? `${command.slice(0, 59)}…` : command;
|
|
72
|
+
const m = msg().interactive.events;
|
|
71
73
|
switch (event.phase) {
|
|
72
74
|
case "started":
|
|
73
|
-
return
|
|
75
|
+
return m.backgroundStarted(event.jobId, short);
|
|
74
76
|
case "exited":
|
|
75
|
-
return
|
|
77
|
+
return m.backgroundExited(event.jobId, String(event.exitCode ?? "?"), short);
|
|
76
78
|
case "stopped":
|
|
77
|
-
return
|
|
79
|
+
return m.backgroundStopped(event.jobId, short);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -24,7 +24,7 @@ import type { ModeContext } from "../../cli/deps.js";
|
|
|
24
24
|
import type { Runtime } from "../../cli/runtime.js";
|
|
25
25
|
import type { StatusLineMode } from "../../config/types.js";
|
|
26
26
|
import type { ClipboardDeps } from "../../tools/clipboard-image.js";
|
|
27
|
-
import { Editor,
|
|
27
|
+
import { Editor, TUI, type Keybindings, type Terminal, type Theme } from "../../tui.js";
|
|
28
28
|
import { MessageView } from "./message-view.js";
|
|
29
29
|
import { StatusArea } from "./status-area.js";
|
|
30
30
|
import type { StatusBar } from "./status-bar.js";
|
|
@@ -25,42 +25,33 @@ import { AgentSessionImpl } from "../../agent/session.js";
|
|
|
25
25
|
import { taskRegistryView } from "../../agent/subagent-registry.js";
|
|
26
26
|
import { currentSession, switchSession } from "../../cli/compose-session.js";
|
|
27
27
|
import { startupInfo, startupScreenLevel, tildePath } from "../../cli/startup-screen.js";
|
|
28
|
-
import { KEYBINDINGS_FILE } from "../../config/paths.js";
|
|
29
28
|
import { AmaError, isAmaError } from "../../errors.js";
|
|
30
|
-
import {
|
|
29
|
+
import { msg } from "../../i18n/index.js";
|
|
30
|
+
import { Container, Editor, Loader, Spacer, TUI, Text, createTheme, detectCapabilities, resolveAscii, resolveThemeName, } from "../../tui.js";
|
|
31
31
|
import { BYPASS_MODE, createBypassGate } from "../../permissions/bypass.js";
|
|
32
32
|
import { onTerminationSignals } from "../shared.js";
|
|
33
|
-
import { AgentUi } from "./agent-ui.js";
|
|
33
|
+
import { AgentUi, agentCommandHooks } from "./agent-ui.js";
|
|
34
34
|
import { ApprovalDialogBroker, approvalOutcomeText } from "./approval-dialog.js";
|
|
35
35
|
import { mergingBroker } from "./approval-merge.js";
|
|
36
36
|
import { ALL_COMMANDS, runInteractiveCommand } from "./commands.js";
|
|
37
|
+
import { memoryPanelFor } from "./memory-panel.js";
|
|
37
38
|
import { InteractiveCompletion } from "./completion.js";
|
|
38
39
|
import { confirmBypass } from "./confirm-dialog.js";
|
|
40
|
+
import { configUiFor } from "./config-ui.js";
|
|
39
41
|
import { createKeyDispatch } from "./key-dispatch.js";
|
|
40
42
|
import { MessageView, exitSummaryLines } from "./message-view.js";
|
|
41
43
|
import { openPicker } from "./pickers.js";
|
|
44
|
+
import { modelPickerFor } from "./model-picker.js";
|
|
42
45
|
import { createRewindFlow } from "./rewind-flow.js";
|
|
46
|
+
import { openTraceView } from "./trace-view.js";
|
|
43
47
|
import { StartupHeader } from "./startup-header.js";
|
|
44
48
|
import { QueueView, RunIndicator } from "./run-indicator.js";
|
|
45
49
|
import { StatusArea, statusLineSlash } from "./status-area.js";
|
|
46
50
|
import { createSessionEventHandler } from "./session-events.js";
|
|
47
51
|
import { SubagentTracker } from "./subagent-view.js";
|
|
52
|
+
import { loadKeys, processTerminal } from "./terminal-setup.js";
|
|
48
53
|
import { ToolTracker } from "./tool-view.js";
|
|
49
54
|
const HINT_MS = 2500;
|
|
50
|
-
const EDITOR_PLACEHOLDER = "输入消息,/ 命令,@ 文件,Shift+Enter 换行";
|
|
51
|
-
function processTerminal() {
|
|
52
|
-
const stdin = process.stdin;
|
|
53
|
-
if (stdin.isTTY !== true || typeof stdin.setRawMode !== "function" || !process.stdout.isTTY) {
|
|
54
|
-
throw new AmaError("terminal_init_failed", "stdin / stdout 不是终端");
|
|
55
|
-
}
|
|
56
|
-
return new ProcessTerminal();
|
|
57
|
-
}
|
|
58
|
-
function loadKeys(runtime, warn) {
|
|
59
|
-
const parsed = loadKeybindingsFile(join(runtime.paths.configDir, KEYBINDINGS_FILE));
|
|
60
|
-
for (const w of parsed.warnings)
|
|
61
|
-
warn(`keybindings.json:${w}`);
|
|
62
|
-
return new Keybindings(parsed.overrides);
|
|
63
|
-
}
|
|
64
55
|
export function runInteractiveMode(runtime, context, options = {}) {
|
|
65
56
|
const terminal = options.terminal ?? processTerminal();
|
|
66
57
|
const ui = runtime.config.ui ?? {};
|
|
@@ -95,7 +86,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
95
86
|
const loaderSlot = new Container();
|
|
96
87
|
const loader = new Loader(() => tui.requestRender(), {
|
|
97
88
|
theme,
|
|
98
|
-
message:
|
|
89
|
+
message: msg().interactive.view.run.thinking,
|
|
99
90
|
now,
|
|
100
91
|
...(ui.animation === false ? { animation: false } : {}),
|
|
101
92
|
...(options.spinnerIntervalMs !== undefined ? { intervalMs: options.spinnerIntervalMs } : {}),
|
|
@@ -126,7 +117,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
126
117
|
theme,
|
|
127
118
|
keybindings: keys,
|
|
128
119
|
maxVisibleLines: 8,
|
|
129
|
-
placeholder:
|
|
120
|
+
placeholder: msg().interactive.app.placeholder,
|
|
130
121
|
autocomplete: completion,
|
|
131
122
|
requestRender: () => tui.requestRender(),
|
|
132
123
|
...(historyFile !== undefined ? { historyFile } : {}),
|
|
@@ -196,7 +187,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
196
187
|
const replay = () => {
|
|
197
188
|
view.replay(session.messages, {
|
|
198
189
|
tool: (call, result) => tools.completed(call.id, call.name, call.arguments, result === undefined
|
|
199
|
-
? { content:
|
|
190
|
+
? { content: msg().interactive.app.noResult, isError: true }
|
|
200
191
|
: {
|
|
201
192
|
content: result.content,
|
|
202
193
|
isError: result.isError,
|
|
@@ -285,6 +276,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
285
276
|
setDraft,
|
|
286
277
|
editorEmpty: () => editor.isEmpty(),
|
|
287
278
|
});
|
|
279
|
+
const configUi = configUiFor(pickerHost, { runtime, context, view, loader, area, tui, notice });
|
|
288
280
|
const commandUi = {
|
|
289
281
|
runtime,
|
|
290
282
|
session: () => session,
|
|
@@ -294,6 +286,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
294
286
|
return next;
|
|
295
287
|
},
|
|
296
288
|
pick: (spec) => openPicker(pickerHost, spec),
|
|
289
|
+
pickModel: modelPickerFor(pickerHost, runtime, context),
|
|
297
290
|
confirmMode,
|
|
298
291
|
rewind: () => rewind.open(),
|
|
299
292
|
setDraft,
|
|
@@ -314,6 +307,10 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
314
307
|
exit: (code) => exit(code),
|
|
315
308
|
now,
|
|
316
309
|
extra: (name, args) => agentUi.command(name, args),
|
|
310
|
+
...agentCommandHooks(() => agentUi),
|
|
311
|
+
configPanel: (args) => configUi.open(args),
|
|
312
|
+
traceView: (id) => openTraceView({ ...pickerHost, session: () => session, now, notice, render }, id),
|
|
313
|
+
memoryPanel: memoryPanelFor(() => commandUi, pickerHost, tui, env), // [W6-M]
|
|
317
314
|
};
|
|
318
315
|
const runCommand = (line) => (statusLineSlash(area, line, notice)
|
|
319
316
|
? Promise.resolve(true)
|
|
@@ -360,6 +357,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
360
357
|
runCommand: (line) => void runCommand(line),
|
|
361
358
|
exit: (code) => exit(code),
|
|
362
359
|
onInterrupted: (empty) => void rewind.afterInterrupt(empty),
|
|
360
|
+
agents: () => agentUi.keys,
|
|
363
361
|
}));
|
|
364
362
|
// ---- 晚绑定 ---------------------------------------------------------------
|
|
365
363
|
const overlayHooks = {
|
|
@@ -395,6 +393,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
395
393
|
dialog: { theme, keybindings: keys, ...overlayHooks },
|
|
396
394
|
displayPath: (path) => tildePath(path, home),
|
|
397
395
|
...(options.clipboard !== undefined ? { clipboard: options.clipboard } : {}),
|
|
396
|
+
area,
|
|
398
397
|
});
|
|
399
398
|
const taskAgent = (taskId) => taskRegistryView(session.state.sessionId)?.get(taskId)?.agent;
|
|
400
399
|
const broker = mergingBroker(new ApprovalDialogBroker({
|
|
@@ -411,7 +410,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
411
410
|
notice(outcome === "deny" ? "info" : "warn", text);
|
|
412
411
|
}
|
|
413
412
|
},
|
|
414
|
-
}), agentUi.merge, (request) => notice("info",
|
|
413
|
+
}), agentUi.merge, (request) => notice("info", msg().interactive.app.followed(approvalOutcomeText(request, "allow", taskAgent))));
|
|
415
414
|
// ---- 启动与退出 -----------------------------------------------------------
|
|
416
415
|
let offSignals = () => undefined;
|
|
417
416
|
function exit(code) {
|
|
@@ -453,7 +452,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
|
|
|
453
452
|
}
|
|
454
453
|
catch (error) {
|
|
455
454
|
unsubscribe();
|
|
456
|
-
reject(new AmaError("terminal_init_failed",
|
|
455
|
+
reject(new AmaError("terminal_init_failed", msg().interactive.app.terminalInitFailed(error instanceof Error ? error.message : String(error)), { cause: error }));
|
|
457
456
|
return;
|
|
458
457
|
}
|
|
459
458
|
runtime.approvals.setUiBroker(broker);
|
|
@@ -9,12 +9,22 @@
|
|
|
9
9
|
*
|
|
10
10
|
* [RW-C] 空闲时双击 Esc(`app.rewind`,double-esc.ts):输入框为空打开回滚列表,有字则清空并存进
|
|
11
11
|
* 输入历史;运行中 Esc 仍为中断,中断后交给 `onInterrupted`(中断即撤回)。
|
|
12
|
+
*
|
|
13
|
+
* [W6-A] Agent 栏(agent-ui.ts):栏聚焦时它先收键(Esc 是「返回」,不中断、不回滚);输入为空、补全没开时
|
|
14
|
+
* `app.agents.focus`(缺省 `Ctrl+B` / `↓`)先问它要不要进栏,不要就照常交给编辑器(光标左移、历史下一条)。
|
|
12
15
|
*/
|
|
13
16
|
import type { AgentSession } from "../../agent/types.js";
|
|
14
17
|
import type { PermissionMode } from "../../permissions/types.js";
|
|
15
18
|
import type { Editor, Keybindings } from "../../tui.js";
|
|
16
19
|
import type { StatusBar } from "./status-bar.js";
|
|
17
20
|
import type { ToolTracker } from "./tool-view.js";
|
|
21
|
+
/** [W6-A] Agent 栏的按键入口。 */
|
|
22
|
+
export interface AgentKeys {
|
|
23
|
+
/** 栏聚焦时先消费按键;返回 true 已处理。 */
|
|
24
|
+
handleKey(data: string): boolean;
|
|
25
|
+
/** `app.agents.focus`(输入为空):进栏返回 true,否则交给编辑器。 */
|
|
26
|
+
focus(data: string): boolean;
|
|
27
|
+
}
|
|
18
28
|
export interface KeyDispatchDeps {
|
|
19
29
|
keys: Keybindings;
|
|
20
30
|
editor: Editor;
|
|
@@ -46,6 +56,8 @@ export interface KeyDispatchDeps {
|
|
|
46
56
|
onInterrupted?(editorWasEmpty: boolean): void;
|
|
47
57
|
/** 双击 Esc 的间隔(测试注入)。 */
|
|
48
58
|
doubleEscMs?: number;
|
|
59
|
+
/** [W6-A] Agent 栏(晚绑定)。 */
|
|
60
|
+
agents?(): AgentKeys | undefined;
|
|
49
61
|
}
|
|
50
62
|
/** 返回输入监听器:已处理返回 true,交给编辑器返回 false。 */
|
|
51
63
|
export declare function createKeyDispatch(deps: KeyDispatchDeps): (data: string) => boolean;
|