@armadra/agent 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +174 -1
- package/README.md +201 -82
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/dist/acp.d.ts +18 -0
- package/dist/acp.js +19 -0
- package/dist/agent/limits.d.ts +38 -0
- package/dist/agent/limits.js +127 -0
- package/dist/agent/loop-guard.d.ts +38 -0
- package/dist/agent/loop-guard.js +95 -0
- package/dist/agent/loop.d.ts +4 -0
- package/dist/agent/loop.js +7 -0
- package/dist/agent/prompt-rules.d.ts +12 -0
- package/dist/agent/prompt-rules.js +18 -0
- package/dist/agent/reminders.d.ts +59 -0
- package/dist/agent/reminders.js +327 -0
- package/dist/agent/session-cache.d.ts +5 -0
- package/dist/agent/session-cache.js +17 -1
- package/dist/agent/session-classifier.d.ts +1 -1
- package/dist/agent/session-classifier.js +3 -1
- package/dist/agent/session-compaction.d.ts +35 -6
- package/dist/agent/session-compaction.js +157 -31
- package/dist/agent/session-core.d.ts +27 -1
- package/dist/agent/session-extensions.d.ts +61 -0
- package/dist/agent/session-extensions.js +129 -0
- package/dist/agent/session-images.d.ts +23 -0
- package/dist/agent/session-images.js +97 -0
- package/dist/agent/session-plan.d.ts +21 -0
- package/dist/agent/session-plan.js +524 -0
- package/dist/agent/session-rewind.d.ts +81 -0
- package/dist/agent/session-rewind.js +354 -0
- package/dist/agent/session-run.d.ts +28 -1
- package/dist/agent/session-run.js +157 -6
- package/dist/agent/session-settings.d.ts +49 -0
- package/dist/agent/session-settings.js +95 -0
- package/dist/agent/session-subagent.d.ts +36 -24
- package/dist/agent/session-subagent.js +259 -129
- package/dist/agent/session-sync.d.ts +10 -3
- package/dist/agent/session-sync.js +37 -8
- package/dist/agent/session-telemetry.d.ts +39 -0
- package/dist/agent/session-telemetry.js +231 -0
- package/dist/agent/session-tools.js +40 -1
- package/dist/agent/session.d.ts +30 -29
- package/dist/agent/session.js +79 -123
- package/dist/agent/subagent-registry.d.ts +91 -0
- package/dist/agent/subagent-registry.js +494 -0
- package/dist/agent/system-prompt.d.ts +6 -3
- package/dist/agent/system-prompt.js +7 -2
- package/dist/agent/tool-runner.d.ts +8 -1
- package/dist/agent/tool-runner.js +57 -4
- package/dist/agent/types-w5.d.ts +192 -0
- package/dist/agent/types-w5.js +10 -0
- package/dist/agent/types.d.ts +47 -4
- package/dist/agent/types.js +2 -0
- package/dist/agent/worktree.d.ts +36 -0
- package/dist/agent/worktree.js +86 -0
- package/dist/agents/builtin.d.ts +14 -0
- package/dist/agents/builtin.js +39 -0
- package/dist/agents/catalog.d.ts +43 -0
- package/dist/agents/catalog.js +82 -0
- package/dist/agents/discover.d.ts +35 -0
- package/dist/agents/discover.js +83 -0
- package/dist/agents/external.d.ts +82 -0
- package/dist/agents/external.js +326 -0
- package/dist/agents/parse.d.ts +18 -0
- package/dist/agents/parse.js +116 -0
- package/dist/agents/result.d.ts +32 -0
- package/dist/agents/result.js +67 -0
- package/dist/agents/task-control.d.ts +17 -0
- package/dist/agents/task-control.js +17 -0
- package/dist/agents/task-record.d.ts +78 -0
- package/dist/agents/task-record.js +141 -0
- package/dist/agents/types.d.ts +46 -0
- package/dist/agents/types.js +8 -0
- package/dist/ai/apis/anthropic-compat.d.ts +36 -0
- package/dist/ai/apis/anthropic-compat.js +92 -0
- package/dist/ai/apis/anthropic-request.d.ts +7 -6
- package/dist/ai/apis/anthropic-request.js +10 -28
- package/dist/ai/apis/cache-params.d.ts +11 -2
- package/dist/ai/apis/cache-params.js +25 -6
- package/dist/ai/apis/openai-compat.d.ts +4 -1
- package/dist/ai/apis/openai-compat.js +8 -1
- package/dist/ai/image-limits.d.ts +45 -0
- package/dist/ai/image-limits.js +68 -0
- package/dist/ai/providers/builtin.d.ts +18 -6
- package/dist/ai/providers/builtin.js +135 -6
- package/dist/ai/providers/catalog-data.js +17 -13
- package/dist/ai/providers/catalog.d.ts +60 -7
- package/dist/ai/providers/catalog.js +197 -38
- package/dist/ai/providers/channels.d.ts +33 -3
- package/dist/ai/providers/channels.js +108 -7
- package/dist/ai/providers/enrich.d.ts +6 -3
- package/dist/ai/providers/enrich.js +19 -4
- package/dist/ai/providers/models-dev-cache.d.ts +28 -24
- package/dist/ai/providers/models-dev-cache.js +92 -78
- package/dist/ai/providers/models-dev-data.d.ts +7 -0
- package/dist/ai/providers/models-dev-data.js +32 -0
- package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
- package/dist/ai/providers/models-dev-snapshot.js +137 -0
- package/dist/ai/providers/models-dev.d.ts +51 -10
- package/dist/ai/providers/models-dev.js +132 -39
- package/dist/ai/providers/registry.d.ts +20 -10
- package/dist/ai/providers/registry.js +82 -43
- package/dist/ai/types.d.ts +28 -2
- package/dist/ai/types.js +5 -0
- package/dist/bundle/ama.cjs +36203 -20499
- package/dist/checkpoints/backend.d.ts +61 -0
- package/dist/checkpoints/backend.js +135 -0
- package/dist/checkpoints/blobs.d.ts +60 -0
- package/dist/checkpoints/blobs.js +203 -0
- package/dist/checkpoints/gc.d.ts +47 -0
- package/dist/checkpoints/gc.js +144 -0
- package/dist/checkpoints/git-head.d.ts +15 -0
- package/dist/checkpoints/git-head.js +89 -0
- package/dist/checkpoints/index.d.ts +17 -0
- package/dist/checkpoints/index.js +17 -0
- package/dist/checkpoints/replay.d.ts +48 -0
- package/dist/checkpoints/replay.js +154 -0
- package/dist/checkpoints/restore.d.ts +86 -0
- package/dist/checkpoints/restore.js +263 -0
- package/dist/checkpoints/settings.d.ts +14 -0
- package/dist/checkpoints/settings.js +23 -0
- package/dist/checkpoints/shadow-git.d.ts +108 -0
- package/dist/checkpoints/shadow-git.js +491 -0
- package/dist/checkpoints/shadow-restore.d.ts +25 -0
- package/dist/checkpoints/shadow-restore.js +128 -0
- package/dist/checkpoints/tracker.d.ts +64 -0
- package/dist/checkpoints/tracker.js +192 -0
- package/dist/checkpoints/types.d.ts +99 -0
- package/dist/checkpoints/types.js +12 -0
- package/dist/cli/args.d.ts +8 -4
- package/dist/cli/args.js +17 -97
- package/dist/cli/bootstrap.js +13 -1
- package/dist/cli/codemode-notice.d.ts +3 -2
- package/dist/cli/codemode-notice.js +3 -2
- package/dist/cli/compose-agents.d.ts +27 -0
- package/dist/cli/compose-agents.js +111 -0
- package/dist/cli/compose-extensions.d.ts +29 -0
- package/dist/cli/compose-extensions.js +44 -0
- package/dist/cli/compose-session.d.ts +3 -0
- package/dist/cli/compose-session.js +47 -4
- package/dist/cli/compose.d.ts +3 -0
- package/dist/cli/compose.js +33 -6
- package/dist/cli/deps.d.ts +6 -0
- package/dist/cli/exit-codes.d.ts +10 -0
- package/dist/cli/exit-codes.js +12 -0
- package/dist/cli/help-text.d.ts +4 -0
- package/dist/cli/help-text.js +102 -0
- package/dist/cli/startup-screen.js +5 -3
- package/dist/cli/startup-steps.js +7 -1
- package/dist/cli/subcommands/config.d.ts +4 -1
- package/dist/cli/subcommands/config.js +17 -6
- package/dist/cli/subcommands/doctor.js +21 -0
- package/dist/cli/subcommands/models-discover.js +5 -6
- package/dist/cli/subcommands/models.d.ts +2 -0
- package/dist/cli/subcommands/models.js +33 -14
- package/dist/cli/subcommands/providers.js +5 -6
- package/dist/cli/subcommands/sessions.d.ts +3 -1
- package/dist/cli/subcommands/sessions.js +36 -2
- package/dist/codemode/capability.d.ts +24 -7
- package/dist/codemode/capability.js +38 -10
- package/dist/codemode/host-side.d.ts +14 -0
- package/dist/codemode/host-side.js +24 -1
- package/dist/codemode/tool.d.ts +1 -1
- package/dist/codemode/tool.js +6 -4
- package/dist/compaction/breaker.d.ts +25 -9
- package/dist/compaction/breaker.js +47 -17
- package/dist/compaction/estimate.d.ts +11 -3
- package/dist/compaction/estimate.js +64 -22
- package/dist/compaction/image-budget.d.ts +45 -0
- package/dist/compaction/image-budget.js +115 -0
- package/dist/compaction/post-compact.d.ts +38 -0
- package/dist/compaction/post-compact.js +152 -0
- package/dist/compaction/protect.d.ts +27 -0
- package/dist/compaction/protect.js +56 -0
- package/dist/compaction/prune-tier.d.ts +58 -12
- package/dist/compaction/prune-tier.js +120 -54
- package/dist/compaction/summarize-tier.d.ts +23 -4
- package/dist/compaction/summarize-tier.js +100 -29
- package/dist/config/checker.d.ts +28 -0
- package/dist/config/checker.js +97 -0
- package/dist/config/json-schema.js +63 -2
- package/dist/config/key-docs.js +72 -3
- package/dist/config/merge.d.ts +5 -3
- package/dist/config/merge.js +81 -7
- package/dist/config/profile.d.ts +2 -0
- package/dist/config/profile.js +2 -0
- package/dist/config/schema-w5.d.ts +18 -0
- package/dist/config/schema-w5.js +109 -0
- package/dist/config/schema.d.ts +5 -9
- package/dist/config/schema.js +68 -114
- package/dist/config/types-w5.d.ts +118 -0
- package/dist/config/types-w5.js +20 -0
- package/dist/config/types.d.ts +50 -1
- package/dist/config/types.js +12 -0
- package/dist/drivers/acp/client.d.ts +57 -0
- package/dist/drivers/acp/client.js +160 -0
- package/dist/drivers/acp/driver.d.ts +31 -0
- package/dist/drivers/acp/driver.js +274 -0
- package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
- package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
- package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
- package/dist/drivers/acp/testing/fake-agent.js +211 -0
- package/dist/drivers/acp/types.d.ts +285 -0
- package/dist/drivers/acp/types.js +36 -0
- package/dist/drivers/agents.d.ts +58 -0
- package/dist/drivers/agents.js +142 -0
- package/dist/drivers/base.d.ts +35 -0
- package/dist/drivers/base.js +59 -0
- package/dist/drivers/catalog.d.ts +46 -0
- package/dist/drivers/catalog.js +167 -0
- package/dist/drivers/env.d.ts +20 -0
- package/dist/drivers/env.js +46 -0
- package/dist/drivers/host-runners.d.ts +18 -0
- package/dist/drivers/host-runners.js +45 -0
- package/dist/drivers/jsonrpc.d.ts +58 -0
- package/dist/drivers/jsonrpc.js +180 -0
- package/dist/drivers/native/claude-normalize.d.ts +46 -0
- package/dist/drivers/native/claude-normalize.js +106 -0
- package/dist/drivers/native/claude-stream.d.ts +29 -0
- package/dist/drivers/native/claude-stream.js +456 -0
- package/dist/drivers/native/codex-app-server.d.ts +26 -0
- package/dist/drivers/native/codex-app-server.js +407 -0
- package/dist/drivers/native/codex-normalize.d.ts +38 -0
- package/dist/drivers/native/codex-normalize.js +124 -0
- package/dist/drivers/native/oneshot.d.ts +28 -0
- package/dist/drivers/native/oneshot.js +312 -0
- package/dist/drivers/permissions.d.ts +40 -0
- package/dist/drivers/permissions.js +92 -0
- package/dist/drivers/pids.d.ts +32 -0
- package/dist/drivers/pids.js +93 -0
- package/dist/drivers/pool.d.ts +28 -0
- package/dist/drivers/pool.js +96 -0
- package/dist/drivers/probe.d.ts +47 -0
- package/dist/drivers/probe.js +172 -0
- package/dist/drivers/process.d.ts +48 -0
- package/dist/drivers/process.js +100 -0
- package/dist/drivers/runner.d.ts +61 -0
- package/dist/drivers/runner.js +388 -0
- package/dist/drivers/store.d.ts +49 -0
- package/dist/drivers/store.js +91 -0
- package/dist/drivers/turn.d.ts +41 -0
- package/dist/drivers/turn.js +99 -0
- package/dist/drivers/types.d.ts +122 -0
- package/dist/drivers/types.js +11 -0
- package/dist/git/info.d.ts +75 -0
- package/dist/git/info.js +191 -0
- package/dist/hooks/protocol.js +6 -1
- package/dist/hooks/types.d.ts +10 -1
- package/dist/hooks/types.js +2 -0
- package/dist/host/api-impl.d.ts +7 -0
- package/dist/host/api-impl.js +15 -0
- package/dist/host/types.d.ts +24 -2
- package/dist/host/types.js +4 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/modes/acp/acp-events.d.ts +46 -0
- package/dist/modes/acp/acp-events.js +233 -0
- package/dist/modes/acp/acp-mode.d.ts +17 -0
- package/dist/modes/acp/acp-mode.js +47 -0
- package/dist/modes/acp/acp-server.d.ts +79 -0
- package/dist/modes/acp/acp-server.js +315 -0
- package/dist/modes/commands-core.d.ts +7 -1
- package/dist/modes/commands-core.js +55 -0
- package/dist/modes/image-input.d.ts +12 -4
- package/dist/modes/image-input.js +22 -5
- package/dist/modes/interactive/agent-panels.d.ts +14 -0
- package/dist/modes/interactive/agent-panels.js +103 -0
- package/dist/modes/interactive/agent-ui.d.ts +73 -0
- package/dist/modes/interactive/agent-ui.js +234 -0
- package/dist/modes/interactive/approval-dialog.d.ts +21 -4
- package/dist/modes/interactive/approval-dialog.js +98 -20
- package/dist/modes/interactive/approval-merge.d.ts +41 -0
- package/dist/modes/interactive/approval-merge.js +89 -0
- package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
- package/dist/modes/interactive/clipboard-paste.js +28 -0
- package/dist/modes/interactive/commands.d.ts +9 -1
- package/dist/modes/interactive/commands.js +19 -0
- package/dist/modes/interactive/double-esc.d.ts +20 -0
- package/dist/modes/interactive/double-esc.js +34 -0
- package/dist/modes/interactive/event-notices.d.ts +32 -0
- package/dist/modes/interactive/event-notices.js +79 -0
- package/dist/modes/interactive/external-editor.d.ts +16 -0
- package/dist/modes/interactive/external-editor.js +39 -0
- package/dist/modes/interactive/interactive-mode.d.ts +14 -1
- package/dist/modes/interactive/interactive-mode.js +134 -136
- package/dist/modes/interactive/key-dispatch.d.ts +16 -2
- package/dist/modes/interactive/key-dispatch.js +49 -1
- package/dist/modes/interactive/line/line-mode.d.ts +2 -1
- package/dist/modes/interactive/line/line-mode.js +22 -5
- package/dist/modes/interactive/line/line-render.d.ts +2 -1
- package/dist/modes/interactive/line/line-render.js +40 -4
- package/dist/modes/interactive/message-view.d.ts +1 -1
- package/dist/modes/interactive/message-view.js +24 -2
- package/dist/modes/interactive/panels.d.ts +18 -1
- package/dist/modes/interactive/panels.js +19 -5
- package/dist/modes/interactive/plan-command.d.ts +40 -0
- package/dist/modes/interactive/plan-command.js +129 -0
- package/dist/modes/interactive/plan-dialog.d.ts +98 -0
- package/dist/modes/interactive/plan-dialog.js +290 -0
- package/dist/modes/interactive/plan-flow.d.ts +34 -0
- package/dist/modes/interactive/plan-flow.js +98 -0
- package/dist/modes/interactive/rewind-command.d.ts +31 -0
- package/dist/modes/interactive/rewind-command.js +106 -0
- package/dist/modes/interactive/rewind-flow.d.ts +37 -0
- package/dist/modes/interactive/rewind-flow.js +151 -0
- package/dist/modes/interactive/rewind-list.d.ts +36 -0
- package/dist/modes/interactive/rewind-list.js +123 -0
- package/dist/modes/interactive/rewind-panel.d.ts +77 -0
- package/dist/modes/interactive/rewind-panel.js +309 -0
- package/dist/modes/interactive/rewind-text.d.ts +40 -0
- package/dist/modes/interactive/rewind-text.js +139 -0
- package/dist/modes/interactive/session-events.d.ts +24 -0
- package/dist/modes/interactive/session-events.js +96 -0
- package/dist/modes/interactive/status-area.d.ts +73 -0
- package/dist/modes/interactive/status-area.js +190 -0
- package/dist/modes/interactive/status-bar.d.ts +99 -11
- package/dist/modes/interactive/status-bar.js +273 -90
- package/dist/modes/interactive/status-line.d.ts +33 -0
- package/dist/modes/interactive/status-line.js +113 -0
- package/dist/modes/interactive/subagent-view.d.ts +56 -0
- package/dist/modes/interactive/subagent-view.js +154 -0
- package/dist/modes/interactive/tasks-report.d.ts +27 -0
- package/dist/modes/interactive/tasks-report.js +114 -0
- package/dist/modes/interactive/tool-view.d.ts +12 -2
- package/dist/modes/interactive/tool-view.js +34 -4
- package/dist/modes/print/print-mode.d.ts +13 -4
- package/dist/modes/print/print-mode.js +56 -12
- package/dist/modes/rpc/commands.d.ts +9 -0
- package/dist/modes/rpc/commands.js +44 -0
- package/dist/modes/rpc/rpc-mode.js +7 -1
- package/dist/modes/session-report.d.ts +11 -0
- package/dist/modes/session-report.js +48 -1
- package/dist/permissions/auto-safe.d.ts +5 -0
- package/dist/permissions/auto-safe.js +18 -0
- package/dist/permissions/classifier.d.ts +4 -0
- package/dist/permissions/classifier.js +2 -0
- package/dist/permissions/modes.js +1 -1
- package/dist/permissions/pipeline.d.ts +43 -4
- package/dist/permissions/pipeline.js +114 -9
- package/dist/permissions/readonly-bash.d.ts +30 -0
- package/dist/permissions/readonly-bash.js +118 -0
- package/dist/permissions/types.d.ts +42 -0
- package/dist/plan/compose.d.ts +9 -0
- package/dist/plan/compose.js +19 -0
- package/dist/plan/controller.d.ts +71 -0
- package/dist/plan/controller.js +27 -0
- package/dist/plan/done-markers.d.ts +17 -0
- package/dist/plan/done-markers.js +51 -0
- package/dist/plan/extract.d.ts +29 -0
- package/dist/plan/extract.js +160 -0
- package/dist/plan/prompts.d.ts +36 -0
- package/dist/plan/prompts.js +89 -0
- package/dist/plan/store.d.ts +37 -0
- package/dist/plan/store.js +90 -0
- package/dist/rpc.d.ts +58 -2
- package/dist/rpc.js +7 -0
- package/dist/sandbox/bash.d.ts +74 -0
- package/dist/sandbox/bash.js +126 -0
- package/dist/sandbox/detect.d.ts +48 -0
- package/dist/sandbox/detect.js +149 -0
- package/dist/sandbox/index.d.ts +5 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/profile.d.ts +33 -0
- package/dist/sandbox/profile.js +76 -0
- package/dist/sandbox/wrap.d.ts +29 -0
- package/dist/sandbox/wrap.js +117 -0
- package/dist/sdk.d.ts +33 -2
- package/dist/sdk.js +24 -2
- package/dist/session/types.d.ts +3 -1
- package/dist/session/types.js +1 -0
- package/dist/skills/builtin.d.ts +31 -0
- package/dist/skills/builtin.js +109 -0
- package/dist/skills/discover.d.ts +2 -1
- package/dist/skills/index-prompt.js +5 -8
- package/dist/tools/background-jobs.d.ts +71 -0
- package/dist/tools/background-jobs.js +198 -0
- package/dist/tools/bash.d.ts +53 -1
- package/dist/tools/bash.js +158 -7
- package/dist/tools/clipboard-image.d.ts +44 -0
- package/dist/tools/clipboard-image.js +148 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.js +18 -3
- package/dist/tools/image-file.d.ts +38 -3
- package/dist/tools/image-file.js +81 -10
- package/dist/tools/image-resize.d.ts +58 -0
- package/dist/tools/image-resize.js +97 -0
- package/dist/tools/presets.d.ts +7 -2
- package/dist/tools/presets.js +11 -4
- package/dist/tools/read.d.ts +5 -2
- package/dist/tools/read.js +13 -10
- package/dist/tools/registry.d.ts +7 -1
- package/dist/tools/registry.js +27 -4
- package/dist/tools/task-ctl.d.ts +22 -0
- package/dist/tools/task-ctl.js +116 -0
- package/dist/tools/task.d.ts +22 -10
- package/dist/tools/task.js +66 -26
- package/dist/tools/todo.d.ts +22 -2
- package/dist/tools/todo.js +58 -14
- package/dist/tools/truncate.d.ts +15 -0
- package/dist/tools/truncate.js +25 -0
- package/dist/tools/types.d.ts +113 -0
- package/dist/tools/types.js +5 -0
- package/dist/tools/write.js +3 -0
- package/dist/tui/glyphs.d.ts +4 -0
- package/dist/tui/glyphs.js +4 -0
- package/dist/tui/keybindings.d.ts +5 -0
- package/dist/tui/keybindings.js +5 -0
- package/docs/acp.md +78 -0
- package/docs/agents.md +250 -0
- package/docs/codemode.md +12 -8
- package/docs/hooks.md +26 -22
- package/docs/permissions.md +77 -13
- package/docs/plan.md +107 -0
- package/docs/providers.md +228 -52
- package/docs/rewind-plan.md +181 -0
- package/docs/rpc.md +92 -5
- package/docs/sandbox.md +215 -0
- package/docs/session-format.md +41 -21
- package/docs/sessions.md +41 -1
- package/docs/tui-design.md +751 -0
- package/docs/tui.md +125 -6
- package/package.json +13 -2
|
@@ -6,6 +6,9 @@ import { THINKING_LEVELS } from "../../../ai/thinking.js";
|
|
|
6
6
|
import { listSessions } from "../../../cli/compose-store.js";
|
|
7
7
|
import { AUTO_LAYER_TEXT, permissionModeLines } from "../../../permissions/modes.js";
|
|
8
8
|
import { cacheEventNotice, warmSentNotice } from "../../session-report.js";
|
|
9
|
+
import { isFirstRunRequest, sourceLabel } from "../approval-dialog.js";
|
|
10
|
+
import { LIMIT_WARNING, backgroundJobText, limitReachedText, modelFallbackText, } from "../event-notices.js";
|
|
11
|
+
import { taskStatusText } from "../tasks-report.js";
|
|
9
12
|
const SUMMARY_KEYS = ["command", "path", "pattern", "file_path", "url", "description", "name"];
|
|
10
13
|
/** 工具参数的一行摘要(第一个常见字段,折叠换行、截到 80 字符)。 */
|
|
11
14
|
export function argsSummary(args) {
|
|
@@ -21,8 +24,18 @@ export function argsSummary(args) {
|
|
|
21
24
|
}
|
|
22
25
|
return "";
|
|
23
26
|
}
|
|
24
|
-
export function approvalQuestion(request) {
|
|
25
|
-
const
|
|
27
|
+
export function approvalQuestion(request, taskAgent) {
|
|
28
|
+
const label = sourceLabel(request, taskAgent);
|
|
29
|
+
const task = label === undefined ? "" : `${label} `;
|
|
30
|
+
const origin = request.context?.origin;
|
|
31
|
+
if (origin !== undefined) {
|
|
32
|
+
const where = origin.toolCall.locations?.[0];
|
|
33
|
+
return `${task}允许 ${origin.toolCall.title}${where !== undefined ? ` ${where}` : ""}?[y 允许 / a 本会话都允许 / N 拒绝] `;
|
|
34
|
+
}
|
|
35
|
+
if (isFirstRunRequest(request)) {
|
|
36
|
+
const input = request.input;
|
|
37
|
+
return `${task}${String(input["note"])} 允许?[y 允许 / N 拒绝] `;
|
|
38
|
+
}
|
|
26
39
|
const summary = argsSummary(request.input);
|
|
27
40
|
const auto = request.autoDecision;
|
|
28
41
|
const why = request.reason === "dangerous"
|
|
@@ -131,11 +144,34 @@ export class EventPrinter {
|
|
|
131
144
|
this.failures++;
|
|
132
145
|
this.line(`ama: 错误:${error}`, true);
|
|
133
146
|
}
|
|
134
|
-
// 失败时 warning
|
|
135
|
-
if (event.warning !== undefined &&
|
|
147
|
+
// 失败时 warning 就是同一条错误文本,不再重复打印;预算到限已由 limit_reached 说明
|
|
148
|
+
if (event.warning !== undefined &&
|
|
149
|
+
event.warning !== error &&
|
|
150
|
+
event.warning !== LIMIT_WARNING)
|
|
136
151
|
this.line(`ama: ${event.warning}`, true);
|
|
137
152
|
return;
|
|
138
153
|
}
|
|
154
|
+
// [W5-U] 第五波事件
|
|
155
|
+
case "plan_proposed": {
|
|
156
|
+
const file = event.filePath !== undefined ? `(${event.filePath})` : "";
|
|
157
|
+
this.line(`◇ 计划 v${event.version} 待审批${file}:/plan approve [模式|fresh] 批准 · /plan reject 放弃 · 直接输入修改意见`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
case "subagent_start":
|
|
161
|
+
this.line(` ↳ ${event.taskId} ${event.agent}${event.background ? "(后台)" : ""} 开始`);
|
|
162
|
+
return;
|
|
163
|
+
case "subagent_end":
|
|
164
|
+
this.line(` ↳ ${event.taskId} ${taskStatusText(event.status)}`);
|
|
165
|
+
return;
|
|
166
|
+
case "limit_reached":
|
|
167
|
+
this.line(`ama: ${limitReachedText(event)}`, true);
|
|
168
|
+
return;
|
|
169
|
+
case "model_fallback":
|
|
170
|
+
this.line(`ama: ${modelFallbackText(event)}`, true);
|
|
171
|
+
return;
|
|
172
|
+
case "background_job":
|
|
173
|
+
this.line(`ama: ${backgroundJobText(event)}`, true);
|
|
174
|
+
return;
|
|
139
175
|
default:
|
|
140
176
|
return;
|
|
141
177
|
}
|
|
@@ -47,7 +47,7 @@ export declare class PrefixedText implements Component {
|
|
|
47
47
|
render(width: number): string[];
|
|
48
48
|
invalidate(): void;
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
export declare function displayText(text: string): string;
|
|
51
51
|
export declare function estimateTokens(text: string): number;
|
|
52
52
|
export declare function contentText(content: string | readonly ContentBlock[]): string;
|
|
53
53
|
/** 一条助手消息:按内容块(思考 / 文本)同步子组件;工具调用块由 tool-view 单独显示。 */
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { Card, Container, Markdown, Spacer, Text, visibleWidth, wrapTextWithAnsi, } from "../../tui.js";
|
|
18
18
|
import { formatCost, formatTokens } from "./status-bar.js";
|
|
19
|
+
import { notificationSummary } from "./subagent-view.js";
|
|
20
|
+
import { PLAN_APPROVED_PROMPT } from "../../plan/prompts.js";
|
|
19
21
|
/** 退出摘要的时长:不足 1 分钟按秒,否则按分钟。 */
|
|
20
22
|
function sessionDuration(ms) {
|
|
21
23
|
const seconds = Math.max(0, Math.round(ms / 1000));
|
|
@@ -60,7 +62,11 @@ export const ORIGIN_LABELS = {
|
|
|
60
62
|
steer: "插话",
|
|
61
63
|
followUp: "之后",
|
|
62
64
|
host: "宿主",
|
|
65
|
+
task: "子 Agent 通知",
|
|
66
|
+
plan: "计划",
|
|
63
67
|
};
|
|
68
|
+
/** [W5-U] origin 为 plan 的交接消息(给模型的英文开场)在消息区的说法。 */
|
|
69
|
+
const PLAN_HANDOFF_TEXT = "按批准的计划开始执行";
|
|
64
70
|
/** 首行带前缀、续行按 `indent` 缩进的文本(用户消息、排队消息)。 */
|
|
65
71
|
export class PrefixedText {
|
|
66
72
|
prefix;
|
|
@@ -155,6 +161,11 @@ class ThinkingView {
|
|
|
155
161
|
}
|
|
156
162
|
}
|
|
157
163
|
/** 粗估 token(4 字符 ≈ 1 token),只用于思考块的流式计数。 */
|
|
164
|
+
/** [W5-U] 计划块的开闭标签(独占一行)只给模型与提取用,消息区不显示(计划正文照常渲染)。 */
|
|
165
|
+
const PLAN_TAG_LINE = /^[ \t]*<\/?proposed_plan>[ \t]*$/gm;
|
|
166
|
+
export function displayText(text) {
|
|
167
|
+
return text.includes("proposed_plan>") ? text.replace(PLAN_TAG_LINE, "") : text;
|
|
168
|
+
}
|
|
158
169
|
export function estimateTokens(text) {
|
|
159
170
|
return Math.ceil(text.length / 4);
|
|
160
171
|
}
|
|
@@ -214,8 +225,9 @@ export class AssistantView extends Container {
|
|
|
214
225
|
if (block.text.trim() === "")
|
|
215
226
|
return;
|
|
216
227
|
const view = this.part(index, () => this.options.markdown === false ? new Text("") : new Markdown("", { theme }));
|
|
217
|
-
|
|
218
|
-
|
|
228
|
+
const text = displayText(block.text);
|
|
229
|
+
if (view.getText() !== text)
|
|
230
|
+
view.setText(text);
|
|
219
231
|
order.push(view);
|
|
220
232
|
});
|
|
221
233
|
const gap = this.options.compact !== true;
|
|
@@ -339,6 +351,16 @@ export class MessageView extends Container {
|
|
|
339
351
|
return;
|
|
340
352
|
}
|
|
341
353
|
const label = ORIGIN_LABELS[origin] ?? origin;
|
|
354
|
+
// [W5-U] 后台子 Agent 的 <task-notification> 是给模型的全文,消息区只留一行
|
|
355
|
+
const summary = origin === "task"
|
|
356
|
+
? notificationSummary(text)
|
|
357
|
+
: origin === "plan" && text === PLAN_APPROVED_PROMPT
|
|
358
|
+
? PLAN_HANDOFF_TEXT
|
|
359
|
+
: undefined;
|
|
360
|
+
if (summary !== undefined) {
|
|
361
|
+
this.add(new PrefixedText(t.fg("dim", t.glyphs.queued) + " " + t.fg("muted", `${label} `), t.fg("muted", summary)));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
342
364
|
this.add(new PrefixedText(t.fg("dim", t.glyphs.queued) + " " + t.fg("muted", `${label} `), t.fg("muted", text)));
|
|
343
365
|
}
|
|
344
366
|
newAssistant() {
|
|
@@ -4,12 +4,29 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - `/session`:标题 `会话 <id 前 8 位> · <文件>`;模型 / 消息 / 用量 / 上下文(余量表,阈值着色),
|
|
6
6
|
* 空一行后「缓存」段(与 `/cache` 共用 `cacheRows`);
|
|
7
|
+
* - [W5-U] `/session` 多「子 Agent」行(任务汇总)与「外部 Agent」段(按 Agent 的运行次数与用量,单位不换算);
|
|
7
8
|
* - `/permissions`:权限模式、判定顺序(折行对齐值列)、规则(allow success、deny error、来源 dim)、
|
|
8
9
|
* 最近的 auto 判定。
|
|
9
10
|
*/
|
|
10
11
|
import type { AgentSession } from "../../agent/types.js";
|
|
11
12
|
import type { Runtime } from "../../cli/runtime.js";
|
|
12
|
-
import { type Component, type Theme } from "../../tui.js";
|
|
13
|
+
import { KeyValue, type Component, type KeyValueRow, type Theme } from "../../tui.js";
|
|
14
|
+
/** 多段内容按顺序拼起来(段之间不加空行,由调用方放空串)。 */
|
|
15
|
+
export declare class Stack implements Component {
|
|
16
|
+
private readonly parts;
|
|
17
|
+
constructor(parts: readonly (Component | string)[]);
|
|
18
|
+
render(width: number): string[];
|
|
19
|
+
invalidate(): void;
|
|
20
|
+
}
|
|
21
|
+
/** 缩进若干列的子组件。 */
|
|
22
|
+
export declare class Indent implements Component {
|
|
23
|
+
private readonly child;
|
|
24
|
+
private readonly columns;
|
|
25
|
+
constructor(child: Component, columns: number);
|
|
26
|
+
render(width: number): string[];
|
|
27
|
+
invalidate(): void;
|
|
28
|
+
}
|
|
29
|
+
export declare function keyValue(rows: readonly KeyValueRow[], theme: Theme, wrap?: boolean): KeyValue;
|
|
13
30
|
export declare function sessionPanel(session: AgentSession, theme: Theme, options?: {
|
|
14
31
|
now?: number;
|
|
15
32
|
home?: string;
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - `/session`:标题 `会话 <id 前 8 位> · <文件>`;模型 / 消息 / 用量 / 上下文(余量表,阈值着色),
|
|
6
6
|
* 空一行后「缓存」段(与 `/cache` 共用 `cacheRows`);
|
|
7
|
+
* - [W5-U] `/session` 多「子 Agent」行(任务汇总)与「外部 Agent」段(按 Agent 的运行次数与用量,单位不换算);
|
|
7
8
|
* - `/permissions`:权限模式、判定顺序(折行对齐值列)、规则(allow success、deny error、来源 dim)、
|
|
8
9
|
* 最近的 auto 判定。
|
|
9
10
|
*/
|
|
10
11
|
import { AUTO_LAYER_TEXT, permissionModeLabel } from "../../permissions/modes.js";
|
|
11
12
|
import { Card, KeyValue, Meter, } from "../../tui.js";
|
|
12
|
-
import { cacheRows, formatTokenCount, formatUsd } from "../session-report.js";
|
|
13
|
+
import { cacheRows, externalRows, formatTokenCount, formatUsd, taskStatsText, } from "../session-report.js";
|
|
13
14
|
import { tildePath } from "../../cli/startup-screen.js";
|
|
14
15
|
/** 多段内容按顺序拼起来(段之间不加空行,由调用方放空串)。 */
|
|
15
|
-
class Stack {
|
|
16
|
+
export class Stack {
|
|
16
17
|
parts;
|
|
17
18
|
constructor(parts) {
|
|
18
19
|
this.parts = parts;
|
|
@@ -27,7 +28,7 @@ class Stack {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
/** 缩进若干列的子组件。 */
|
|
30
|
-
class Indent {
|
|
31
|
+
export class Indent {
|
|
31
32
|
child;
|
|
32
33
|
columns;
|
|
33
34
|
constructor(child, columns) {
|
|
@@ -44,7 +45,7 @@ class Indent {
|
|
|
44
45
|
this.child.invalidate();
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
function keyValue(rows, theme, wrap = false) {
|
|
48
|
+
export function keyValue(rows, theme, wrap = false) {
|
|
48
49
|
return new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...(wrap ? { wrap: true } : {}) });
|
|
49
50
|
}
|
|
50
51
|
function cacheSection(session, theme, now) {
|
|
@@ -93,8 +94,21 @@ export function sessionPanel(session, theme, options = {}) {
|
|
|
93
94
|
},
|
|
94
95
|
{ key: "上下文", value: meter + window },
|
|
95
96
|
];
|
|
97
|
+
const tasks = taskStatsText(session);
|
|
98
|
+
if (tasks !== undefined)
|
|
99
|
+
rows.push({ key: "子 Agent", value: tasks });
|
|
100
|
+
const external = externalRows(session);
|
|
101
|
+
const externalSection = external.length > 0
|
|
102
|
+
? ["", theme.bold("外部 Agent"), new Indent(keyValue(external, theme), 2)]
|
|
103
|
+
: [];
|
|
96
104
|
const file = state.sessionFile === undefined ? "未落盘" : tildePath(state.sessionFile, options.home);
|
|
97
|
-
|
|
105
|
+
const parts = [
|
|
106
|
+
keyValue(rows, theme),
|
|
107
|
+
"",
|
|
108
|
+
...cacheSection(session, theme, now),
|
|
109
|
+
...externalSection,
|
|
110
|
+
];
|
|
111
|
+
return new Card(new Stack(parts), {
|
|
98
112
|
theme,
|
|
99
113
|
title: `会话 ${state.sessionId.slice(0, 8)}`,
|
|
100
114
|
subtitle: file,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/plan` 的语义(line 模式与交互模式共用,经 commands-core)。[W5-U]
|
|
3
|
+
*
|
|
4
|
+
* - `/plan`:当前计划与状态(版本、状态、文件、步骤、待办进度、所处模式);
|
|
5
|
+
* - `/plan approve [模式|fresh]`:批准待审批的计划(没有计划块时把上一条回复当作计划,docs/wave5-plan.md
|
|
6
|
+
* §6.3);模式缺省回到进入 plan 前的模式,`fresh` 在新会话里执行(新建会话 → `adopt(plan)` → 发计划
|
|
7
|
+
* 全文);
|
|
8
|
+
* - `/plan reject`:放弃待审批的计划(留在 Plan 模式);
|
|
9
|
+
* - `/plan <目标>`:进入 Plan 模式并把目标作为提示发出。
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentSession, PlanData } from "../../agent/types.js";
|
|
12
|
+
import type { SwitchRequest } from "../../cli/compose-session.js";
|
|
13
|
+
import type { PermissionMode } from "../../permissions/types.js";
|
|
14
|
+
import { type PlanController } from "../../plan/controller.js";
|
|
15
|
+
export declare const PLAN_USAGE = "\u7528\u6CD5\uFF1A/plan [\u76EE\u6807] | /plan approve [\u6A21\u5F0F|fresh] | /plan reject";
|
|
16
|
+
export declare function planStatusText(status: PlanData["status"]): string;
|
|
17
|
+
/** 计划的标题:第一个 `#` 标题,没有时取第一行非空文本。 */
|
|
18
|
+
export declare function planTitle(plan: Pick<PlanData, "markdown">): string;
|
|
19
|
+
/** 批准后的执行模式(缺省回到进入 plan 前的模式;进入前就是 plan 则 default)。 */
|
|
20
|
+
export declare function defaultExecutionMode(controller: PlanController): PermissionMode;
|
|
21
|
+
/** `/plan` 的纯文本说明。 */
|
|
22
|
+
export declare function describePlan(controller: PlanController, session: AgentSession): string;
|
|
23
|
+
export interface PlanCommandContext {
|
|
24
|
+
switchSession(request: SwitchRequest): Promise<AgentSession>;
|
|
25
|
+
}
|
|
26
|
+
export type PlanCommandResult = {
|
|
27
|
+
kind: "handled";
|
|
28
|
+
message: string;
|
|
29
|
+
wait?: boolean;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "prompt";
|
|
32
|
+
text: string;
|
|
33
|
+
};
|
|
34
|
+
/** 「新上下文执行」:新建会话、记下计划与 todo、切到执行模式,返回首条消息。 */
|
|
35
|
+
export declare function approveFresh(controller: PlanController, plan: PlanData, mode: PermissionMode, ctx: PlanCommandContext, editedMarkdown?: string): Promise<{
|
|
36
|
+
session: AgentSession;
|
|
37
|
+
prompt: string;
|
|
38
|
+
plan: PlanData;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function planCommand(session: AgentSession, args: string, ctx: PlanCommandContext): Promise<PlanCommandResult>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/plan` 的语义(line 模式与交互模式共用,经 commands-core)。[W5-U]
|
|
3
|
+
*
|
|
4
|
+
* - `/plan`:当前计划与状态(版本、状态、文件、步骤、待办进度、所处模式);
|
|
5
|
+
* - `/plan approve [模式|fresh]`:批准待审批的计划(没有计划块时把上一条回复当作计划,docs/wave5-plan.md
|
|
6
|
+
* §6.3);模式缺省回到进入 plan 前的模式,`fresh` 在新会话里执行(新建会话 → `adopt(plan)` → 发计划
|
|
7
|
+
* 全文);
|
|
8
|
+
* - `/plan reject`:放弃待审批的计划(留在 Plan 模式);
|
|
9
|
+
* - `/plan <目标>`:进入 Plan 模式并把目标作为提示发出。
|
|
10
|
+
*/
|
|
11
|
+
import { AmaError } from "../../errors.js";
|
|
12
|
+
import { parsePermissionMode, permissionModeLabel } from "../../permissions/modes.js";
|
|
13
|
+
import { planController } from "../../plan/controller.js";
|
|
14
|
+
import { executionMode } from "../../plan/store.js";
|
|
15
|
+
export const PLAN_USAGE = "用法:/plan [目标] | /plan approve [模式|fresh] | /plan reject";
|
|
16
|
+
const STATUS_TEXT = {
|
|
17
|
+
proposed: "待审批",
|
|
18
|
+
approved: "已批准",
|
|
19
|
+
rejected: "已放弃",
|
|
20
|
+
superseded: "已被新版本取代",
|
|
21
|
+
};
|
|
22
|
+
export function planStatusText(status) {
|
|
23
|
+
return STATUS_TEXT[status];
|
|
24
|
+
}
|
|
25
|
+
/** 计划的标题:第一个 `#` 标题,没有时取第一行非空文本。 */
|
|
26
|
+
export function planTitle(plan) {
|
|
27
|
+
const lines = plan.markdown.split(/\r?\n/).map((l) => l.trim());
|
|
28
|
+
const heading = lines.find((l) => /^#{1,6}\s+\S/.test(l));
|
|
29
|
+
if (heading !== undefined)
|
|
30
|
+
return heading.replace(/^#{1,6}\s+/, "");
|
|
31
|
+
return lines.find((l) => l !== "" && !/^<\/?proposed_plan>$/.test(l)) ?? "(无标题)";
|
|
32
|
+
}
|
|
33
|
+
/** 批准后的执行模式(缺省回到进入 plan 前的模式;进入前就是 plan 则 default)。 */
|
|
34
|
+
export function defaultExecutionMode(controller) {
|
|
35
|
+
return executionMode(undefined, controller.prePlanMode());
|
|
36
|
+
}
|
|
37
|
+
/** `/plan` 的纯文本说明。 */
|
|
38
|
+
export function describePlan(controller, session) {
|
|
39
|
+
const plan = controller.current();
|
|
40
|
+
const mode = session.state.permissionMode;
|
|
41
|
+
const pre = controller.prePlanMode();
|
|
42
|
+
const modeLine = mode === "plan"
|
|
43
|
+
? `模式:Plan(批准后回到 ${permissionModeLabel(executionMode(undefined, pre))})`
|
|
44
|
+
: `模式:${permissionModeLabel(mode)}`;
|
|
45
|
+
if (plan === null) {
|
|
46
|
+
return mode === "plan"
|
|
47
|
+
? [modeLine, "还没有计划:模型给出 <proposed_plan> 后在这里审批"].join("\n")
|
|
48
|
+
: "没有计划。/plan <目标> 进入 Plan 模式";
|
|
49
|
+
}
|
|
50
|
+
const lines = [
|
|
51
|
+
`计划 v${plan.version} · ${planStatusText(plan.status)} · ${planTitle(plan)}`,
|
|
52
|
+
...(plan.filePath !== undefined ? [`文件:${plan.filePath}`] : []),
|
|
53
|
+
modeLine,
|
|
54
|
+
];
|
|
55
|
+
if (plan.steps.length > 0) {
|
|
56
|
+
lines.push(`步骤(${plan.steps.length}):`);
|
|
57
|
+
for (const step of plan.steps)
|
|
58
|
+
lines.push(` ${step.id} ${step.text}`);
|
|
59
|
+
}
|
|
60
|
+
const todos = controller.todos();
|
|
61
|
+
if (todos.length > 0) {
|
|
62
|
+
const done = todos.filter((t) => t.status === "done").length;
|
|
63
|
+
const current = todos.find((t) => t.status === "in_progress");
|
|
64
|
+
lines.push(`待办:${done}/${todos.length} 完成${current !== undefined ? ` · 进行中 ${current.text}` : ""}`);
|
|
65
|
+
}
|
|
66
|
+
if (plan.status === "proposed")
|
|
67
|
+
lines.push("/plan approve [模式|fresh] 批准 · /plan reject 放弃 · 直接输入修改意见");
|
|
68
|
+
return lines.join("\n");
|
|
69
|
+
}
|
|
70
|
+
/** 「新上下文执行」:新建会话、记下计划与 todo、切到执行模式,返回首条消息。 */
|
|
71
|
+
export async function approveFresh(controller, plan, mode, ctx, editedMarkdown) {
|
|
72
|
+
const result = await controller.respond({
|
|
73
|
+
planId: plan.id,
|
|
74
|
+
decision: "approve_fresh",
|
|
75
|
+
mode,
|
|
76
|
+
...(editedMarkdown !== undefined ? { editedMarkdown } : {}),
|
|
77
|
+
});
|
|
78
|
+
const next = await ctx.switchSession({ kind: "new" });
|
|
79
|
+
planController(next)?.adopt(result.plan);
|
|
80
|
+
next.setPermissionMode(result.mode ?? mode);
|
|
81
|
+
return { session: next, prompt: result.freshPrompt ?? result.plan.markdown, plan: result.plan };
|
|
82
|
+
}
|
|
83
|
+
function pendingOrLastReply(controller) {
|
|
84
|
+
const plan = controller.pending() ?? controller.proposeFromLastReply();
|
|
85
|
+
if (plan === undefined)
|
|
86
|
+
throw new AmaError("plan_not_found", "没有待审批的计划");
|
|
87
|
+
return plan;
|
|
88
|
+
}
|
|
89
|
+
export async function planCommand(session, args, ctx) {
|
|
90
|
+
const controller = planController(session);
|
|
91
|
+
const [verb = "", ...rest] = args.split(/\s+/).filter((s) => s !== "");
|
|
92
|
+
if (controller === undefined) {
|
|
93
|
+
if (args === "")
|
|
94
|
+
return { kind: "handled", message: "当前会话没有 Plan 能力" };
|
|
95
|
+
throw new AmaError("invalid_arguments", "当前会话没有 Plan 能力");
|
|
96
|
+
}
|
|
97
|
+
if (verb === "")
|
|
98
|
+
return { kind: "handled", message: describePlan(controller, session) };
|
|
99
|
+
if (verb === "approve") {
|
|
100
|
+
if (rest.length > 1)
|
|
101
|
+
throw new AmaError("invalid_arguments", PLAN_USAGE);
|
|
102
|
+
const plan = pendingOrLastReply(controller);
|
|
103
|
+
const arg = rest[0];
|
|
104
|
+
if (arg === "fresh") {
|
|
105
|
+
const fresh = await approveFresh(controller, plan, defaultExecutionMode(controller), ctx);
|
|
106
|
+
return { kind: "prompt", text: fresh.prompt };
|
|
107
|
+
}
|
|
108
|
+
const mode = arg === undefined ? defaultExecutionMode(controller) : parsePermissionMode(arg);
|
|
109
|
+
if (mode === undefined || mode === "plan")
|
|
110
|
+
throw new AmaError("invalid_arguments", `执行模式无效:${arg ?? ""}(${PLAN_USAGE})`);
|
|
111
|
+
const result = await controller.respond({ planId: plan.id, decision: "approve", mode });
|
|
112
|
+
return {
|
|
113
|
+
kind: "handled",
|
|
114
|
+
message: `已批准计划 v${result.plan.version},以 ${permissionModeLabel(result.mode ?? mode)} 执行`,
|
|
115
|
+
wait: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (verb === "reject" && rest.length === 0) {
|
|
119
|
+
const plan = controller.pending();
|
|
120
|
+
if (plan === undefined)
|
|
121
|
+
throw new AmaError("plan_not_found", "没有待审批的计划");
|
|
122
|
+
await controller.respond({ planId: plan.id, decision: "reject" });
|
|
123
|
+
return { kind: "handled", message: `已放弃计划 v${plan.version}(仍在 Plan 模式)` };
|
|
124
|
+
}
|
|
125
|
+
// 其余:目标文本
|
|
126
|
+
if (session.state.permissionMode !== "plan")
|
|
127
|
+
session.setPermissionMode("plan");
|
|
128
|
+
return { kind: "prompt", text: args };
|
|
129
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 计划审批对话框(docs/wave5-plan.md §6.1、§6.3):底部覆盖层,与权限审批框同一手法。[W5-U]
|
|
3
|
+
*
|
|
4
|
+
* ```
|
|
5
|
+
* ╭─ 计划待审批 ──────────────────────────────────────────────╮
|
|
6
|
+
* │ 计划 v1 · 3 步 · ~/.local/share/ama/plans/3f2a9c1e-v1.md │
|
|
7
|
+
* │ 给 status-bar 加回退模型显示 │
|
|
8
|
+
* │ S1 读 status-bar.ts 与 status-area.ts │
|
|
9
|
+
* │ … │
|
|
10
|
+
* │ │
|
|
11
|
+
* │ › 1. 批准并执行 │
|
|
12
|
+
* │ 2. 批准,在新上下文执行 │
|
|
13
|
+
* │ 3. 继续修改… │
|
|
14
|
+
* │ 4. 放弃,退出 Plan 模式 │
|
|
15
|
+
* │ │
|
|
16
|
+
* │ ↑↓ 选择 · Enter 确认 · e 编辑计划 · Esc 留在 Plan │
|
|
17
|
+
* ╰───────────────────────────────────────────────────────────╯
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* - 1 / 2 之后选执行模式:回到进入前的模式(缺省)/ Accept edits / Auto;Esc 回到上一步。
|
|
21
|
+
* - 3「继续修改」:行内写意见(Enter 发送,`Ctrl+E` 改用外部编辑器写),意见作为普通用户消息、留在 plan;
|
|
22
|
+
* Esc 回到上一步。
|
|
23
|
+
* - `e`:在外部编辑器(`$VISUAL` / `$EDITOR`,TUI 挂起)里改计划全文;批准时以改后的版本(version + 1)
|
|
24
|
+
* 交接。
|
|
25
|
+
* - 4「放弃」:计划标 rejected 并退出 Plan 模式(回到进入前的模式);Esc:计划标 rejected、留在 Plan 模式
|
|
26
|
+
* (§6.1)。
|
|
27
|
+
* - 宽 < 56 时紧凑:去掉空行、按键提示缩短。ASCII 字形走 theme.glyphs。
|
|
28
|
+
*/
|
|
29
|
+
import type { PlanData } from "../../agent/types.js";
|
|
30
|
+
import type { PermissionMode } from "../../permissions/types.js";
|
|
31
|
+
import { type Component, type Focusable, type Keybindings, type OverlayHandle, type Theme } from "../../tui.js";
|
|
32
|
+
/** 对话框里最多列出的步骤数。 */
|
|
33
|
+
export declare const PLAN_DIALOG_STEPS = 6;
|
|
34
|
+
export type PlanChoice = {
|
|
35
|
+
decision: "approve" | "approve_fresh";
|
|
36
|
+
mode: PermissionMode;
|
|
37
|
+
editedMarkdown?: string;
|
|
38
|
+
} | {
|
|
39
|
+
decision: "revise";
|
|
40
|
+
feedback: string;
|
|
41
|
+
}
|
|
42
|
+
/** `exit`:放弃并退出 Plan 模式(选项 4);Esc 为 false。 */
|
|
43
|
+
| {
|
|
44
|
+
decision: "reject";
|
|
45
|
+
exit: boolean;
|
|
46
|
+
};
|
|
47
|
+
export interface PlanDialogHost {
|
|
48
|
+
theme: Theme;
|
|
49
|
+
keybindings?: Keybindings;
|
|
50
|
+
showOverlay(component: Component): OverlayHandle;
|
|
51
|
+
/** 外部编辑器:返回改后的文本,取消或失败返回 undefined。 */
|
|
52
|
+
editExternal?(text: string, kind: "plan" | "feedback"): Promise<string | undefined>;
|
|
53
|
+
/** 计划文件路径的显示(缩写家目录)。 */
|
|
54
|
+
displayPath?(path: string): string;
|
|
55
|
+
/** 重画(外部编辑器回来之后)。 */
|
|
56
|
+
render?(): void;
|
|
57
|
+
onOpen?(): void;
|
|
58
|
+
onClose?(): void;
|
|
59
|
+
}
|
|
60
|
+
export interface PlanDialogInput {
|
|
61
|
+
plan: PlanData;
|
|
62
|
+
/** 「回到进入前的模式」对应的执行模式。 */
|
|
63
|
+
preMode: PermissionMode;
|
|
64
|
+
}
|
|
65
|
+
export declare class PlanDialog implements Component, Focusable {
|
|
66
|
+
private readonly input;
|
|
67
|
+
private readonly host;
|
|
68
|
+
private readonly done;
|
|
69
|
+
focused: boolean;
|
|
70
|
+
private stage;
|
|
71
|
+
private selected;
|
|
72
|
+
private modeSelected;
|
|
73
|
+
/** 选执行模式时记下的是 1 还是 2。 */
|
|
74
|
+
private fresh;
|
|
75
|
+
private feedback;
|
|
76
|
+
private edited;
|
|
77
|
+
constructor(input: PlanDialogInput, host: PlanDialogHost, done: (choice: PlanChoice) => void);
|
|
78
|
+
private modes;
|
|
79
|
+
handleInput(data: string): void;
|
|
80
|
+
private keys;
|
|
81
|
+
private cancelKey;
|
|
82
|
+
private mainInput;
|
|
83
|
+
private choose;
|
|
84
|
+
private modeInput;
|
|
85
|
+
private approve;
|
|
86
|
+
private reviseInput;
|
|
87
|
+
private editPlan;
|
|
88
|
+
private editFeedback;
|
|
89
|
+
render(width: number): string[];
|
|
90
|
+
/** 版本、步数、文件、标题与前几步。 */
|
|
91
|
+
private summary;
|
|
92
|
+
private optionLines;
|
|
93
|
+
private reviseLines;
|
|
94
|
+
private hint;
|
|
95
|
+
invalidate(): void;
|
|
96
|
+
}
|
|
97
|
+
/** 打开对话框,等用户选择。 */
|
|
98
|
+
export declare function openPlanDialog(host: PlanDialogHost, input: PlanDialogInput): Promise<PlanChoice>;
|