@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,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹(docs/wave6-plan.md §2.1、§2.2、D5、D6)。[W6-C0] 纯类型,经 `@armadra/agent` 导出。
|
|
3
|
+
*
|
|
4
|
+
* 两部分:
|
|
5
|
+
* - **持久化**:`custom{customType:"ama.trace"}` 条目的 `data`(`TraceEntryData`),由
|
|
6
|
+
* `agent/session-trace-writer.ts` 在事件发生后追加;不进上下文、不改请求字节、不改已落条目。
|
|
7
|
+
* 只记 id、时间与计数——**不含正文**(提示、参数、结果、外部 Agent 的工具标题 / 命令行 / 路径)。
|
|
8
|
+
* - **轨迹树**:`Trace`,由 `trace/build.ts` 的 `buildTrace()`([W6-T1],纯函数)从会话条目构建,TUI `/trace`、
|
|
9
|
+
* `ama sessions trace`、RPC `get_trace` 三方共用;老会话(无 `ama.trace`)回退推算并标 `approx`。
|
|
10
|
+
*/
|
|
11
|
+
import type { Usage } from "../ai/types.js";
|
|
12
|
+
export declare const TRACE_CUSTOM_TYPE = "ama.trace";
|
|
13
|
+
/** `TraceEntryData.reason` 的最大长度(字符)。 */
|
|
14
|
+
export declare const TRACE_REASON_MAX = 200;
|
|
15
|
+
/** 一次工具调用的计时(顶层调用;`id` = toolCallId)。 */
|
|
16
|
+
export interface TraceToolTiming {
|
|
17
|
+
id: string;
|
|
18
|
+
startedAt: number;
|
|
19
|
+
endedAt?: number;
|
|
20
|
+
/** 等审批的时长(`permission_request` → `permission_resolved`)。 */
|
|
21
|
+
approvalMs?: number;
|
|
22
|
+
/** 被拒(权限管线 / Hook / 审批 / 无人值守),没有执行。 */
|
|
23
|
+
denied?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** codemode 脚本里的内层调用(`parentId` = 外层 codemode 调用的 toolCallId)。 */
|
|
26
|
+
export interface TraceSubcallTiming {
|
|
27
|
+
id: string;
|
|
28
|
+
parentId: string;
|
|
29
|
+
name: string;
|
|
30
|
+
startedAt: number;
|
|
31
|
+
endedAt?: number;
|
|
32
|
+
isError?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** 一次模型请求(成功、失败、被重试掉的都写一条);写在该批 toolResult 之后(无工具时紧跟 assistant)。 */
|
|
35
|
+
export interface TraceStepData {
|
|
36
|
+
kind: "step";
|
|
37
|
+
/** 该请求的 assistant 条目。 */
|
|
38
|
+
assistantEntryId?: string;
|
|
39
|
+
requestAt?: number;
|
|
40
|
+
firstTokenAt?: number;
|
|
41
|
+
doneAt?: number;
|
|
42
|
+
outputTokens?: number;
|
|
43
|
+
tps?: number;
|
|
44
|
+
/** 本周期内第几次尝试(1 起;重试 / 回退后递增)。 */
|
|
45
|
+
attempt: number;
|
|
46
|
+
/** 回退前的模型 `provider/model`。 */
|
|
47
|
+
fallbackFrom?: string;
|
|
48
|
+
/** 中断时 `agent_end` 兜底写入。 */
|
|
49
|
+
status?: "aborted";
|
|
50
|
+
tools?: TraceToolTiming[];
|
|
51
|
+
subcalls?: TraceSubcallTiming[];
|
|
52
|
+
}
|
|
53
|
+
export interface TraceRetryWaitData {
|
|
54
|
+
kind: "retry_wait";
|
|
55
|
+
/** 即将进行的尝试序号(2 起)。 */
|
|
56
|
+
attempt: number;
|
|
57
|
+
delayMs: number;
|
|
58
|
+
startedAt: number;
|
|
59
|
+
/** 失败原因(≤ 200 字符)。 */
|
|
60
|
+
reason?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface TraceFallbackData {
|
|
63
|
+
kind: "fallback";
|
|
64
|
+
from: string;
|
|
65
|
+
to: string;
|
|
66
|
+
reason?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface TraceCompactionData {
|
|
69
|
+
kind: "compaction";
|
|
70
|
+
trigger: "threshold" | "overflow" | "manual";
|
|
71
|
+
startedAt: number;
|
|
72
|
+
endedAt: number;
|
|
73
|
+
compactionEntryId?: string;
|
|
74
|
+
aborted?: boolean;
|
|
75
|
+
}
|
|
76
|
+
export interface TraceAuxData {
|
|
77
|
+
kind: "aux";
|
|
78
|
+
purpose: "cache_warm" | "permission_classify" | (string & {});
|
|
79
|
+
usageEntryId: string;
|
|
80
|
+
startedAt?: number;
|
|
81
|
+
endedAt: number;
|
|
82
|
+
}
|
|
83
|
+
/** 外部 Agent 工具的骨架:只有种类与状态,**不含标题 / 命令行 / 路径**。 */
|
|
84
|
+
export interface TraceExternalTool {
|
|
85
|
+
kind: string;
|
|
86
|
+
status: "completed" | "failed" | "in_progress";
|
|
87
|
+
startedAt?: number;
|
|
88
|
+
endedAt?: number;
|
|
89
|
+
}
|
|
90
|
+
/** 外部 Agent 的一个回合(写在父会话,`taskId` 关联)。 */
|
|
91
|
+
export interface TraceExternalTurnData {
|
|
92
|
+
kind: "external_turn";
|
|
93
|
+
taskId?: string;
|
|
94
|
+
agent: string;
|
|
95
|
+
sessionId: string;
|
|
96
|
+
turn: number;
|
|
97
|
+
startedAt: number;
|
|
98
|
+
endedAt: number;
|
|
99
|
+
stopReason: string;
|
|
100
|
+
tools: TraceExternalTool[];
|
|
101
|
+
toolCount: number;
|
|
102
|
+
filesTouched: number;
|
|
103
|
+
}
|
|
104
|
+
export type TraceEntryData = TraceStepData | TraceRetryWaitData | TraceFallbackData | TraceCompactionData | TraceAuxData | TraceExternalTurnData;
|
|
105
|
+
export type TraceEntryKind = TraceEntryData["kind"];
|
|
106
|
+
export type TraceNodeKind = "turn" | "step" | "tool" | "subcall" | "subagent" | "compaction" | "retry_wait" | "aux";
|
|
107
|
+
export type TraceNodeStatus = "ok" | "error" | "aborted" | "denied" | "running" | "retried" | "interrupted";
|
|
108
|
+
export interface TraceNodeBase {
|
|
109
|
+
/** turn = 用户消息 entryId;step = assistant entryId;tool = toolCallId;subagent = taskId。 */
|
|
110
|
+
id: string;
|
|
111
|
+
kind: TraceNodeKind;
|
|
112
|
+
startedAt?: number;
|
|
113
|
+
/** 进行中只有 startedAt,不编造时长。 */
|
|
114
|
+
endedAt?: number;
|
|
115
|
+
/** 时间来自回退推算(老会话 / 缺 ama.trace)。 */
|
|
116
|
+
approx?: boolean;
|
|
117
|
+
status: TraceNodeStatus;
|
|
118
|
+
/** 回到会话条目(详情、跳转用)。 */
|
|
119
|
+
entryIds: string[];
|
|
120
|
+
}
|
|
121
|
+
export interface TraceTotals {
|
|
122
|
+
requests: number;
|
|
123
|
+
input: number;
|
|
124
|
+
output: number;
|
|
125
|
+
cacheRead: number;
|
|
126
|
+
cacheWrite: number;
|
|
127
|
+
cost?: number;
|
|
128
|
+
durationMs?: number;
|
|
129
|
+
toolCalls: number;
|
|
130
|
+
/** 只用非 approx 的 step。 */
|
|
131
|
+
ttftP50?: number;
|
|
132
|
+
ttftP90?: number;
|
|
133
|
+
avgTps?: number;
|
|
134
|
+
cacheHitRatio?: number;
|
|
135
|
+
}
|
|
136
|
+
export interface TraceTurnNode extends TraceNodeBase {
|
|
137
|
+
kind: "turn";
|
|
138
|
+
/** 用户消息的 origin(`steer` / `followUp` / `host` / `direct` …)。 */
|
|
139
|
+
origin?: string;
|
|
140
|
+
steps: (TraceStepNode | TraceCompactionNode | TraceRetryWaitNode)[];
|
|
141
|
+
usage: TraceTotals;
|
|
142
|
+
}
|
|
143
|
+
export interface TraceStepNode extends TraceNodeBase {
|
|
144
|
+
kind: "step";
|
|
145
|
+
provider: string;
|
|
146
|
+
model: string;
|
|
147
|
+
attempt: number;
|
|
148
|
+
fallbackFrom?: string;
|
|
149
|
+
requestAt?: number;
|
|
150
|
+
firstTokenAt?: number;
|
|
151
|
+
doneAt?: number;
|
|
152
|
+
ttftMs?: number;
|
|
153
|
+
tps?: number;
|
|
154
|
+
usage: Usage;
|
|
155
|
+
stopReason: string;
|
|
156
|
+
errorMessage?: string;
|
|
157
|
+
thinkingLevel?: string;
|
|
158
|
+
cacheHitRatio?: number;
|
|
159
|
+
tools: TraceToolNode[];
|
|
160
|
+
}
|
|
161
|
+
export interface TraceToolNode extends TraceNodeBase {
|
|
162
|
+
kind: "tool";
|
|
163
|
+
name: string;
|
|
164
|
+
isError: boolean;
|
|
165
|
+
approvalMs?: number;
|
|
166
|
+
denied?: boolean;
|
|
167
|
+
children: (TraceSubcallNode | TraceSubagentNode)[];
|
|
168
|
+
}
|
|
169
|
+
export interface TraceSubcallNode extends TraceNodeBase {
|
|
170
|
+
kind: "subcall";
|
|
171
|
+
name: string;
|
|
172
|
+
parentToolCallId: string;
|
|
173
|
+
isError: boolean;
|
|
174
|
+
}
|
|
175
|
+
export interface TraceExternalTurnNode extends Omit<TraceNodeBase, "kind"> {
|
|
176
|
+
kind: "external_turn";
|
|
177
|
+
turn: number;
|
|
178
|
+
stopReason: string;
|
|
179
|
+
tools: TraceExternalTool[];
|
|
180
|
+
toolCount: number;
|
|
181
|
+
filesTouched: number;
|
|
182
|
+
}
|
|
183
|
+
export interface TraceSubagentNode extends TraceNodeBase {
|
|
184
|
+
kind: "subagent";
|
|
185
|
+
taskId: string;
|
|
186
|
+
agent: string;
|
|
187
|
+
runner: string;
|
|
188
|
+
background: boolean;
|
|
189
|
+
usage?: Usage;
|
|
190
|
+
costUsd?: number;
|
|
191
|
+
turns?: number;
|
|
192
|
+
/** ama 子会话(懒加载,深度 ≤ 1)。 */
|
|
193
|
+
child?: Trace;
|
|
194
|
+
/** 外部 Agent 骨架。 */
|
|
195
|
+
external?: TraceExternalTurnNode[];
|
|
196
|
+
childRef?: {
|
|
197
|
+
sessionFile?: string;
|
|
198
|
+
sessionId: string;
|
|
199
|
+
};
|
|
200
|
+
/** 子会话文件缺失或损坏。 */
|
|
201
|
+
childMissing?: boolean;
|
|
202
|
+
}
|
|
203
|
+
export interface TraceCompactionNode extends TraceNodeBase {
|
|
204
|
+
kind: "compaction";
|
|
205
|
+
trigger?: "threshold" | "overflow" | "manual";
|
|
206
|
+
tokensBefore?: number;
|
|
207
|
+
tokensAfter?: number;
|
|
208
|
+
}
|
|
209
|
+
export interface TraceRetryWaitNode extends TraceNodeBase {
|
|
210
|
+
kind: "retry_wait";
|
|
211
|
+
attempt: number;
|
|
212
|
+
delayMs: number;
|
|
213
|
+
reason?: string;
|
|
214
|
+
}
|
|
215
|
+
export interface TraceAuxNode extends TraceNodeBase {
|
|
216
|
+
kind: "aux";
|
|
217
|
+
purpose: string;
|
|
218
|
+
usage?: Usage;
|
|
219
|
+
}
|
|
220
|
+
export interface Trace {
|
|
221
|
+
version: 1;
|
|
222
|
+
sessionId: string;
|
|
223
|
+
sessionFile?: string;
|
|
224
|
+
cwd: string;
|
|
225
|
+
startedAt: number;
|
|
226
|
+
endedAt?: number;
|
|
227
|
+
totals: TraceTotals;
|
|
228
|
+
turns: TraceTurnNode[];
|
|
229
|
+
/** cache_warm / permission_classify。 */
|
|
230
|
+
aux: TraceAuxNode[];
|
|
231
|
+
/** 有进行中节点。 */
|
|
232
|
+
partial: boolean;
|
|
233
|
+
}
|
|
234
|
+
/** `buildTrace` / `session.trace()` / RPC `get_trace` 的选项([W6-T1] / [W6-T2] 实现)。 */
|
|
235
|
+
export interface TraceOptions {
|
|
236
|
+
branch?: "leaf" | "all";
|
|
237
|
+
/** 注入当前时刻(确定性)。 */
|
|
238
|
+
now?: number;
|
|
239
|
+
/** 尾部优先的回合数上限。 */
|
|
240
|
+
turnLimit?: number;
|
|
241
|
+
/** 子任务的子轨迹。 */
|
|
242
|
+
taskId?: string;
|
|
243
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹(docs/wave6-plan.md §2.1、§2.2、D5、D6)。[W6-C0] 纯类型,经 `@armadra/agent` 导出。
|
|
3
|
+
*
|
|
4
|
+
* 两部分:
|
|
5
|
+
* - **持久化**:`custom{customType:"ama.trace"}` 条目的 `data`(`TraceEntryData`),由
|
|
6
|
+
* `agent/session-trace-writer.ts` 在事件发生后追加;不进上下文、不改请求字节、不改已落条目。
|
|
7
|
+
* 只记 id、时间与计数——**不含正文**(提示、参数、结果、外部 Agent 的工具标题 / 命令行 / 路径)。
|
|
8
|
+
* - **轨迹树**:`Trace`,由 `trace/build.ts` 的 `buildTrace()`([W6-T1],纯函数)从会话条目构建,TUI `/trace`、
|
|
9
|
+
* `ama sessions trace`、RPC `get_trace` 三方共用;老会话(无 `ama.trace`)回退推算并标 `approx`。
|
|
10
|
+
*/
|
|
11
|
+
export const TRACE_CUSTOM_TYPE = "ama.trace";
|
|
12
|
+
/** `TraceEntryData.reason` 的最大长度(字符)。 */
|
|
13
|
+
export const TRACE_REASON_MAX = 200;
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* - 换行规范化:`\r\n` / 单独的 `\r` → `\n`(括号粘贴里终端常把换行发成 `\r`)。
|
|
6
6
|
* - 未折叠的粘贴把制表符换成 4 个空格(编辑器按列宽渲染,`\t` 没有确定宽度);折叠内容保留原文。
|
|
7
7
|
* - 标记只在本编辑器记录过的编号上展开;用户手打的同形文本不会被替换成别的内容。
|
|
8
|
+
* - [W6-C0] 标记按界面语言渲染(zh `[粘贴 #N · M 行]`、en `[paste #N · M lines]`);识别同时认两种写法,
|
|
9
|
+
* 换了语言后历史草稿里的旧标记照样是不可分割段、照样展开。
|
|
8
10
|
*/
|
|
9
11
|
export declare const PASTE_LINE_THRESHOLD = 10;
|
|
10
12
|
export declare const PASTE_CHAR_THRESHOLD = 1000;
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
* - 换行规范化:`\r\n` / 单独的 `\r` → `\n`(括号粘贴里终端常把换行发成 `\r`)。
|
|
6
6
|
* - 未折叠的粘贴把制表符换成 4 个空格(编辑器按列宽渲染,`\t` 没有确定宽度);折叠内容保留原文。
|
|
7
7
|
* - 标记只在本编辑器记录过的编号上展开;用户手打的同形文本不会被替换成别的内容。
|
|
8
|
+
* - [W6-C0] 标记按界面语言渲染(zh `[粘贴 #N · M 行]`、en `[paste #N · M lines]`);识别同时认两种写法,
|
|
9
|
+
* 换了语言后历史草稿里的旧标记照样是不可分割段、照样展开。
|
|
8
10
|
*/
|
|
11
|
+
import { msg } from "../../i18n/index.js";
|
|
9
12
|
export const PASTE_LINE_THRESHOLD = 10;
|
|
10
13
|
export const PASTE_CHAR_THRESHOLD = 1000;
|
|
11
|
-
const MARKER_RE = /\[
|
|
14
|
+
const MARKER_RE = /\[(?:粘贴|paste) #(\d+) · (\d+) (?:行|lines?)\]/g;
|
|
12
15
|
export function normalizePastedText(text) {
|
|
13
16
|
return text.replace(/\r\n?/g, "\n");
|
|
14
17
|
}
|
|
@@ -20,7 +23,7 @@ export function shouldCollapse(text) {
|
|
|
20
23
|
return countLines(text) > PASTE_LINE_THRESHOLD || text.length > PASTE_CHAR_THRESHOLD;
|
|
21
24
|
}
|
|
22
25
|
export function formatMarker(id, lines) {
|
|
23
|
-
return
|
|
26
|
+
return msg().interactive.paste.marker(id, lines);
|
|
24
27
|
}
|
|
25
28
|
export class PasteStore {
|
|
26
29
|
next = 1;
|
|
@@ -48,7 +51,7 @@ export class PasteStore {
|
|
|
48
51
|
}
|
|
49
52
|
/** 一行内已登记标记的区间(编辑器的不可分割段)。 */
|
|
50
53
|
ranges(line) {
|
|
51
|
-
if (this.entries.size === 0 || !line.includes("[粘贴 #"))
|
|
54
|
+
if (this.entries.size === 0 || !(line.includes("[粘贴 #") || line.includes("[paste #")))
|
|
52
55
|
return [];
|
|
53
56
|
const out = [];
|
|
54
57
|
for (const m of line.matchAll(MARKER_RE)) {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* 弹层缩进 2 列,尾行 `(i/n) Tab 接受 · Esc 关闭`。
|
|
14
14
|
* - 历史:会话内 + 可选历史文件(JSONL,每行一个 JSON 字符串,保留最近 500 条)。
|
|
15
15
|
*/
|
|
16
|
+
import { msg } from "../../i18n/index.js";
|
|
16
17
|
import { CURSOR_MARKER } from "../component.js";
|
|
17
18
|
import { truncateToWidth, visibleWidth } from "../ansi.js";
|
|
18
19
|
import { defaultKeybindings } from "../keybindings.js";
|
|
@@ -26,7 +27,6 @@ export { loadHistoryFile } from "./editor-history.js";
|
|
|
26
27
|
const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
27
28
|
/** 提示符 `› ` / 续行缩进的宽度。 */
|
|
28
29
|
const PROMPT_WIDTH = 2;
|
|
29
|
-
const COMPLETION_FOOTER = "Tab 接受 · Esc 关闭";
|
|
30
30
|
export class Editor {
|
|
31
31
|
options;
|
|
32
32
|
focused = false;
|
|
@@ -351,7 +351,7 @@ export class Editor {
|
|
|
351
351
|
maxVisible: 8,
|
|
352
352
|
theme: this.theme,
|
|
353
353
|
keybindings: this.keys,
|
|
354
|
-
footer:
|
|
354
|
+
footer: msg().interactive.editor.completionFooter,
|
|
355
355
|
showCount: true,
|
|
356
356
|
}),
|
|
357
357
|
from: result.from,
|
|
@@ -56,6 +56,9 @@ export declare class Loader implements Component {
|
|
|
56
56
|
/** 已用时从现在重新算(换到另一段工作时)。 */
|
|
57
57
|
resetElapsed(): void;
|
|
58
58
|
start(): void;
|
|
59
|
+
private schedule;
|
|
60
|
+
/** [W6-S] 运行中切换动画(`/config ui.animation`):换定时器间隔,已用时不清零。 */
|
|
61
|
+
setAnimation(on: boolean): void;
|
|
59
62
|
stop(): void;
|
|
60
63
|
/** 推进一帧(定时器调用;测试可直接调用)。静止时只在已用时变化时重绘。 */
|
|
61
64
|
tick(): void;
|
|
@@ -87,12 +87,26 @@ export class Loader {
|
|
|
87
87
|
return;
|
|
88
88
|
this.startedAt = this.now();
|
|
89
89
|
this.frameIndex = 0;
|
|
90
|
+
this.schedule();
|
|
91
|
+
this.requestRender();
|
|
92
|
+
}
|
|
93
|
+
schedule() {
|
|
90
94
|
const glyphs = this.options.theme?.glyphs ?? UNICODE_GLYPHS;
|
|
91
95
|
const interval = this.animated
|
|
92
96
|
? (this.options.intervalMs ?? (glyphs.ascii ? 250 : 80))
|
|
93
97
|
: Math.max(this.options.intervalMs ?? 1000, 1000);
|
|
94
98
|
this.timer = setInterval(() => this.tick(), interval);
|
|
95
99
|
this.timer.unref?.();
|
|
100
|
+
}
|
|
101
|
+
/** [W6-S] 运行中切换动画(`/config ui.animation`):换定时器间隔,已用时不清零。 */
|
|
102
|
+
setAnimation(on) {
|
|
103
|
+
if (this.animated === on)
|
|
104
|
+
return;
|
|
105
|
+
this.options.animation = on;
|
|
106
|
+
if (this.timer === null)
|
|
107
|
+
return;
|
|
108
|
+
clearInterval(this.timer);
|
|
109
|
+
this.schedule();
|
|
96
110
|
this.requestRender();
|
|
97
111
|
}
|
|
98
112
|
stop() {
|
|
@@ -60,6 +60,8 @@ export declare class SelectList implements Component, Focusable {
|
|
|
60
60
|
private get maxVisible();
|
|
61
61
|
setItems(items: readonly SelectItem[]): void;
|
|
62
62
|
getItems(): readonly SelectItem[];
|
|
63
|
+
/** 换列表下的按键提示(选择器切视图时)。 */
|
|
64
|
+
setFooter(footer: string | undefined): void;
|
|
63
65
|
getFilter(): string;
|
|
64
66
|
setFilter(filter: string): void;
|
|
65
67
|
getSelected(): SelectItem | undefined;
|
|
@@ -52,6 +52,13 @@ export class SelectList {
|
|
|
52
52
|
getItems() {
|
|
53
53
|
return this.filtered;
|
|
54
54
|
}
|
|
55
|
+
/** 换列表下的按键提示(选择器切视图时)。 */
|
|
56
|
+
setFooter(footer) {
|
|
57
|
+
if (footer === undefined)
|
|
58
|
+
delete this.options.footer;
|
|
59
|
+
else
|
|
60
|
+
this.options.footer = footer;
|
|
61
|
+
}
|
|
55
62
|
getFilter() {
|
|
56
63
|
return this.filter;
|
|
57
64
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouped settings list (docs/wave6-plan.md §6.3). [W6-S]
|
|
3
|
+
*
|
|
4
|
+
* Rows `› label value tag note` under muted group headers; the selected row uses the prompt glyph,
|
|
5
|
+
* accent + bold and the `selection` background (same look as ChoiceDialog). A query filters rows by id,
|
|
6
|
+
* label, value and extra search text (case-insensitive); groups left without rows disappear. Only
|
|
7
|
+
* `maxVisible` lines (headers included) are drawn, scrolled so the selected row stays visible.
|
|
8
|
+
* Narrow widths drop the note column (< 60) and then the tag column (< 48).
|
|
9
|
+
*
|
|
10
|
+
* Input handling stays with the owner (the `/config` panel decides what Enter / Space do); this
|
|
11
|
+
* component only moves the selection and renders.
|
|
12
|
+
*/
|
|
13
|
+
import type { Component, SemanticColor, Theme } from "../component.js";
|
|
14
|
+
export interface SettingsRow {
|
|
15
|
+
id: string;
|
|
16
|
+
/** Group header text; consecutive rows with the same group share one header. */
|
|
17
|
+
group: string;
|
|
18
|
+
label: string;
|
|
19
|
+
/** Already formatted value. */
|
|
20
|
+
value: string;
|
|
21
|
+
valueColor?: SemanticColor;
|
|
22
|
+
/** Short right column (apply tier). */
|
|
23
|
+
tag?: string;
|
|
24
|
+
/** Trailing note (source, lock reason). */
|
|
25
|
+
note?: string;
|
|
26
|
+
noteColor?: SemanticColor;
|
|
27
|
+
/** Not editable in the current scope: drawn dim. */
|
|
28
|
+
dim?: boolean;
|
|
29
|
+
/** Extra text the query matches (enum values, description). */
|
|
30
|
+
search?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface SettingsListOptions {
|
|
33
|
+
theme: Theme;
|
|
34
|
+
/** Lines to draw (headers included); default 16. */
|
|
35
|
+
maxVisible?: number;
|
|
36
|
+
emptyText?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare class SettingsList implements Component {
|
|
39
|
+
private readonly options;
|
|
40
|
+
private rows;
|
|
41
|
+
private shown;
|
|
42
|
+
private selected;
|
|
43
|
+
private top;
|
|
44
|
+
private filter;
|
|
45
|
+
constructor(options: SettingsListOptions);
|
|
46
|
+
set maxVisible(lines: number);
|
|
47
|
+
get query(): string;
|
|
48
|
+
/** Replace the rows, keeping the selection on the same id when possible. */
|
|
49
|
+
setRows(rows: readonly SettingsRow[]): void;
|
|
50
|
+
setQuery(query: string): void;
|
|
51
|
+
get selectedRow(): SettingsRow | undefined;
|
|
52
|
+
get visibleRows(): readonly SettingsRow[];
|
|
53
|
+
selectId(id: string): boolean;
|
|
54
|
+
/** Move by `delta` rows (wraps around). */
|
|
55
|
+
move(delta: number): void;
|
|
56
|
+
private refilter;
|
|
57
|
+
private lines;
|
|
58
|
+
render(width: number): string[];
|
|
59
|
+
private rowLine;
|
|
60
|
+
invalidate(): void;
|
|
61
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouped settings list (docs/wave6-plan.md §6.3). [W6-S]
|
|
3
|
+
*
|
|
4
|
+
* Rows `› label value tag note` under muted group headers; the selected row uses the prompt glyph,
|
|
5
|
+
* accent + bold and the `selection` background (same look as ChoiceDialog). A query filters rows by id,
|
|
6
|
+
* label, value and extra search text (case-insensitive); groups left without rows disappear. Only
|
|
7
|
+
* `maxVisible` lines (headers included) are drawn, scrolled so the selected row stays visible.
|
|
8
|
+
* Narrow widths drop the note column (< 60) and then the tag column (< 48).
|
|
9
|
+
*
|
|
10
|
+
* Input handling stays with the owner (the `/config` panel decides what Enter / Space do); this
|
|
11
|
+
* component only moves the selection and renders.
|
|
12
|
+
*/
|
|
13
|
+
import { padToWidth, truncateToWidth, visibleWidth } from "../ansi.js";
|
|
14
|
+
const LABEL_MAX = 24;
|
|
15
|
+
const VALUE_MAX = 16;
|
|
16
|
+
export class SettingsList {
|
|
17
|
+
options;
|
|
18
|
+
rows = [];
|
|
19
|
+
shown = [];
|
|
20
|
+
selected = 0;
|
|
21
|
+
top = 0;
|
|
22
|
+
filter = "";
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.options = options;
|
|
25
|
+
}
|
|
26
|
+
set maxVisible(lines) {
|
|
27
|
+
this.options.maxVisible = Math.max(3, lines);
|
|
28
|
+
}
|
|
29
|
+
get query() {
|
|
30
|
+
return this.filter;
|
|
31
|
+
}
|
|
32
|
+
/** Replace the rows, keeping the selection on the same id when possible. */
|
|
33
|
+
setRows(rows) {
|
|
34
|
+
const id = this.selectedRow?.id;
|
|
35
|
+
this.rows = rows;
|
|
36
|
+
this.refilter();
|
|
37
|
+
if (id !== undefined)
|
|
38
|
+
this.selectId(id);
|
|
39
|
+
}
|
|
40
|
+
setQuery(query) {
|
|
41
|
+
if (query === this.filter)
|
|
42
|
+
return;
|
|
43
|
+
const id = this.selectedRow?.id;
|
|
44
|
+
this.filter = query;
|
|
45
|
+
this.refilter();
|
|
46
|
+
this.selected = 0;
|
|
47
|
+
if (id !== undefined)
|
|
48
|
+
this.selectId(id);
|
|
49
|
+
}
|
|
50
|
+
get selectedRow() {
|
|
51
|
+
return this.shown[this.selected];
|
|
52
|
+
}
|
|
53
|
+
get visibleRows() {
|
|
54
|
+
return this.shown;
|
|
55
|
+
}
|
|
56
|
+
selectId(id) {
|
|
57
|
+
const index = this.shown.findIndex((row) => row.id === id);
|
|
58
|
+
if (index === -1)
|
|
59
|
+
return false;
|
|
60
|
+
this.selected = index;
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
/** Move by `delta` rows (wraps around). */
|
|
64
|
+
move(delta) {
|
|
65
|
+
const n = this.shown.length;
|
|
66
|
+
if (n === 0)
|
|
67
|
+
return;
|
|
68
|
+
this.selected = (((this.selected + delta) % n) + n) % n;
|
|
69
|
+
}
|
|
70
|
+
refilter() {
|
|
71
|
+
const q = this.filter.trim().toLowerCase();
|
|
72
|
+
this.shown =
|
|
73
|
+
q === ""
|
|
74
|
+
? [...this.rows]
|
|
75
|
+
: this.rows.filter((row) => [row.id, row.label, row.value, row.search ?? ""].some((t) => t.toLowerCase().includes(q)));
|
|
76
|
+
if (this.selected >= this.shown.length)
|
|
77
|
+
this.selected = Math.max(0, this.shown.length - 1);
|
|
78
|
+
}
|
|
79
|
+
lines() {
|
|
80
|
+
const out = [];
|
|
81
|
+
let group;
|
|
82
|
+
this.shown.forEach((row, index) => {
|
|
83
|
+
if (row.group !== group) {
|
|
84
|
+
group = row.group;
|
|
85
|
+
out.push({ kind: "group", text: row.group });
|
|
86
|
+
}
|
|
87
|
+
out.push({ kind: "row", row, index });
|
|
88
|
+
});
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
render(width) {
|
|
92
|
+
const { theme } = this.options;
|
|
93
|
+
if (this.shown.length === 0)
|
|
94
|
+
return [theme.fg("dim", truncateToWidth(this.options.emptyText ?? "", width))];
|
|
95
|
+
const all = this.lines();
|
|
96
|
+
const max = this.options.maxVisible ?? 16;
|
|
97
|
+
const at = all.findIndex((l) => l.kind === "row" && l.index === this.selected);
|
|
98
|
+
// keep the selected row (and its group header when it is the first row of the group) in view
|
|
99
|
+
const anchor = at > 0 && all[at - 1].kind === "group" ? at - 1 : at;
|
|
100
|
+
if (anchor < this.top)
|
|
101
|
+
this.top = anchor;
|
|
102
|
+
if (at >= this.top + max)
|
|
103
|
+
this.top = at - max + 1;
|
|
104
|
+
this.top = Math.max(0, Math.min(this.top, Math.max(0, all.length - max)));
|
|
105
|
+
const window = all.slice(this.top, this.top + max);
|
|
106
|
+
// column widths from all rows: filtering does not make columns jump
|
|
107
|
+
const rows = this.rows;
|
|
108
|
+
// narrow terminals: label gets at most half the width, value what is left of the first two columns
|
|
109
|
+
const labelCap = Math.min(LABEL_MAX, Math.max(8, Math.floor((width - 4) / 2)));
|
|
110
|
+
const labelW = Math.min(labelCap, Math.max(...rows.map((r) => visibleWidth(r.label))));
|
|
111
|
+
const valueCap = Math.min(VALUE_MAX, Math.max(4, width - 4 - labelW));
|
|
112
|
+
const valueW = Math.min(valueCap, Math.max(...rows.map((r) => visibleWidth(r.value))));
|
|
113
|
+
const tagW = Math.max(0, ...rows.map((r) => visibleWidth(r.tag ?? "")));
|
|
114
|
+
return window.map((line) => line.kind === "group"
|
|
115
|
+
? truncateToWidth(theme.fg("muted", theme.bold(line.text)), width)
|
|
116
|
+
: this.rowLine(line.row, line.index === this.selected, width, labelW, valueW, tagW));
|
|
117
|
+
}
|
|
118
|
+
rowLine(row, selected, width, labelW, valueW, tagW) {
|
|
119
|
+
const { theme } = this.options;
|
|
120
|
+
const pointer = selected ? theme.glyphs.prompt : " ";
|
|
121
|
+
const label = padToWidth(truncateToWidth(row.label, labelW), labelW);
|
|
122
|
+
const valueText = padToWidth(truncateToWidth(row.value, valueW), valueW);
|
|
123
|
+
const value = row.valueColor !== undefined ? theme.fg(row.valueColor, valueText) : valueText;
|
|
124
|
+
let line = `${pointer} ${selected ? theme.fg("accent", theme.bold(label)) : label} ${value}`;
|
|
125
|
+
if (width >= 48 && tagW > 0)
|
|
126
|
+
line += ` ${theme.fg("dim", padToWidth(row.tag ?? "", tagW))}`;
|
|
127
|
+
if (width >= 60 && row.note !== undefined && row.note !== "")
|
|
128
|
+
line += ` ${theme.fg(row.noteColor ?? "dim", row.note)}`;
|
|
129
|
+
let out = truncateToWidth(line, width);
|
|
130
|
+
if (row.dim === true && !selected)
|
|
131
|
+
out = theme.dim(out);
|
|
132
|
+
return selected ? theme.bg("selection", padToWidth(out, width)) : out;
|
|
133
|
+
}
|
|
134
|
+
invalidate() { }
|
|
135
|
+
}
|
|
@@ -44,6 +44,11 @@ export declare const DEFAULT_KEYBINDINGS: {
|
|
|
44
44
|
readonly "app.statusLine.toggle": readonly ["ctrl+g"];
|
|
45
45
|
/** [W5-U] 粘贴剪贴板图片(写进数据目录,输入框插入 `@路径`)。 */
|
|
46
46
|
readonly "app.paste.image": readonly ["ctrl+v"];
|
|
47
|
+
/**
|
|
48
|
+
* [W6-A] 进入 Agent 栏:只在输入为空时生效(有字时 `Ctrl+B` 仍是光标左移、`↓` 仍是下移 / 历史);
|
|
49
|
+
* `↓` 另要求栏可见。tmux 缺省前缀吃掉 `Ctrl+B` 时用 `↓`。
|
|
50
|
+
*/
|
|
51
|
+
readonly "app.agents.focus": readonly ["ctrl+b", "down"];
|
|
47
52
|
};
|
|
48
53
|
export type ActionId = keyof typeof DEFAULT_KEYBINDINGS;
|
|
49
54
|
export type KeybindingOverrides = Partial<Record<ActionId, readonly string[]>>;
|
package/dist/tui/keybindings.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* - 覆盖时整组替换;空数组表示禁用该动作。未知动作 id 与非字符串键会被报告并忽略。
|
|
6
6
|
* - 文件位置由调用方决定(配置目录归 B5),这里只负责解析与合并。
|
|
7
7
|
*/
|
|
8
|
+
import { msg } from "../i18n/index.js";
|
|
8
9
|
import { readFileSync } from "node:fs";
|
|
9
10
|
import { normalizeKeyId, parseKey } from "./keys.js";
|
|
10
11
|
export const DEFAULT_KEYBINDINGS = {
|
|
@@ -46,6 +47,11 @@ export const DEFAULT_KEYBINDINGS = {
|
|
|
46
47
|
"app.statusLine.toggle": ["ctrl+g"],
|
|
47
48
|
/** [W5-U] 粘贴剪贴板图片(写进数据目录,输入框插入 `@路径`)。 */
|
|
48
49
|
"app.paste.image": ["ctrl+v"],
|
|
50
|
+
/**
|
|
51
|
+
* [W6-A] 进入 Agent 栏:只在输入为空时生效(有字时 `Ctrl+B` 仍是光标左移、`↓` 仍是下移 / 历史);
|
|
52
|
+
* `↓` 另要求栏可见。tmux 缺省前缀吃掉 `Ctrl+B` 时用 `↓`。
|
|
53
|
+
*/
|
|
54
|
+
"app.agents.focus": ["ctrl+b", "down"],
|
|
49
55
|
};
|
|
50
56
|
export function isActionId(id) {
|
|
51
57
|
return Object.prototype.hasOwnProperty.call(DEFAULT_KEYBINDINGS, id);
|
|
@@ -55,16 +61,16 @@ export function parseKeybindings(value) {
|
|
|
55
61
|
const overrides = {};
|
|
56
62
|
const warnings = [];
|
|
57
63
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
58
|
-
return { overrides: {}, warnings: [
|
|
64
|
+
return { overrides: {}, warnings: [msg().interactive.keybindings.notObject] };
|
|
59
65
|
}
|
|
60
66
|
for (const [action, keys] of Object.entries(value)) {
|
|
61
67
|
if (!isActionId(action)) {
|
|
62
|
-
warnings.push(
|
|
68
|
+
warnings.push(msg().interactive.keybindings.unknownAction(action));
|
|
63
69
|
continue;
|
|
64
70
|
}
|
|
65
71
|
const list = typeof keys === "string" ? [keys] : keys;
|
|
66
72
|
if (!Array.isArray(list) || !list.every((k) => typeof k === "string")) {
|
|
67
|
-
warnings.push(
|
|
73
|
+
warnings.push(msg().interactive.keybindings.badKeys(action));
|
|
68
74
|
continue;
|
|
69
75
|
}
|
|
70
76
|
overrides[action] = list.map((k) => normalizeKeyId(k));
|
|
@@ -80,13 +86,19 @@ export function loadKeybindingsFile(path) {
|
|
|
80
86
|
catch (error) {
|
|
81
87
|
if (error.code === "ENOENT")
|
|
82
88
|
return { overrides: {}, warnings: [] };
|
|
83
|
-
return {
|
|
89
|
+
return {
|
|
90
|
+
overrides: {},
|
|
91
|
+
warnings: [msg().interactive.keybindings.readFailed(path, error.message)],
|
|
92
|
+
};
|
|
84
93
|
}
|
|
85
94
|
try {
|
|
86
95
|
return parseKeybindings(JSON.parse(text));
|
|
87
96
|
}
|
|
88
97
|
catch (error) {
|
|
89
|
-
return {
|
|
98
|
+
return {
|
|
99
|
+
overrides: {},
|
|
100
|
+
warnings: [msg().interactive.keybindings.badJson(path, error.message)],
|
|
101
|
+
};
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
104
|
export class Keybindings {
|
package/dist/tui.d.ts
CHANGED
|
@@ -30,3 +30,4 @@ export { Loader, LOADER_FRAMES, formatElapsed, type LoaderOptions, type LoaderVe
|
|
|
30
30
|
export { compositeOverlays, type OverlayAnchor, type OverlayOptions, type OverlayLayer, } from "./tui/components/overlay.js";
|
|
31
31
|
export { KeyValue, type KeyValueRow, type KeyValueOptions } from "./tui/components/key-value.js";
|
|
32
32
|
export { Meter, METER_FULL, METER_EMPTY, type MeterOptions } from "./tui/components/meter.js";
|
|
33
|
+
export { SettingsList, type SettingsRow, type SettingsListOptions, } from "./tui/components/settings-list.js";
|
package/dist/tui.js
CHANGED
|
@@ -31,3 +31,5 @@ export { compositeOverlays, } from "./tui/components/overlay.js";
|
|
|
31
31
|
// ---- W3-B9a-2 组件 ----
|
|
32
32
|
export { KeyValue } from "./tui/components/key-value.js";
|
|
33
33
|
export { Meter, METER_FULL, METER_EMPTY } from "./tui/components/meter.js";
|
|
34
|
+
// ---- W6-S 组件 ----
|
|
35
|
+
export { SettingsList, } from "./tui/components/settings-list.js";
|