@armadra/agent 0.0.0-stage → 0.3.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 +37 -0
- package/LICENSE +21 -0
- package/README.md +470 -2
- package/dist/agent/agent.d.ts +56 -0
- package/dist/agent/agent.js +129 -0
- package/dist/agent/loop.d.ts +51 -0
- package/dist/agent/loop.js +158 -0
- package/dist/agent/queue.d.ts +25 -0
- package/dist/agent/queue.js +55 -0
- package/dist/agent/retry.d.ts +22 -0
- package/dist/agent/retry.js +92 -0
- package/dist/agent/schema.d.ts +27 -0
- package/dist/agent/schema.js +186 -0
- package/dist/agent/session-cache.d.ts +100 -0
- package/dist/agent/session-cache.js +514 -0
- package/dist/agent/session-compaction.d.ts +49 -0
- package/dist/agent/session-compaction.js +251 -0
- package/dist/agent/session-core.d.ts +103 -0
- package/dist/agent/session-core.js +7 -0
- package/dist/agent/session-run.d.ts +55 -0
- package/dist/agent/session-run.js +246 -0
- package/dist/agent/session-state.d.ts +39 -0
- package/dist/agent/session-state.js +119 -0
- package/dist/agent/session-subagent.d.ts +54 -0
- package/dist/agent/session-subagent.js +157 -0
- package/dist/agent/session-sync.d.ts +20 -0
- package/dist/agent/session-sync.js +111 -0
- package/dist/agent/session-tools.d.ts +24 -0
- package/dist/agent/session-tools.js +277 -0
- package/dist/agent/session.d.ts +117 -0
- package/dist/agent/session.js +485 -0
- package/dist/agent/system-prompt.d.ts +49 -0
- package/dist/agent/system-prompt.js +121 -0
- package/dist/agent/tool-runner.d.ts +64 -0
- package/dist/agent/tool-runner.js +309 -0
- package/dist/agent/transform.d.ts +26 -0
- package/dist/agent/transform.js +171 -0
- package/dist/agent/types.d.ts +378 -0
- package/dist/agent/types.js +21 -0
- package/dist/ai/apis/anthropic-messages.d.ts +26 -0
- package/dist/ai/apis/anthropic-messages.js +214 -0
- package/dist/ai/apis/anthropic-request.d.ts +42 -0
- package/dist/ai/apis/anthropic-request.js +282 -0
- package/dist/ai/apis/api.d.ts +28 -0
- package/dist/ai/apis/api.js +102 -0
- package/dist/ai/apis/cache-params.d.ts +48 -0
- package/dist/ai/apis/cache-params.js +163 -0
- package/dist/ai/apis/google-generative-ai.d.ts +32 -0
- package/dist/ai/apis/google-generative-ai.js +249 -0
- package/dist/ai/apis/google-request.d.ts +40 -0
- package/dist/ai/apis/google-request.js +255 -0
- package/dist/ai/apis/openai-compat.d.ts +35 -0
- package/dist/ai/apis/openai-compat.js +142 -0
- package/dist/ai/apis/openai-completions.d.ts +28 -0
- package/dist/ai/apis/openai-completions.js +246 -0
- package/dist/ai/apis/openai-request.d.ts +35 -0
- package/dist/ai/apis/openai-request.js +303 -0
- package/dist/ai/apis/openai-responses-request.d.ts +52 -0
- package/dist/ai/apis/openai-responses-request.js +266 -0
- package/dist/ai/apis/openai-responses.d.ts +28 -0
- package/dist/ai/apis/openai-responses.js +304 -0
- package/dist/ai/apis/shared.d.ts +56 -0
- package/dist/ai/apis/shared.js +179 -0
- package/dist/ai/cache/economics.d.ts +24 -0
- package/dist/ai/cache/economics.js +69 -0
- package/dist/ai/cache/fingerprint.d.ts +17 -0
- package/dist/ai/cache/fingerprint.js +39 -0
- package/dist/ai/cache/miss.d.ts +49 -0
- package/dist/ai/cache/miss.js +96 -0
- package/dist/ai/cache/reporting.d.ts +39 -0
- package/dist/ai/cache/reporting.js +103 -0
- package/dist/ai/cache/types.d.ts +94 -0
- package/dist/ai/cache/types.js +19 -0
- package/dist/ai/cache/warmer.d.ts +94 -0
- package/dist/ai/cache/warmer.js +224 -0
- package/dist/ai/context.d.ts +35 -0
- package/dist/ai/context.js +114 -0
- package/dist/ai/cost.d.ts +21 -0
- package/dist/ai/cost.js +60 -0
- package/dist/ai/event-stream.d.ts +33 -0
- package/dist/ai/event-stream.js +101 -0
- package/dist/ai/fake/fake-provider.d.ts +68 -0
- package/dist/ai/fake/fake-provider.js +278 -0
- package/dist/ai/fake/fake-script.d.ts +69 -0
- package/dist/ai/fake/fake-script.js +142 -0
- package/dist/ai/http.d.ts +54 -0
- package/dist/ai/http.js +212 -0
- package/dist/ai/json-partial.d.ts +17 -0
- package/dist/ai/json-partial.js +243 -0
- package/dist/ai/overflow.d.ts +22 -0
- package/dist/ai/overflow.js +61 -0
- package/dist/ai/providers/auth.d.ts +71 -0
- package/dist/ai/providers/auth.js +202 -0
- package/dist/ai/providers/builtin.d.ts +23 -0
- package/dist/ai/providers/builtin.js +148 -0
- package/dist/ai/providers/catalog-data.d.ts +5 -0
- package/dist/ai/providers/catalog-data.js +19 -0
- package/dist/ai/providers/catalog.d.ts +28 -0
- package/dist/ai/providers/catalog.js +166 -0
- package/dist/ai/providers/channels.d.ts +51 -0
- package/dist/ai/providers/channels.js +96 -0
- package/dist/ai/providers/enrich.d.ts +34 -0
- package/dist/ai/providers/enrich.js +86 -0
- package/dist/ai/providers/models-dev-cache.d.ts +53 -0
- package/dist/ai/providers/models-dev-cache.js +147 -0
- package/dist/ai/providers/models-dev.d.ts +99 -0
- package/dist/ai/providers/models-dev.js +315 -0
- package/dist/ai/providers/registry.d.ts +114 -0
- package/dist/ai/providers/registry.js +458 -0
- package/dist/ai/sse.d.ts +32 -0
- package/dist/ai/sse.js +140 -0
- package/dist/ai/thinking.d.ts +42 -0
- package/dist/ai/thinking.js +101 -0
- package/dist/ai/types.d.ts +448 -0
- package/dist/ai/types.js +19 -0
- package/dist/bundle/ama-sandbox.cjs +324 -0
- package/dist/bundle/ama.cjs +27837 -0
- package/dist/bundle.d.ts +9 -0
- package/dist/bundle.js +15 -0
- package/dist/cli/args.d.ts +85 -0
- package/dist/cli/args.js +408 -0
- package/dist/cli/bootstrap.d.ts +18 -0
- package/dist/cli/bootstrap.js +399 -0
- package/dist/cli/compose-providers.d.ts +37 -0
- package/dist/cli/compose-providers.js +107 -0
- package/dist/cli/compose-session.d.ts +72 -0
- package/dist/cli/compose-session.js +370 -0
- package/dist/cli/compose-store.d.ts +24 -0
- package/dist/cli/compose-store.js +125 -0
- package/dist/cli/compose.d.ts +108 -0
- package/dist/cli/compose.js +221 -0
- package/dist/cli/default-model.d.ts +16 -0
- package/dist/cli/default-model.js +24 -0
- package/dist/cli/deps.d.ts +207 -0
- package/dist/cli/deps.js +12 -0
- package/dist/cli/exit-codes.d.ts +29 -0
- package/dist/cli/exit-codes.js +40 -0
- package/dist/cli/main.d.ts +27 -0
- package/dist/cli/main.js +177 -0
- package/dist/cli/runtime.d.ts +90 -0
- package/dist/cli/runtime.js +8 -0
- package/dist/cli/startup-screen.d.ts +15 -0
- package/dist/cli/startup-screen.js +56 -0
- package/dist/cli/startup-steps.d.ts +35 -0
- package/dist/cli/startup-steps.js +202 -0
- package/dist/cli/subcommands/auth.d.ts +12 -0
- package/dist/cli/subcommands/auth.js +91 -0
- package/dist/cli/subcommands/config.d.ts +53 -0
- package/dist/cli/subcommands/config.js +277 -0
- package/dist/cli/subcommands/context.d.ts +21 -0
- package/dist/cli/subcommands/context.js +42 -0
- package/dist/cli/subcommands/doctor.d.ts +11 -0
- package/dist/cli/subcommands/doctor.js +246 -0
- package/dist/cli/subcommands/init.d.ts +6 -0
- package/dist/cli/subcommands/init.js +22 -0
- package/dist/cli/subcommands/model-meta.d.ts +16 -0
- package/dist/cli/subcommands/model-meta.js +54 -0
- package/dist/cli/subcommands/models-cache-probe.d.ts +34 -0
- package/dist/cli/subcommands/models-cache-probe.js +190 -0
- package/dist/cli/subcommands/models-discover.d.ts +46 -0
- package/dist/cli/subcommands/models-discover.js +232 -0
- package/dist/cli/subcommands/models.d.ts +40 -0
- package/dist/cli/subcommands/models.js +152 -0
- package/dist/cli/subcommands/providers-list.d.ts +8 -0
- package/dist/cli/subcommands/providers-list.js +97 -0
- package/dist/cli/subcommands/providers-plan.d.ts +79 -0
- package/dist/cli/subcommands/providers-plan.js +215 -0
- package/dist/cli/subcommands/providers.d.ts +27 -0
- package/dist/cli/subcommands/providers.js +433 -0
- package/dist/cli/subcommands/sessions.d.ts +11 -0
- package/dist/cli/subcommands/sessions.js +100 -0
- package/dist/codemode/capability.d.ts +37 -0
- package/dist/codemode/capability.js +55 -0
- package/dist/codemode/declarations.d.ts +44 -0
- package/dist/codemode/declarations.js +111 -0
- package/dist/codemode/host-side.d.ts +59 -0
- package/dist/codemode/host-side.js +253 -0
- package/dist/codemode/modes.d.ts +23 -0
- package/dist/codemode/modes.js +40 -0
- package/dist/codemode/protocol.d.ts +91 -0
- package/dist/codemode/protocol.js +114 -0
- package/dist/codemode/sandbox-entry.d.ts +25 -0
- package/dist/codemode/sandbox-entry.js +323 -0
- package/dist/codemode/store.d.ts +26 -0
- package/dist/codemode/store.js +53 -0
- package/dist/codemode/tool.d.ts +105 -0
- package/dist/codemode/tool.js +283 -0
- package/dist/compaction/branch-summary.d.ts +30 -0
- package/dist/compaction/branch-summary.js +79 -0
- package/dist/compaction/breaker.d.ts +32 -0
- package/dist/compaction/breaker.js +65 -0
- package/dist/compaction/cut-point.d.ts +23 -0
- package/dist/compaction/cut-point.js +70 -0
- package/dist/compaction/estimate.d.ts +30 -0
- package/dist/compaction/estimate.js +114 -0
- package/dist/compaction/prune-tier.d.ts +31 -0
- package/dist/compaction/prune-tier.js +83 -0
- package/dist/compaction/serialize.d.ts +20 -0
- package/dist/compaction/serialize.js +115 -0
- package/dist/compaction/summarize-tier.d.ts +111 -0
- package/dist/compaction/summarize-tier.js +305 -0
- package/dist/config/auth-file.d.ts +39 -0
- package/dist/config/auth-file.js +92 -0
- package/dist/config/context-files.d.ts +30 -0
- package/dist/config/context-files.js +77 -0
- package/dist/config/init.d.ts +30 -0
- package/dist/config/init.js +92 -0
- package/dist/config/json-schema.d.ts +14 -0
- package/dist/config/json-schema.js +182 -0
- package/dist/config/load.d.ts +45 -0
- package/dist/config/load.js +97 -0
- package/dist/config/merge.d.ts +73 -0
- package/dist/config/merge.js +248 -0
- package/dist/config/paths.d.ts +38 -0
- package/dist/config/paths.js +108 -0
- package/dist/config/profile.d.ts +27 -0
- package/dist/config/profile.js +65 -0
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.js +476 -0
- package/dist/config/trust.d.ts +42 -0
- package/dist/config/trust.js +122 -0
- package/dist/config/types.d.ts +190 -0
- package/dist/config/types.js +29 -0
- package/dist/config/write.d.ts +10 -0
- package/dist/config/write.js +25 -0
- package/dist/errors.d.ts +28 -0
- package/dist/errors.js +30 -0
- package/dist/hooks/config.d.ts +49 -0
- package/dist/hooks/config.js +102 -0
- package/dist/hooks/dispatcher.d.ts +41 -0
- package/dist/hooks/dispatcher.js +104 -0
- package/dist/hooks/matcher.d.ts +22 -0
- package/dist/hooks/matcher.js +108 -0
- package/dist/hooks/protocol.d.ts +33 -0
- package/dist/hooks/protocol.js +240 -0
- package/dist/hooks/runner.d.ts +30 -0
- package/dist/hooks/runner.js +143 -0
- package/dist/hooks/types.d.ts +147 -0
- package/dist/hooks/types.js +20 -0
- package/dist/host/api-impl.d.ts +75 -0
- package/dist/host/api-impl.js +173 -0
- package/dist/host/loader.d.ts +31 -0
- package/dist/host/loader.js +147 -0
- package/dist/host/types.d.ts +169 -0
- package/dist/host/types.js +14 -0
- package/dist/host.d.ts +5 -0
- package/dist/host.js +4 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +28 -0
- package/dist/modes/commands-core.d.ts +44 -0
- package/dist/modes/commands-core.js +171 -0
- package/dist/modes/image-input.d.ts +27 -0
- package/dist/modes/image-input.js +78 -0
- package/dist/modes/interactive/approval-dialog.d.ts +48 -0
- package/dist/modes/interactive/approval-dialog.js +202 -0
- package/dist/modes/interactive/commands.d.ts +41 -0
- package/dist/modes/interactive/commands.js +201 -0
- package/dist/modes/interactive/completion.d.ts +53 -0
- package/dist/modes/interactive/completion.js +157 -0
- package/dist/modes/interactive/interactive-mode.d.ts +46 -0
- package/dist/modes/interactive/interactive-mode.js +491 -0
- package/dist/modes/interactive/key-dispatch.d.ts +29 -0
- package/dist/modes/interactive/key-dispatch.js +107 -0
- package/dist/modes/interactive/line/line-editor.d.ts +50 -0
- package/dist/modes/interactive/line/line-editor.js +232 -0
- package/dist/modes/interactive/line/line-mode.d.ts +20 -0
- package/dist/modes/interactive/line/line-mode.js +218 -0
- package/dist/modes/interactive/line/line-render.d.ts +35 -0
- package/dist/modes/interactive/line/line-render.js +171 -0
- package/dist/modes/interactive/line/paste-state.d.ts +26 -0
- package/dist/modes/interactive/line/paste-state.js +72 -0
- package/dist/modes/interactive/message-view.d.ts +77 -0
- package/dist/modes/interactive/message-view.js +269 -0
- package/dist/modes/interactive/pickers.d.ts +42 -0
- package/dist/modes/interactive/pickers.js +115 -0
- package/dist/modes/interactive/startup-ui.d.ts +33 -0
- package/dist/modes/interactive/startup-ui.js +268 -0
- package/dist/modes/interactive/status-bar.d.ts +48 -0
- package/dist/modes/interactive/status-bar.js +139 -0
- package/dist/modes/interactive/tool-view.d.ts +95 -0
- package/dist/modes/interactive/tool-view.js +344 -0
- package/dist/modes/print/json-event.d.ts +15 -0
- package/dist/modes/print/json-event.js +39 -0
- package/dist/modes/print/print-mode.d.ts +17 -0
- package/dist/modes/print/print-mode.js +107 -0
- package/dist/modes/rpc/commands.d.ts +40 -0
- package/dist/modes/rpc/commands.js +263 -0
- package/dist/modes/rpc/jsonl.d.ts +16 -0
- package/dist/modes/rpc/jsonl.js +55 -0
- package/dist/modes/rpc/rpc-mode.d.ts +22 -0
- package/dist/modes/rpc/rpc-mode.js +153 -0
- package/dist/modes/session-report.d.ts +55 -0
- package/dist/modes/session-report.js +278 -0
- package/dist/modes/shared.d.ts +13 -0
- package/dist/modes/shared.js +52 -0
- package/dist/modes/startup-ui-text.d.ts +16 -0
- package/dist/modes/startup-ui-text.js +103 -0
- package/dist/permissions/broker.d.ts +47 -0
- package/dist/permissions/broker.js +107 -0
- package/dist/permissions/dangerous.d.ts +47 -0
- package/dist/permissions/dangerous.js +370 -0
- package/dist/permissions/pipeline.d.ts +51 -0
- package/dist/permissions/pipeline.js +181 -0
- package/dist/permissions/preview.d.ts +43 -0
- package/dist/permissions/preview.js +463 -0
- package/dist/permissions/rules.d.ts +58 -0
- package/dist/permissions/rules.js +249 -0
- package/dist/permissions/types.d.ts +100 -0
- package/dist/permissions/types.js +18 -0
- package/dist/rpc.d.ts +173 -0
- package/dist/rpc.js +13 -0
- package/dist/sdk.d.ts +98 -0
- package/dist/sdk.js +195 -0
- package/dist/session/manager.d.ts +70 -0
- package/dist/session/manager.js +278 -0
- package/dist/session/migrate.d.ts +19 -0
- package/dist/session/migrate.js +53 -0
- package/dist/session/projection.d.ts +50 -0
- package/dist/session/projection.js +184 -0
- package/dist/session/store.d.ts +47 -0
- package/dist/session/store.js +210 -0
- package/dist/session/tree.d.ts +21 -0
- package/dist/session/tree.js +88 -0
- package/dist/session/types.d.ts +201 -0
- package/dist/session/types.js +18 -0
- package/dist/skills/discover.d.ts +60 -0
- package/dist/skills/discover.js +160 -0
- package/dist/skills/expand.d.ts +35 -0
- package/dist/skills/expand.js +46 -0
- package/dist/skills/frontmatter.d.ts +27 -0
- package/dist/skills/frontmatter.js +157 -0
- package/dist/skills/index-prompt.d.ts +13 -0
- package/dist/skills/index-prompt.js +42 -0
- package/dist/skills/templates.d.ts +52 -0
- package/dist/skills/templates.js +177 -0
- package/dist/tools/bash.d.ts +49 -0
- package/dist/tools/bash.js +222 -0
- package/dist/tools/edit-fuzzy.d.ts +36 -0
- package/dist/tools/edit-fuzzy.js +129 -0
- package/dist/tools/edit.d.ts +38 -0
- package/dist/tools/edit.js +241 -0
- package/dist/tools/file-mutex.d.ts +8 -0
- package/dist/tools/file-mutex.js +29 -0
- package/dist/tools/glob.d.ts +44 -0
- package/dist/tools/glob.js +217 -0
- package/dist/tools/grep.d.ts +39 -0
- package/dist/tools/grep.js +179 -0
- package/dist/tools/ignore.d.ts +40 -0
- package/dist/tools/ignore.js +174 -0
- package/dist/tools/image-file.d.ts +31 -0
- package/dist/tools/image-file.js +114 -0
- package/dist/tools/ls.d.ts +21 -0
- package/dist/tools/ls.js +96 -0
- package/dist/tools/output-accumulator.d.ts +48 -0
- package/dist/tools/output-accumulator.js +106 -0
- package/dist/tools/paths.d.ts +20 -0
- package/dist/tools/paths.js +58 -0
- package/dist/tools/presets.d.ts +71 -0
- package/dist/tools/presets.js +128 -0
- package/dist/tools/process-tree.d.ts +35 -0
- package/dist/tools/process-tree.js +125 -0
- package/dist/tools/read.d.ts +24 -0
- package/dist/tools/read.js +132 -0
- package/dist/tools/registry.d.ts +43 -0
- package/dist/tools/registry.js +106 -0
- package/dist/tools/shell.d.ts +38 -0
- package/dist/tools/shell.js +91 -0
- package/dist/tools/task.d.ts +29 -0
- package/dist/tools/task.js +107 -0
- package/dist/tools/todo.d.ts +28 -0
- package/dist/tools/todo.js +107 -0
- package/dist/tools/truncate.d.ts +44 -0
- package/dist/tools/truncate.js +175 -0
- package/dist/tools/types.d.ts +135 -0
- package/dist/tools/types.js +19 -0
- package/dist/tools/write.d.ts +20 -0
- package/dist/tools/write.js +84 -0
- package/dist/tui/ansi.d.ts +29 -0
- package/dist/tui/ansi.js +420 -0
- package/dist/tui/component.d.ts +38 -0
- package/dist/tui/component.js +13 -0
- package/dist/tui/components/box.d.ts +26 -0
- package/dist/tui/components/box.js +65 -0
- package/dist/tui/components/container.d.ts +14 -0
- package/dist/tui/components/container.js +39 -0
- package/dist/tui/components/editor-buffer.d.ts +67 -0
- package/dist/tui/components/editor-buffer.js +300 -0
- package/dist/tui/components/editor-paste.d.ts +29 -0
- package/dist/tui/components/editor-paste.js +64 -0
- package/dist/tui/components/editor.d.ts +114 -0
- package/dist/tui/components/editor.js +530 -0
- package/dist/tui/components/key-value.d.ts +29 -0
- package/dist/tui/components/key-value.js +48 -0
- package/dist/tui/components/loader.d.ts +35 -0
- package/dist/tui/components/loader.js +71 -0
- package/dist/tui/components/markdown.d.ts +90 -0
- package/dist/tui/components/markdown.js +462 -0
- package/dist/tui/components/meter.d.ts +29 -0
- package/dist/tui/components/meter.js +47 -0
- package/dist/tui/components/overlay.d.ts +24 -0
- package/dist/tui/components/overlay.js +52 -0
- package/dist/tui/components/select-list.d.ts +57 -0
- package/dist/tui/components/select-list.js +179 -0
- package/dist/tui/components/spacer.d.ts +11 -0
- package/dist/tui/components/spacer.js +16 -0
- package/dist/tui/components/text.d.ts +30 -0
- package/dist/tui/components/text.js +65 -0
- package/dist/tui/keybindings.d.ts +66 -0
- package/dist/tui/keybindings.js +120 -0
- package/dist/tui/keys.d.ts +38 -0
- package/dist/tui/keys.js +275 -0
- package/dist/tui/stdin-buffer.d.ts +41 -0
- package/dist/tui/stdin-buffer.js +206 -0
- package/dist/tui/terminal.d.ts +79 -0
- package/dist/tui/terminal.js +153 -0
- package/dist/tui/theme.d.ts +31 -0
- package/dist/tui/theme.js +199 -0
- package/dist/tui/tui.d.ts +103 -0
- package/dist/tui/tui.js +363 -0
- package/dist/tui/vt-screen.d.ts +46 -0
- package/dist/tui/vt-screen.js +251 -0
- package/dist/tui.d.ts +30 -0
- package/dist/tui.js +31 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.js +24 -0
- package/docs/codemode.md +102 -0
- package/docs/hooks.md +196 -0
- package/docs/host-api.md +161 -0
- package/docs/providers.md +531 -0
- package/docs/rpc.md +253 -0
- package/docs/session-format.md +119 -0
- package/docs/tui.md +170 -0
- package/package.json +101 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 行式界面的单行编辑器(raw 模式可用时)。[B6]
|
|
3
|
+
*
|
|
4
|
+
* 键位:可见字符插入;←/→、Home/End(Ctrl+A / Ctrl+E)移动;↑/↓ 历史;退格、Delete、
|
|
5
|
+
* Ctrl+U(删到行首)、Ctrl+K(删到行尾)、Ctrl+W(删前一个词);Enter 提交;Ctrl+C 中断;
|
|
6
|
+
* 空行 Ctrl+D 结束。括号粘贴:单行原样插入,多行折叠成 `[粘贴 #n +k 行]` 标记,提交时展开。
|
|
7
|
+
* `ask()`:审批等单键问答,下一个可见字符(或 Enter = 缺省答案)作答。
|
|
8
|
+
*/
|
|
9
|
+
export type EditorAction = {
|
|
10
|
+
kind: "submit";
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "interrupt";
|
|
14
|
+
} | {
|
|
15
|
+
kind: "eof";
|
|
16
|
+
};
|
|
17
|
+
export interface LineEditorOptions {
|
|
18
|
+
prompt: string;
|
|
19
|
+
write(text: string): void;
|
|
20
|
+
history?: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare class LineEditor {
|
|
23
|
+
private readonly options;
|
|
24
|
+
buffer: string;
|
|
25
|
+
cursor: number;
|
|
26
|
+
private readonly paste;
|
|
27
|
+
private readonly pastes;
|
|
28
|
+
private readonly history;
|
|
29
|
+
private historyAt;
|
|
30
|
+
private visible;
|
|
31
|
+
private question;
|
|
32
|
+
constructor(options: LineEditorOptions);
|
|
33
|
+
/** 提示符 + 内容,光标放到正确的列。 */
|
|
34
|
+
render(): void;
|
|
35
|
+
/** 清掉编辑行(输出前调用)。 */
|
|
36
|
+
hide(): void;
|
|
37
|
+
get isVisible(): boolean;
|
|
38
|
+
/** 单键问答:返回小写的回答字符;Enter → fallback;Ctrl+C → fallback。 */
|
|
39
|
+
ask(question: string, fallback: string): Promise<string>;
|
|
40
|
+
feed(data: string): EditorAction[];
|
|
41
|
+
/** 输入暂停后交出留着的 ESC 前缀。 */
|
|
42
|
+
flush(): EditorAction[];
|
|
43
|
+
private answer;
|
|
44
|
+
private keys;
|
|
45
|
+
private special;
|
|
46
|
+
private insert;
|
|
47
|
+
private insertPaste;
|
|
48
|
+
/** 展开粘贴标记、记历史、清空。 */
|
|
49
|
+
private submit;
|
|
50
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 行式界面的单行编辑器(raw 模式可用时)。[B6]
|
|
3
|
+
*
|
|
4
|
+
* 键位:可见字符插入;←/→、Home/End(Ctrl+A / Ctrl+E)移动;↑/↓ 历史;退格、Delete、
|
|
5
|
+
* Ctrl+U(删到行首)、Ctrl+K(删到行尾)、Ctrl+W(删前一个词);Enter 提交;Ctrl+C 中断;
|
|
6
|
+
* 空行 Ctrl+D 结束。括号粘贴:单行原样插入,多行折叠成 `[粘贴 #n +k 行]` 标记,提交时展开。
|
|
7
|
+
* `ask()`:审批等单键问答,下一个可见字符(或 Enter = 缺省答案)作答。
|
|
8
|
+
*/
|
|
9
|
+
import { visibleWidth } from "../../../tui/ansi.js";
|
|
10
|
+
import { PasteState } from "./paste-state.js";
|
|
11
|
+
const KEYS = {
|
|
12
|
+
"\x1b[A": "up",
|
|
13
|
+
"\x1b[B": "down",
|
|
14
|
+
"\x1b[C": "right",
|
|
15
|
+
"\x1b[D": "left",
|
|
16
|
+
"\x1b[H": "home",
|
|
17
|
+
"\x1bOH": "home",
|
|
18
|
+
"\x1b[1~": "home",
|
|
19
|
+
"\x1b[F": "end",
|
|
20
|
+
"\x1bOF": "end",
|
|
21
|
+
"\x1b[4~": "end",
|
|
22
|
+
"\x1b[3~": "delete",
|
|
23
|
+
};
|
|
24
|
+
export class LineEditor {
|
|
25
|
+
options;
|
|
26
|
+
buffer = "";
|
|
27
|
+
cursor = 0;
|
|
28
|
+
paste = new PasteState();
|
|
29
|
+
pastes = new Map();
|
|
30
|
+
history;
|
|
31
|
+
historyAt;
|
|
32
|
+
visible = false;
|
|
33
|
+
question;
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.options = options;
|
|
36
|
+
this.history = options.history ?? [];
|
|
37
|
+
this.historyAt = this.history.length;
|
|
38
|
+
}
|
|
39
|
+
/** 提示符 + 内容,光标放到正确的列。 */
|
|
40
|
+
render() {
|
|
41
|
+
this.visible = true;
|
|
42
|
+
const line = this.options.prompt + this.buffer;
|
|
43
|
+
const back = visibleWidth(this.buffer.slice(this.cursor));
|
|
44
|
+
this.options.write(`\r\x1b[2K${line}${back > 0 ? `\x1b[${back}D` : ""}`);
|
|
45
|
+
}
|
|
46
|
+
/** 清掉编辑行(输出前调用)。 */
|
|
47
|
+
hide() {
|
|
48
|
+
if (!this.visible)
|
|
49
|
+
return;
|
|
50
|
+
this.visible = false;
|
|
51
|
+
this.options.write("\r\x1b[2K");
|
|
52
|
+
}
|
|
53
|
+
get isVisible() {
|
|
54
|
+
return this.visible;
|
|
55
|
+
}
|
|
56
|
+
/** 单键问答:返回小写的回答字符;Enter → fallback;Ctrl+C → fallback。 */
|
|
57
|
+
ask(question, fallback) {
|
|
58
|
+
this.hide();
|
|
59
|
+
this.options.write(question);
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
this.question = { resolve, fallback };
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
feed(data) {
|
|
65
|
+
const actions = [];
|
|
66
|
+
for (const piece of this.paste.feed(data)) {
|
|
67
|
+
if (piece.kind === "paste")
|
|
68
|
+
this.insertPaste(piece.text);
|
|
69
|
+
else
|
|
70
|
+
this.keys(piece.text, actions);
|
|
71
|
+
}
|
|
72
|
+
return actions;
|
|
73
|
+
}
|
|
74
|
+
/** 输入暂停后交出留着的 ESC 前缀。 */
|
|
75
|
+
flush() {
|
|
76
|
+
const actions = [];
|
|
77
|
+
for (const piece of this.paste.flush())
|
|
78
|
+
if (piece.kind === "text")
|
|
79
|
+
this.keys(piece.text, actions);
|
|
80
|
+
return actions;
|
|
81
|
+
}
|
|
82
|
+
answer(ch) {
|
|
83
|
+
const q = this.question;
|
|
84
|
+
if (q === undefined)
|
|
85
|
+
return;
|
|
86
|
+
this.question = undefined;
|
|
87
|
+
const answer = ch === "\r" || ch === "\n" || ch === "\x03" ? q.fallback : ch.toLowerCase();
|
|
88
|
+
this.options.write(`${answer}\n`);
|
|
89
|
+
q.resolve(answer);
|
|
90
|
+
}
|
|
91
|
+
keys(text, actions) {
|
|
92
|
+
let i = 0;
|
|
93
|
+
while (i < text.length) {
|
|
94
|
+
if (this.question !== undefined) {
|
|
95
|
+
const ch = text[i];
|
|
96
|
+
i++;
|
|
97
|
+
if (ch === "\x1b")
|
|
98
|
+
continue;
|
|
99
|
+
this.answer(ch);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (text[i] === "\x1b") {
|
|
103
|
+
const seq = /^\x1b(?:\[[0-9;]*[~A-Za-z]|O[A-Za-z])?/.exec(text.slice(i))?.[0] ?? "\x1b";
|
|
104
|
+
i += seq.length;
|
|
105
|
+
this.special(KEYS[seq]);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const cp = text.codePointAt(i);
|
|
109
|
+
const ch = String.fromCodePoint(cp);
|
|
110
|
+
i += ch.length;
|
|
111
|
+
switch (ch) {
|
|
112
|
+
case "\r":
|
|
113
|
+
case "\n":
|
|
114
|
+
actions.push({ kind: "submit", text: this.submit() });
|
|
115
|
+
break;
|
|
116
|
+
case "\x03":
|
|
117
|
+
actions.push({ kind: "interrupt" });
|
|
118
|
+
break;
|
|
119
|
+
case "\x04":
|
|
120
|
+
if (this.buffer === "")
|
|
121
|
+
actions.push({ kind: "eof" });
|
|
122
|
+
else
|
|
123
|
+
this.special("delete");
|
|
124
|
+
break;
|
|
125
|
+
case "\x7f":
|
|
126
|
+
case "\b":
|
|
127
|
+
if (this.cursor > 0) {
|
|
128
|
+
const before = Array.from(this.buffer.slice(0, this.cursor));
|
|
129
|
+
before.pop();
|
|
130
|
+
const head = before.join("");
|
|
131
|
+
this.buffer = head + this.buffer.slice(this.cursor);
|
|
132
|
+
this.cursor = head.length;
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
case "\x01":
|
|
136
|
+
this.special("home");
|
|
137
|
+
break;
|
|
138
|
+
case "\x05":
|
|
139
|
+
this.special("end");
|
|
140
|
+
break;
|
|
141
|
+
case "\x15":
|
|
142
|
+
this.buffer = this.buffer.slice(this.cursor);
|
|
143
|
+
this.cursor = 0;
|
|
144
|
+
break;
|
|
145
|
+
case "\x0b":
|
|
146
|
+
this.buffer = this.buffer.slice(0, this.cursor);
|
|
147
|
+
break;
|
|
148
|
+
case "\x17": {
|
|
149
|
+
const head = this.buffer.slice(0, this.cursor).replace(/\S+\s*$/, "");
|
|
150
|
+
this.buffer = head + this.buffer.slice(this.cursor);
|
|
151
|
+
this.cursor = head.length;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
default:
|
|
155
|
+
if (cp >= 0x20)
|
|
156
|
+
this.insert(ch);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (this.visible)
|
|
160
|
+
this.render();
|
|
161
|
+
}
|
|
162
|
+
special(key) {
|
|
163
|
+
switch (key) {
|
|
164
|
+
case "left":
|
|
165
|
+
if (this.cursor > 0)
|
|
166
|
+
this.cursor -= Array.from(this.buffer.slice(0, this.cursor)).pop()?.length ?? 1;
|
|
167
|
+
break;
|
|
168
|
+
case "right":
|
|
169
|
+
if (this.cursor < this.buffer.length)
|
|
170
|
+
this.cursor += Array.from(this.buffer.slice(this.cursor))[0]?.length ?? 1;
|
|
171
|
+
break;
|
|
172
|
+
case "home":
|
|
173
|
+
this.cursor = 0;
|
|
174
|
+
break;
|
|
175
|
+
case "end":
|
|
176
|
+
this.cursor = this.buffer.length;
|
|
177
|
+
break;
|
|
178
|
+
case "delete":
|
|
179
|
+
if (this.cursor < this.buffer.length) {
|
|
180
|
+
const tail = Array.from(this.buffer.slice(this.cursor)).slice(1).join("");
|
|
181
|
+
this.buffer = this.buffer.slice(0, this.cursor) + tail;
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
case "up":
|
|
185
|
+
case "down": {
|
|
186
|
+
const next = this.historyAt + (key === "up" ? -1 : 1);
|
|
187
|
+
if (next < 0 || next > this.history.length)
|
|
188
|
+
break;
|
|
189
|
+
this.historyAt = next;
|
|
190
|
+
this.buffer = this.history[next] ?? "";
|
|
191
|
+
this.cursor = this.buffer.length;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
default:
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
insert(text) {
|
|
199
|
+
this.buffer = this.buffer.slice(0, this.cursor) + text + this.buffer.slice(this.cursor);
|
|
200
|
+
this.cursor += text.length;
|
|
201
|
+
}
|
|
202
|
+
insertPaste(text) {
|
|
203
|
+
const lines = text.split("\n").length;
|
|
204
|
+
if (lines <= 1) {
|
|
205
|
+
this.insert(text);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const marker = `[粘贴 #${this.pastes.size + 1} +${lines} 行]`;
|
|
209
|
+
this.pastes.set(marker, text);
|
|
210
|
+
this.insert(marker);
|
|
211
|
+
}
|
|
212
|
+
if (this.visible)
|
|
213
|
+
this.render();
|
|
214
|
+
}
|
|
215
|
+
/** 展开粘贴标记、记历史、清空。 */
|
|
216
|
+
submit() {
|
|
217
|
+
// 提交时把整行(含粘贴标记)留在屏幕上,再换行。
|
|
218
|
+
if (this.visible)
|
|
219
|
+
this.options.write(`\r\x1b[2K${this.options.prompt}${this.buffer}\n`);
|
|
220
|
+
let text = this.buffer;
|
|
221
|
+
for (const [marker, content] of this.pastes)
|
|
222
|
+
text = text.split(marker).join(content);
|
|
223
|
+
if (this.buffer.trim() !== "" && this.history.at(-1) !== this.buffer)
|
|
224
|
+
this.history.push(this.buffer);
|
|
225
|
+
this.historyAt = this.history.length;
|
|
226
|
+
this.buffer = "";
|
|
227
|
+
this.cursor = 0;
|
|
228
|
+
this.pastes.clear();
|
|
229
|
+
this.visible = false;
|
|
230
|
+
return text;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 行式界面(`--no-tui`、非 TTY、`TERM=dumb`;B7 的终端界面合入前也承担交互模式)。[B6]
|
|
3
|
+
*
|
|
4
|
+
* - stdin 是 TTY 且可开 raw:自带单行编辑器(line-editor.ts:历史、括号粘贴折叠),运行中回车
|
|
5
|
+
* = steer;Ctrl+C 运行中中断、空闲时连按两次退出(130);空行 Ctrl+D 退出;审批 y / a / N 单键问答。
|
|
6
|
+
* 问句之前逐行打印执行前预览(`request.preview`,W3-B9a-2)。
|
|
7
|
+
* - 否则(管道):逐行读 stdin,每行依次执行(等上一条运行结束);没有审批 UI,ask → deny。
|
|
8
|
+
* - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选。
|
|
9
|
+
*/
|
|
10
|
+
import type { ModeContext } from "../../../cli/deps.js";
|
|
11
|
+
import type { Runtime } from "../../../cli/runtime.js";
|
|
12
|
+
export interface LineModeOptions {
|
|
13
|
+
stdin?: NodeJS.ReadableStream & {
|
|
14
|
+
setRawMode?(raw: boolean): unknown;
|
|
15
|
+
isTTY?: boolean;
|
|
16
|
+
};
|
|
17
|
+
/** 强制 raw / 管道(测试);缺省按 io.stdinIsTTY 与 setRawMode 判断。 */
|
|
18
|
+
raw?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function runLineMode(runtime: Runtime, context: ModeContext, options?: LineModeOptions): Promise<number>;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 行式界面(`--no-tui`、非 TTY、`TERM=dumb`;B7 的终端界面合入前也承担交互模式)。[B6]
|
|
3
|
+
*
|
|
4
|
+
* - stdin 是 TTY 且可开 raw:自带单行编辑器(line-editor.ts:历史、括号粘贴折叠),运行中回车
|
|
5
|
+
* = steer;Ctrl+C 运行中中断、空闲时连按两次退出(130);空行 Ctrl+D 退出;审批 y / a / N 单键问答。
|
|
6
|
+
* 问句之前逐行打印执行前预览(`request.preview`,W3-B9a-2)。
|
|
7
|
+
* - 否则(管道):逐行读 stdin,每行依次执行(等上一条运行结束);没有审批 UI,ask → deny。
|
|
8
|
+
* - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选。
|
|
9
|
+
*/
|
|
10
|
+
import { promptImages, sessionModel } from "../../image-input.js";
|
|
11
|
+
import { currentSession, switchSession } from "../../../cli/compose-session.js";
|
|
12
|
+
import { ExitCode } from "../../../cli/exit-codes.js";
|
|
13
|
+
import { previewDisplayLines } from "../../../permissions/preview.js";
|
|
14
|
+
import { AMA_VERSION } from "../../../version.js";
|
|
15
|
+
import { runSlashCommand } from "../../commands-core.js";
|
|
16
|
+
import { createLineReader } from "../../rpc/jsonl.js";
|
|
17
|
+
import { errorText, onTerminationSignals } from "../../shared.js";
|
|
18
|
+
import { LineEditor } from "./line-editor.js";
|
|
19
|
+
import { cacheNoticesEnabled } from "../../session-report.js";
|
|
20
|
+
import { EventPrinter, approvalQuestion, logsInfo, pickHint } from "./line-render.js";
|
|
21
|
+
const DOUBLE_INTERRUPT_MS = 1500;
|
|
22
|
+
export async function runLineMode(runtime, context, options = {}) {
|
|
23
|
+
const { io } = context;
|
|
24
|
+
const stdin = options.stdin ?? process.stdin;
|
|
25
|
+
const raw = options.raw ?? (io.stdinIsTTY && typeof stdin.setRawMode === "function");
|
|
26
|
+
let editor;
|
|
27
|
+
const out = (text) => {
|
|
28
|
+
editor?.hide();
|
|
29
|
+
io.stdout(text);
|
|
30
|
+
};
|
|
31
|
+
const err = (text) => {
|
|
32
|
+
editor?.hide();
|
|
33
|
+
io.stderr(text);
|
|
34
|
+
};
|
|
35
|
+
let session = currentSession(runtime);
|
|
36
|
+
const printer = new EventPrinter(out, err, {
|
|
37
|
+
missNotices: () => cacheNoticesEnabled(session),
|
|
38
|
+
info: logsInfo(io.env),
|
|
39
|
+
});
|
|
40
|
+
let unsubscribe = session.subscribe((event) => printer.handle(event));
|
|
41
|
+
const commands = {
|
|
42
|
+
runtime,
|
|
43
|
+
session: () => session,
|
|
44
|
+
async switchSession(request) {
|
|
45
|
+
const next = await switchSession(runtime, request);
|
|
46
|
+
unsubscribe();
|
|
47
|
+
session = next;
|
|
48
|
+
unsubscribe = next.subscribe((event) => printer.handle(event));
|
|
49
|
+
return next;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
/** 一行输入:命令或提示;返回 "exit" 表示结束。 */
|
|
53
|
+
const handle = async (line) => {
|
|
54
|
+
if (line.trim() === "")
|
|
55
|
+
return undefined;
|
|
56
|
+
try {
|
|
57
|
+
const result = await runSlashCommand(line, commands);
|
|
58
|
+
if (result === undefined)
|
|
59
|
+
await prompt(session, line);
|
|
60
|
+
else if (result.kind === "exit")
|
|
61
|
+
return "exit";
|
|
62
|
+
else if (result.kind === "prompt")
|
|
63
|
+
await prompt(session, result.text);
|
|
64
|
+
else if (result.kind === "pick")
|
|
65
|
+
out(`${await pickHint(result.what, runtime, session)}\n`);
|
|
66
|
+
else if (result.message !== undefined)
|
|
67
|
+
out(`${result.message}\n`);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
printer.endLine();
|
|
71
|
+
err(`ama: ${errorText(error)}\n`);
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
75
|
+
const prompt = async (target, text) => {
|
|
76
|
+
const images = await promptImages(text, [], target.state.cwd, sessionModel(runtime.providers, target));
|
|
77
|
+
await target.prompt(text, images.length > 0 ? { images } : {});
|
|
78
|
+
printer.endLine();
|
|
79
|
+
};
|
|
80
|
+
if (!raw)
|
|
81
|
+
return runPiped(stdin, context, handle, () => session, () => unsubscribe());
|
|
82
|
+
// ---- raw 终端 ----
|
|
83
|
+
const tty = stdin;
|
|
84
|
+
editor = new LineEditor({ prompt: "› ", write: (t) => io.stdout(t) });
|
|
85
|
+
const ed = editor;
|
|
86
|
+
if (runtime.config.ui?.quietStartup !== "silent") {
|
|
87
|
+
const model = session.state.model;
|
|
88
|
+
io.stdout(`ama ${AMA_VERSION} · ${model?.provider}/${model?.id} · /help 查看命令,Ctrl+D 退出\n`);
|
|
89
|
+
}
|
|
90
|
+
runtime.approvals.setUiBroker({
|
|
91
|
+
ask: (request, signal) => new Promise((resolve) => {
|
|
92
|
+
if (signal.aborted)
|
|
93
|
+
return resolve(undefined);
|
|
94
|
+
signal.addEventListener("abort", () => resolve(undefined), { once: true });
|
|
95
|
+
const preview = previewDisplayLines(request.preview).map((l) => ` ${l}\n`);
|
|
96
|
+
void ed.ask(`\n${preview.join("")}${approvalQuestion(request)}`, "n").then((answer) => {
|
|
97
|
+
resolve(answer === "y" ? "allow" : answer === "a" ? "allow_session" : "deny");
|
|
98
|
+
if (!busy)
|
|
99
|
+
ed.render();
|
|
100
|
+
});
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
runtime.notifier.set((message, level) => err(`ama: [${level}] ${message}\n`));
|
|
104
|
+
let busy = false;
|
|
105
|
+
let lastInterrupt = 0;
|
|
106
|
+
return new Promise((resolve) => {
|
|
107
|
+
let finished = false;
|
|
108
|
+
const finish = (code) => {
|
|
109
|
+
if (finished)
|
|
110
|
+
return;
|
|
111
|
+
finished = true;
|
|
112
|
+
tty.off("data", onData);
|
|
113
|
+
ed.hide();
|
|
114
|
+
io.stdout("\x1b[?2004l");
|
|
115
|
+
tty.setRawMode?.(false);
|
|
116
|
+
tty.pause?.();
|
|
117
|
+
runtime.approvals.setUiBroker(undefined);
|
|
118
|
+
runtime.notifier.set(undefined);
|
|
119
|
+
void session
|
|
120
|
+
.abort()
|
|
121
|
+
.catch(() => undefined)
|
|
122
|
+
.finally(() => {
|
|
123
|
+
unsubscribe();
|
|
124
|
+
resolve(code);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
const run = (text) => {
|
|
128
|
+
busy = true;
|
|
129
|
+
void handle(text).then((outcome) => {
|
|
130
|
+
busy = false;
|
|
131
|
+
if (outcome === "exit")
|
|
132
|
+
finish(ExitCode.Ok);
|
|
133
|
+
else
|
|
134
|
+
ed.render();
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
let flushTimer;
|
|
138
|
+
const apply = (actions) => {
|
|
139
|
+
for (const action of actions) {
|
|
140
|
+
if (action.kind === "eof")
|
|
141
|
+
return finish(ExitCode.Ok);
|
|
142
|
+
if (action.kind === "interrupt") {
|
|
143
|
+
if (busy) {
|
|
144
|
+
void session.abort();
|
|
145
|
+
err("^C 已中断\n");
|
|
146
|
+
}
|
|
147
|
+
else if (Date.now() - lastInterrupt < DOUBLE_INTERRUPT_MS) {
|
|
148
|
+
return finish(ExitCode.Sigint);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
lastInterrupt = Date.now();
|
|
152
|
+
io.stdout("\n(再按一次 Ctrl+C 退出)\n");
|
|
153
|
+
ed.render();
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (busy) {
|
|
158
|
+
if (action.text.trim() !== "") {
|
|
159
|
+
void session.steer(action.text).catch(() => undefined);
|
|
160
|
+
out(`↳ steer:${action.text}\n`);
|
|
161
|
+
}
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
run(action.text);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const onData = (chunk) => {
|
|
168
|
+
apply(ed.feed(typeof chunk === "string" ? chunk : chunk.toString("utf8")));
|
|
169
|
+
if (flushTimer !== undefined)
|
|
170
|
+
clearTimeout(flushTimer);
|
|
171
|
+
flushTimer = setTimeout(() => apply(ed.flush()), 50);
|
|
172
|
+
};
|
|
173
|
+
tty.setRawMode?.(true);
|
|
174
|
+
io.stdout("\x1b[?2004h");
|
|
175
|
+
tty.on("data", onData);
|
|
176
|
+
tty.resume?.();
|
|
177
|
+
if (context.prompt !== undefined) {
|
|
178
|
+
io.stdout(`› ${context.prompt}\n`);
|
|
179
|
+
run(context.prompt);
|
|
180
|
+
}
|
|
181
|
+
else
|
|
182
|
+
ed.render();
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/** 管道:逐行依次执行;stdin 结束后等最后一条跑完退出 0。 */
|
|
186
|
+
function runPiped(stdin, context, handle, session, unsubscribe) {
|
|
187
|
+
return new Promise((resolve) => {
|
|
188
|
+
let chain = Promise.resolve(undefined);
|
|
189
|
+
let finished = false;
|
|
190
|
+
const finish = (code) => {
|
|
191
|
+
if (finished)
|
|
192
|
+
return;
|
|
193
|
+
finished = true;
|
|
194
|
+
reader.close();
|
|
195
|
+
offSignals();
|
|
196
|
+
stdin.pause?.();
|
|
197
|
+
unsubscribe();
|
|
198
|
+
resolve(code);
|
|
199
|
+
};
|
|
200
|
+
const enqueue = (line) => {
|
|
201
|
+
chain = chain.then((state) => (state === "exit" ? state : handle(line)));
|
|
202
|
+
void chain.then((state) => {
|
|
203
|
+
if (state === "exit")
|
|
204
|
+
finish(ExitCode.Ok);
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
const reader = createLineReader(stdin, enqueue, () => {
|
|
208
|
+
void chain.then(() => finish(ExitCode.Ok));
|
|
209
|
+
});
|
|
210
|
+
const offSignals = onTerminationSignals((code) => {
|
|
211
|
+
void session()
|
|
212
|
+
.abort()
|
|
213
|
+
.finally(() => finish(code));
|
|
214
|
+
});
|
|
215
|
+
if (context.prompt !== undefined)
|
|
216
|
+
enqueue(context.prompt);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 行式界面的输出:会话事件 → 纯文本(助手文本流式写 stdout,工具 / 重试 / 压缩一行提示)。[B6]
|
|
3
|
+
* 选择器在行式界面里退化为列出候选、提示带参数重发。
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentSession, SessionEvent } from "../../../agent/types.js";
|
|
6
|
+
import type { Runtime } from "../../../cli/runtime.js";
|
|
7
|
+
import type { ApprovalRequest } from "../../../permissions/types.js";
|
|
8
|
+
import type { CommandResult } from "../../commands-core.js";
|
|
9
|
+
/** 工具参数的一行摘要(第一个常见字段,折叠换行、截到 80 字符)。 */
|
|
10
|
+
export declare function argsSummary(args: unknown): string;
|
|
11
|
+
export declare function approvalQuestion(request: ApprovalRequest): string;
|
|
12
|
+
/** [W3-C2] 缓存提示的开关(line 模式由 runLineMode 传入)。 */
|
|
13
|
+
export interface EventPrinterOptions {
|
|
14
|
+
/** `cache.missNotices`(每次现取,切换会话后跟随新会话);缺省 true。 */
|
|
15
|
+
missNotices?(): boolean;
|
|
16
|
+
/** `AMA_LOG` 为 info / debug:保温成功也写一行。 */
|
|
17
|
+
info?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** `AMA_LOG=info|debug`。 */
|
|
20
|
+
export declare function logsInfo(env: Readonly<Record<string, string | undefined>>): boolean;
|
|
21
|
+
export declare class EventPrinter {
|
|
22
|
+
private readonly out;
|
|
23
|
+
private readonly err;
|
|
24
|
+
private readonly options;
|
|
25
|
+
private midLine;
|
|
26
|
+
constructor(out: (text: string) => void, err: (text: string) => void, options?: EventPrinterOptions);
|
|
27
|
+
private line;
|
|
28
|
+
/** 收尾:保证光标在行首。 */
|
|
29
|
+
endLine(): void;
|
|
30
|
+
handle(event: SessionEvent): void;
|
|
31
|
+
}
|
|
32
|
+
/** `pick` 在行式界面:列出候选,提示带参数重发。 */
|
|
33
|
+
export declare function pickHint(what: Extract<CommandResult, {
|
|
34
|
+
kind: "pick";
|
|
35
|
+
}>["what"], runtime: Runtime, session: AgentSession): Promise<string>;
|