@armadra/agent 0.3.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 +257 -0
- package/README.md +263 -95
- 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/retry.d.ts +1 -1
- package/dist/agent/retry.js +2 -1
- package/dist/agent/session-cache.d.ts +5 -0
- package/dist/agent/session-cache.js +18 -2
- package/dist/agent/session-classifier.d.ts +18 -0
- package/dist/agent/session-classifier.js +105 -0
- package/dist/agent/session-compaction.d.ts +35 -6
- package/dist/agent/session-compaction.js +157 -31
- package/dist/agent/session-core.d.ts +40 -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 +63 -3
- package/dist/agent/session.d.ts +33 -29
- package/dist/agent/session.js +91 -126
- 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 +72 -6
- package/dist/agent/types-w5.d.ts +192 -0
- package/dist/agent/types-w5.js +10 -0
- package/dist/agent/types.d.ts +55 -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-messages.js +3 -2
- 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/google-generative-ai.js +3 -2
- package/dist/ai/apis/openai-compat.d.ts +4 -1
- package/dist/ai/apis/openai-compat.js +8 -1
- package/dist/ai/apis/openai-completions.js +3 -2
- package/dist/ai/apis/openai-responses.js +3 -2
- package/dist/ai/http.d.ts +28 -6
- package/dist/ai/http.js +41 -8
- 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 +28 -11
- package/dist/ai/providers/registry.js +112 -65
- package/dist/ai/providers/suggest.d.ts +18 -0
- package/dist/ai/providers/suggest.js +72 -0
- package/dist/ai/sse.d.ts +6 -2
- package/dist/ai/sse.js +22 -2
- package/dist/ai/types.d.ts +37 -4
- package/dist/ai/types.js +5 -0
- package/dist/bundle/ama.cjs +41979 -21147
- 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 +26 -7
- package/dist/cli/args.js +75 -82
- package/dist/cli/bootstrap.js +40 -4
- package/dist/cli/codemode-notice.d.ts +21 -0
- package/dist/cli/codemode-notice.js +56 -0
- 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 +8 -0
- package/dist/cli/compose-session.js +76 -2
- package/dist/cli/compose-store.d.ts +1 -1
- package/dist/cli/compose-store.js +3 -1
- package/dist/cli/compose.d.ts +17 -4
- package/dist/cli/compose.js +60 -14
- package/dist/cli/default-model.d.ts +38 -1
- package/dist/cli/default-model.js +96 -9
- package/dist/cli/deps.d.ts +42 -0
- package/dist/cli/exit-codes.d.ts +12 -0
- package/dist/cli/exit-codes.js +15 -0
- package/dist/cli/fake-visibility.d.ts +13 -0
- package/dist/cli/fake-visibility.js +26 -0
- package/dist/cli/from-prompt.d.ts +18 -0
- package/dist/cli/from-prompt.js +49 -0
- package/dist/cli/help-text.d.ts +4 -0
- package/dist/cli/help-text.js +102 -0
- package/dist/cli/main.d.ts +9 -2
- package/dist/cli/main.js +77 -3
- package/dist/cli/proxy.d.ts +51 -0
- package/dist/cli/proxy.js +135 -0
- package/dist/cli/startup-screen.d.ts +29 -0
- package/dist/cli/startup-screen.js +51 -2
- package/dist/cli/startup-steps.d.ts +1 -1
- package/dist/cli/startup-steps.js +21 -13
- package/dist/cli/subcommands/config.d.ts +22 -3
- package/dist/cli/subcommands/config.js +119 -21
- package/dist/cli/subcommands/context.js +4 -1
- package/dist/cli/subcommands/doctor.js +33 -1
- package/dist/cli/subcommands/init.js +2 -1
- package/dist/cli/subcommands/models-discover.d.ts +15 -9
- package/dist/cli/subcommands/models-discover.js +58 -52
- package/dist/cli/subcommands/models.d.ts +2 -0
- package/dist/cli/subcommands/models.js +33 -14
- package/dist/cli/subcommands/probe-runner.d.ts +96 -0
- package/dist/cli/subcommands/probe-runner.js +264 -0
- package/dist/cli/subcommands/providers-probe.d.ts +34 -0
- package/dist/cli/subcommands/providers-probe.js +87 -0
- package/dist/cli/subcommands/providers.d.ts +3 -2
- package/dist/cli/subcommands/providers.js +53 -51
- package/dist/cli/subcommands/sessions-export.d.ts +10 -0
- package/dist/cli/subcommands/sessions-export.js +59 -0
- package/dist/cli/subcommands/sessions-search.d.ts +13 -0
- package/dist/cli/subcommands/sessions-search.js +103 -0
- package/dist/cli/subcommands/sessions.d.ts +6 -3
- package/dist/cli/subcommands/sessions.js +58 -3
- package/dist/cli/subcommands/stats.d.ts +17 -0
- package/dist/cli/subcommands/stats.js +198 -0
- package/dist/cli/system-prompt-arg.d.ts +11 -0
- package/dist/cli/system-prompt-arg.js +34 -0
- 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/modes.d.ts +4 -11
- package/dist/codemode/modes.js +5 -27
- package/dist/codemode/tool.d.ts +18 -14
- package/dist/codemode/tool.js +76 -31
- 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/init.d.ts +6 -2
- package/dist/config/init.js +12 -5
- package/dist/config/json-schema.d.ts +1 -0
- package/dist/config/json-schema.js +98 -4
- package/dist/config/key-docs.d.ts +22 -0
- package/dist/config/key-docs.js +174 -0
- package/dist/config/merge.d.ts +12 -9
- package/dist/config/merge.js +102 -13
- 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 +91 -118
- package/dist/config/types-w5.d.ts +118 -0
- package/dist/config/types-w5.js +20 -0
- package/dist/config/types.d.ts +84 -7
- package/dist/config/types.js +29 -1
- 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 +61 -5
- 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 +40 -7
- package/dist/modes/interactive/approval-dialog.js +192 -35
- 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 +20 -3
- package/dist/modes/interactive/commands.js +75 -16
- 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 +16 -2
- package/dist/modes/interactive/interactive-mode.js +184 -202
- package/dist/modes/interactive/key-dispatch.d.ts +18 -2
- package/dist/modes/interactive/key-dispatch.js +53 -6
- package/dist/modes/interactive/line/line-mode.d.ts +3 -1
- package/dist/modes/interactive/line/line-mode.js +28 -9
- package/dist/modes/interactive/line/line-render.d.ts +6 -1
- package/dist/modes/interactive/line/line-render.js +66 -8
- package/dist/modes/interactive/message-view.d.ts +49 -10
- package/dist/modes/interactive/message-view.js +262 -46
- package/dist/modes/interactive/panels.d.ts +35 -0
- package/dist/modes/interactive/panels.js +157 -0
- package/dist/modes/interactive/pickers.d.ts +23 -2
- package/dist/modes/interactive/pickers.js +48 -15
- 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/run-indicator.d.ts +51 -0
- package/dist/modes/interactive/run-indicator.js +189 -0
- package/dist/modes/interactive/session-events.d.ts +24 -0
- package/dist/modes/interactive/session-events.js +96 -0
- package/dist/modes/interactive/startup-header.d.ts +40 -0
- package/dist/modes/interactive/startup-header.js +169 -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 +107 -16
- package/dist/modes/interactive/status-bar.js +306 -81
- 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-summary.d.ts +46 -0
- package/dist/modes/interactive/tool-summary.js +218 -0
- package/dist/modes/interactive/tool-view.d.ts +58 -15
- package/dist/modes/interactive/tool-view.js +233 -145
- package/dist/modes/print/print-mode.d.ts +40 -4
- package/dist/modes/print/print-mode.js +161 -8
- package/dist/modes/rpc/commands.d.ts +9 -0
- package/dist/modes/rpc/commands.js +49 -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 +65 -0
- package/dist/permissions/auto-safe.js +547 -0
- package/dist/permissions/classifier.d.ts +68 -0
- package/dist/permissions/classifier.js +186 -0
- package/dist/permissions/dangerous.d.ts +5 -0
- package/dist/permissions/dangerous.js +1 -1
- package/dist/permissions/modes.d.ts +30 -0
- package/dist/permissions/modes.js +78 -0
- package/dist/permissions/pipeline.d.ts +72 -6
- package/dist/permissions/pipeline.js +306 -11
- package/dist/permissions/protected.d.ts +19 -0
- package/dist/permissions/protected.js +74 -0
- package/dist/permissions/readonly-bash.d.ts +30 -0
- package/dist/permissions/readonly-bash.js +118 -0
- package/dist/permissions/rules.js +3 -0
- package/dist/permissions/types.d.ts +92 -3
- package/dist/permissions/types.js +3 -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 +42 -5
- package/dist/sdk.js +34 -4
- package/dist/session/export.d.ts +32 -0
- package/dist/session/export.js +187 -0
- package/dist/session/redact.d.ts +15 -0
- package/dist/session/redact.js +55 -0
- package/dist/session/reuse.d.ts +33 -0
- package/dist/session/reuse.js +86 -0
- package/dist/session/scan.d.ts +34 -0
- package/dist/session/scan.js +140 -0
- package/dist/session/search.d.ts +52 -0
- package/dist/session/search.js +211 -0
- package/dist/session/stats-aggregate.d.ts +63 -0
- package/dist/session/stats-aggregate.js +163 -0
- package/dist/session/stats-index.d.ts +26 -0
- package/dist/session/stats-index.js +91 -0
- package/dist/session/stats-scan.d.ts +54 -0
- package/dist/session/stats-scan.js +236 -0
- 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 +40 -8
- package/dist/tools/presets.js +65 -19
- 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/component.d.ts +8 -2
- package/dist/tui/component.js +3 -1
- package/dist/tui/components/box.d.ts +6 -1
- package/dist/tui/components/box.js +16 -6
- package/dist/tui/components/card.d.ts +23 -0
- package/dist/tui/components/card.js +37 -0
- package/dist/tui/components/editor-history.d.ts +6 -0
- package/dist/tui/components/editor-history.js +45 -0
- package/dist/tui/components/editor-paste.d.ts +1 -1
- package/dist/tui/components/editor-paste.js +4 -4
- package/dist/tui/components/editor.d.ts +11 -5
- package/dist/tui/components/editor.js +52 -58
- package/dist/tui/components/key-value.d.ts +3 -0
- package/dist/tui/components/key-value.js +16 -6
- package/dist/tui/components/loader.d.ts +37 -7
- package/dist/tui/components/loader.js +84 -21
- package/dist/tui/components/markdown.d.ts +5 -1
- package/dist/tui/components/markdown.js +45 -21
- package/dist/tui/components/meter.d.ts +3 -3
- package/dist/tui/components/meter.js +13 -11
- package/dist/tui/components/select-list.d.ts +23 -1
- package/dist/tui/components/select-list.js +76 -13
- package/dist/tui/glyphs.d.ts +72 -0
- package/dist/tui/glyphs.js +118 -0
- package/dist/tui/keybindings.d.ts +5 -0
- package/dist/tui/keybindings.js +5 -0
- package/dist/tui/theme.d.ts +30 -6
- package/dist/tui/theme.js +103 -17
- package/dist/tui.d.ts +4 -2
- package/dist/tui.js +3 -1
- package/docs/acp.md +78 -0
- package/docs/agents.md +250 -0
- package/docs/codemode.md +28 -10
- package/docs/hooks.md +36 -32
- package/docs/permissions.md +212 -0
- package/docs/plan.md +107 -0
- package/docs/providers.md +261 -62
- package/docs/rewind-plan.md +181 -0
- package/docs/rpc.md +127 -40
- package/docs/sandbox.md +215 -0
- package/docs/session-format.md +43 -22
- package/docs/sessions.md +174 -0
- package/docs/tui-design.md +751 -0
- package/docs/tui.md +260 -64
- package/package.json +15 -2
package/docs/sandbox.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# 操作系统级沙箱
|
|
2
|
+
|
|
3
|
+
> 状态:第一阶段(`src/sandbox/**` 与 codemode 接入)与第二阶段(bash 沙箱与「沙箱内命令免审批」)都已实现。
|
|
4
|
+
|
|
5
|
+
## 为什么
|
|
6
|
+
|
|
7
|
+
codemode 子进程靠 Node 权限模型(`--permission`)隔离文件、子进程与 worker;网络只有 Node ≥ 25 的权限模型
|
|
8
|
+
才拒绝。Node 22 / 24 上脚本一旦逃出 `vm` 就能联网,所以这两个版本上 codemode 缺省关闭、权限类是 `execute`。
|
|
9
|
+
|
|
10
|
+
操作系统本身有现成的进程级沙箱:macOS 的 `sandbox-exec`(Seatbelt,SBPL 配置)、Linux 的 bubblewrap
|
|
11
|
+
(`bwrap`,命名空间 + 绑定挂载)。把子进程放进去,网络与写入由内核拒绝,不依赖 Node 版本,也不依赖 `vm` 没有
|
|
12
|
+
漏洞。第一阶段只用于 codemode 子进程;第二阶段给 bash 用。
|
|
13
|
+
|
|
14
|
+
## 分层
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
使用方 codemode 子进程(src/codemode/host-side.ts) bash(src/tools/bash.ts 的 spawnShell)
|
|
18
|
+
│ wrapCommand(status, node, args, policy) │ wrapBashCommand(src/sandbox/bash.ts)
|
|
19
|
+
OS 沙箱 src/sandbox/ ── detect.ts 探测 + 进程内缓存 + 开关
|
|
20
|
+
── profile.ts SBPL / bwrap / unshare 参数生成(纯函数)
|
|
21
|
+
── wrap.ts 输入命令行与策略 → 输出包装后的命令行
|
|
22
|
+
── bash.ts bash 的配置 → 会话内固定的设定、每次调用的策略、拒绝提示
|
|
23
|
+
平台 /usr/bin/sandbox-exec bwrap unshare -r -n (Windows:无)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `src/sandbox/**` 只依赖 `node:` 内置模块,不 import codemode、tools、permissions;使用方只拿到「包装后的
|
|
27
|
+
命令行」,自己 spawn。
|
|
28
|
+
- 策略 `OsSandboxPolicy`:`network: "deny" | "allow"`、`writable: string[]`(绝对路径;包装时取 realpath,
|
|
29
|
+
不存在的路径丢弃);bash 另用可选的 `readOnly`(可写目录里仍只读)、`hiddenDirs` / `hiddenFiles`(不可读)。
|
|
30
|
+
其余读取放开(见「安全边界」)。
|
|
31
|
+
- 状态 `OsSandboxStatus`:`kind`(`sandbox-exec` / `bwrap` / `unshare` / `none`)、可执行文件路径、
|
|
32
|
+
`isolatesNetwork`、`restrictsWrites`、给 doctor 的说明。
|
|
33
|
+
|
|
34
|
+
## 各平台实现
|
|
35
|
+
|
|
36
|
+
### macOS:`sandbox-exec`
|
|
37
|
+
|
|
38
|
+
`/usr/bin/sandbox-exec -p <profile> <命令> <参数…>`。`sandbox-exec` 在 `sandbox_init` 之后 `execvp`,pid
|
|
39
|
+
不变,进程组杀树照旧。配置(网络拒绝、只允许写 `/work`):
|
|
40
|
+
|
|
41
|
+
```scheme
|
|
42
|
+
(version 1)
|
|
43
|
+
(allow default)
|
|
44
|
+
(deny network*)
|
|
45
|
+
(deny mach-lookup (global-name "com.apple.dnssd.service"))
|
|
46
|
+
(deny file-write*)
|
|
47
|
+
(allow file-write* (subpath "/work"))
|
|
48
|
+
(allow file-write* (literal "/dev/null") (literal "/dev/zero") (literal "/dev/tty") (literal "/dev/dtracehelper") (regex #"^/dev/fd/"))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- `allow default` 起步再逐项拒绝:`deny default` 需要列出 Node 启动用到的 mach 服务、sysctl、IOKit 等,随系统
|
|
52
|
+
版本变化,维护成本高;我们要的只是「不联网、不越界写」。
|
|
53
|
+
- 网络:`network*` 覆盖 TCP / UDP / Unix 域套接字的 bind、connect、inbound。DNS:macOS 的解析经 mDNSResponder
|
|
54
|
+
(Unix 套接字 `/var/run/mDNSResponder`,已被 `network*` 拒绝),另外拒绝 mach 服务
|
|
55
|
+
`com.apple.dnssd.service`,堵住经 DNS 查询外带数据的通道(实测 `dns.lookup` 返回 `ENOTFOUND`)。
|
|
56
|
+
- 路径:SBPL 按真实路径(vnode)匹配。`/tmp`、`/var` 是指向 `/private/…` 的符号链接,临时目录在
|
|
57
|
+
`/private/var/folders/…`;所以可写目录一律先 `realpath`,字符串转义 `\` 与 `"`,含控制字符的路径拒绝。
|
|
58
|
+
- `/dev/null` 等设备单独放行写;stdin / stdout / stderr 是继承的管道描述符,不经路径检查。
|
|
59
|
+
|
|
60
|
+
### Linux:bubblewrap,退而 `unshare`
|
|
61
|
+
|
|
62
|
+
`bwrap --die-with-parent --ro-bind / / --dev /dev [--unshare-net] [--bind P P …] -- <命令> <参数…>`:
|
|
63
|
+
|
|
64
|
+
- `--ro-bind / /` 递归只读绑定整个根(含 `/proc`、`/sys` 子挂载),`--dev /dev` 给一份最小的 devtmpfs
|
|
65
|
+
(`/dev/null` 可写),可写目录再逐个 `--bind` 回来;
|
|
66
|
+
- `--unshare-net`:新网络命名空间,只有 down 的 lo,连本机端口也不通;
|
|
67
|
+
- 不用 `--unshare-pid` / `--proc`(挂 procfs 需要自己的 pid 命名空间);不用 `--new-session`(会让子进程脱离
|
|
68
|
+
进程组,超时杀树失效;codemode 的 stdio 是管道,没有 TIOCSTI 注入面——第二阶段 bash 再评估);
|
|
69
|
+
- `--die-with-parent`:ama 退出时沙箱里的进程一起结束。
|
|
70
|
+
|
|
71
|
+
没有 bwrap 时试 `unshare -r -n -- <命令>`(用户命名空间映射为 root + 新网络命名空间):**只隔离网络,不限制
|
|
72
|
+
写入**。codemode 的写入已由 Node 权限模型拒绝,所以对 codemode 足够;第二阶段的 bash 要求限制写入,只认 bwrap。
|
|
73
|
+
需要内核允许非特权用户命名空间:Ubuntu 23.10 起 AppArmor 默认限制(`kernel.apparmor_restrict_unprivileged_userns`),
|
|
74
|
+
`unshare` 往往失败;发行版的 bwrap 包带 AppArmor 配置,通常可用。
|
|
75
|
+
|
|
76
|
+
### Windows
|
|
77
|
+
|
|
78
|
+
没有可零依赖调用的进程级沙箱(AppContainer / Job Object 需要原生代码)。`kind: none`,行为与现状相同。
|
|
79
|
+
|
|
80
|
+
## 探测与降级
|
|
81
|
+
|
|
82
|
+
- 「存在」不等于「可用」:嵌套在别的沙箱里时 `sandbox_init` 会失败,容器里没有用户命名空间时 bwrap 会失败。
|
|
83
|
+
所以探测是**用目标配置跑一次最小探针**:macOS `sandbox-exec -p <拒绝网络与写入的配置> /usr/bin/true`;Linux
|
|
84
|
+
`bwrap … --unshare-net -- true`,失败再试 `unshare -r -n -- true`。退出码 0 才算可用,5 秒超时。
|
|
85
|
+
- 结果在进程内缓存(一次 `spawnSync`,约 10 ms);探针的副作用为零。
|
|
86
|
+
- 开关:`sandbox.enabled`(`auto` 缺省 / `off`),环境变量 `AMA_SANDBOX=off` 覆盖。`off` 时 `kind: none`,
|
|
87
|
+
说明写明是用户关闭。
|
|
88
|
+
|
|
89
|
+
降级真值表(codemode):
|
|
90
|
+
|
|
91
|
+
| Node | OS 沙箱 | 网络隔离来源 | strict | codemode 权限类 | `default` 预设 |
|
|
92
|
+
| ------- | ------------------------------ | ------------------ | ------ | --------------- | --------------- |
|
|
93
|
+
| ≥ 25 | 可用 | Node 权限模型 + OS | 是 | read | on |
|
|
94
|
+
| ≥ 25 | 不可用 / off | Node 权限模型 | 是 | read | on |
|
|
95
|
+
| 22 / 24 | sandbox-exec / bwrap / unshare | OS 沙箱 | 是 | read | on |
|
|
96
|
+
| 22 / 24 | 不可用 / off / Windows | 无(`net!`) | 否 | execute | off(提示一次) |
|
|
97
|
+
|
|
98
|
+
- Node ≥ 25 也叠加 OS 沙箱(纵深防御)。Node ≥ 25 时 strict 只靠 Node 权限模型,OS 沙箱不可用不改变任何
|
|
99
|
+
结论;Node 22 / 24 时 strict 依赖 OS 沙箱,所以子进程**必须**经包装启动,包装失败就报错,不悄悄裸跑。
|
|
100
|
+
- 能力只在启动时探测一次,之后同一进程内不变:工具描述(`Sandbox: …` 行、`network not isolated`)与权限类
|
|
101
|
+
在同一环境下逐字节稳定(设计 §9.1)。换机器 / 换 Node / 改 `sandbox.enabled` 才可能变。
|
|
102
|
+
- 传入假设的 Node 版本做计算(测试、展示)时不探测 OS 沙箱,按「不可用」处理,需要时显式传入状态。
|
|
103
|
+
|
|
104
|
+
## 配置
|
|
105
|
+
|
|
106
|
+
| 键 | 取值 | 缺省 | 说明 |
|
|
107
|
+
| ------------------ | ----------------- | ------ | --------------------------------------------------------------------------------------------------- |
|
|
108
|
+
| `sandbox.enabled` | `auto` \| `off` | `auto` | `auto`:探测可用就用;`off`:不用 OS 沙箱(codemode 与 bash 都不用)。`AMA_SANDBOX=off` 覆盖 |
|
|
109
|
+
| `sandbox.bash` | `auto` \| `off` | `off` | bash 经 OS 沙箱运行(见「第二阶段」)。只认 sandbox-exec / bwrap |
|
|
110
|
+
| `sandbox.network` | `deny` \| `allow` | `deny` | bash 沙箱里的网络。`deny` 是 default 模式免审批的前提 |
|
|
111
|
+
| `sandbox.writable` | 字符串数组 | `[]` | bash 沙箱追加的可写目录(绝对路径或 `~/…`;相对路径 warning 并忽略),例如 `["~/.npm", "~/.cache"]` |
|
|
112
|
+
|
|
113
|
+
- codemode 的策略是固定的(网络拒绝、不可写),不受 `network` / `writable` 影响。
|
|
114
|
+
- 只认用户级 / profile。项目级 `.ama/config.json` 只接受收紧的 `sandbox.network: "deny"`,其余忽略并 warning:
|
|
115
|
+
`enabled` / `bash` 两个方向都不是单纯更严(打开 bash 沙箱会让 default 模式的命令免审批,关闭会让命令裸跑),
|
|
116
|
+
`writable` 是放宽。
|
|
117
|
+
- 与第五波 C0 的键不冲突:现有配置没有 `sandbox` 段;`codemode.requireStrict` 语义扩展为「网络既不由 Node
|
|
118
|
+
权限模型、也不由 OS 沙箱隔离时禁用」。
|
|
119
|
+
|
|
120
|
+
## 安全边界与已知绕过
|
|
121
|
+
|
|
122
|
+
- 沙箱防的是「脚本 / 命令绕过权限管线去联网或越界写」,不是对抗内核漏洞的隔离环境。
|
|
123
|
+
- 读取基本不限制:codemode 的读取已由 Node 权限模型限制为只读入口文件;bash 沙箱拒读凭据目录(见「第二阶段」),
|
|
124
|
+
其余可读。
|
|
125
|
+
- `sandbox-exec` 被苹果标为 deprecated(man page),但仍随系统提供,系统组件与主流工具都在用;哪天移除,探针
|
|
126
|
+
失败,自动降级到现状。SBPL 没有公开规范,语义以实测为准(集成测试在 macOS CI 上跑)。
|
|
127
|
+
- `allow default` 意味着未列出的操作都允许:例如 mach IPC 到其它系统服务、`process-exec`。codemode 子进程的
|
|
128
|
+
子进程 / worker 已被 Node 权限模型拒绝;bash 会运行任意程序,`process-exec` 白名单不现实,重点仍是网络与写入
|
|
129
|
+
(mach IPC 的余地见「第二阶段」的已知绕过)。
|
|
130
|
+
- 已有的进程外通道仍在:与父进程的 stdin / stdout(codemode 协议本身)、继承的描述符。codemode 父进程只认
|
|
131
|
+
JSON 行协议,工具调用照常过权限。
|
|
132
|
+
- Linux `unshare` 不限制写入;`--ro-bind` 不挡已打开的可写描述符;`/dev/shm` 在 `--dev /dev` 下是新的。
|
|
133
|
+
- 环境变量:codemode 子进程本来就以空环境启动;沙箱不改变这一点。
|
|
134
|
+
|
|
135
|
+
## 第二阶段:bash 沙箱与免审批
|
|
136
|
+
|
|
137
|
+
实现:`src/sandbox/bash.ts`(设定与策略)、`src/tools/bash.ts` 的 `spawnShell`(唯一的进程创建点,前台与后台
|
|
138
|
+
共用)、`src/permissions/pipeline.ts`(判定)。组装根(`src/cli/compose.ts`)算一次设定,同一份交给 bash 工具与
|
|
139
|
+
权限管线,「这次调用会不会在沙箱里跑」两边结论一致。
|
|
140
|
+
|
|
141
|
+
### 生效条件与缺省
|
|
142
|
+
|
|
143
|
+
- `sandbox.bash: auto` 且探测到能限制写入的沙箱(`sandbox-exec` / bwrap)才生效;`unshare` 只隔离网络,不算;
|
|
144
|
+
Windows、探测失败、`sandbox.enabled: off`、`AMA_SANDBOX=off` → 不包装,行为与以前完全相同。
|
|
145
|
+
- **`sandbox.bash` 缺省 `off`**:沙箱会让写 `~/.npm`、`~/.cache`、`~/.cargo` 的常见命令失败,先让用户试、按需
|
|
146
|
+
用 `sandbox.writable` 补目录;开了才有免审批的好处。
|
|
147
|
+
- **`sandbox.network` 缺省 `deny`**:联网可外带数据,只有拒绝网络时「沙箱内免审批」才成立。`npm install` 之类
|
|
148
|
+
在沙箱里会失败,模型看到拒绝提示后用 `sandbox: false` 重跑并经用户审批;想让它们在沙箱里直接成功,设
|
|
149
|
+
`network: "allow"`,代价是这些命令不再免审批(写入仍受限)。
|
|
150
|
+
- 设定在会话开始时确定、会话内不变:沙箱生效时 bash 工具的 schema 多一个 `sandbox` 布尔参数、描述末尾多一句
|
|
151
|
+
(`Runs in an OS sandbox (writes only in workspace/temp, no network); sandbox:false needs approval.`);不生效时
|
|
152
|
+
工具定义与以前逐字节相同。打开 `sandbox.bash` 后首个请求未命中缓存一次。
|
|
153
|
+
|
|
154
|
+
### 每次调用的策略
|
|
155
|
+
|
|
156
|
+
| 项 | 内容 |
|
|
157
|
+
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
158
|
+
| 可写 | 会话工作区(会话 cwd)、系统临时目录(`os.tmpdir()`)、POSIX 的 `/tmp`、ama 的输出目录(截断全文、后台输出)、`sandbox.writable`;`/dev/null` 等设备 |
|
|
159
|
+
| 只读 | 工作区里的 `.ama/`(项目 Hook 与配置)、`.git/hooks`、`.git/config`(`core.hooksPath`、`core.fsmonitor` 能让之后在沙箱外运行的 git 执行任意命令) |
|
|
160
|
+
| 不可读 | `~/.ssh`、`~/.gnupg`、`~/.aws`、`~/.kube`、`~/.docker/config.json`、`~/.config/gcloud`、`~/.netrc`、`~/.pgpass`、`~/.git-credentials`、ama 的 `auth.json`(与权限规则层的机密路径同一批) |
|
|
161
|
+
| 网络 | `sandbox.network` |
|
|
162
|
+
|
|
163
|
+
- macOS:SBPL 里后出现的规则优先,只读 / 不可读规则排在允许之后;不存在的只读路径按「父目录 realpath + 名字」
|
|
164
|
+
写进配置,挡住新建(例如沙箱里 `mkdir .ama`)。
|
|
165
|
+
- Linux bwrap:只读路径在可写绑定之后 `--ro-bind` 回去,不可读目录挂空 `--tmpfs`、文件挂 `/dev/null`;bwrap 只能
|
|
166
|
+
挂到已存在的路径,**不存在的 `.ama/`、`.git/hooks` 挡不住新建**(已知限制)。
|
|
167
|
+
- 包装失败(不应发生)时报错,不悄悄裸跑:权限管线已按「在沙箱内」放行。
|
|
168
|
+
|
|
169
|
+
### 越出沙箱
|
|
170
|
+
|
|
171
|
+
- 命令非零退出、且输出像是被沙箱拒绝(`Operation not permitted`、`Read-only file system`、`EPERM`、`EACCES`;
|
|
172
|
+
`network: deny` 时另看 `Could not resolve host`、`ENOTFOUND`、`ECONNREFUSED` 等)时,输出末尾追加一行:
|
|
173
|
+
`[sandbox: this command ran in ama's OS sandbox (…). If it failed because of that, rerun it with sandbox:false,
|
|
174
|
+
which needs the user's approval.]`。按文本猜测,可能误报(同样的错误不是沙箱造成的),提示写的是「如果」。
|
|
175
|
+
- `bash{…, sandbox: false}` 不经沙箱运行,**一律走正常审批**:default / auto-edit 询问(allow 规则、Hook allow、
|
|
176
|
+
会话记忆可放行),auto 在规则层询问(不交给分类器),无人值守拒绝;full-auto 照旧放行;plan / allowlist 语义
|
|
177
|
+
不变。结构化结果 `sandboxed: true` 标出经沙箱运行的调用(前台与后台)。
|
|
178
|
+
|
|
179
|
+
### 权限集成
|
|
180
|
+
|
|
181
|
+
判定顺序见 [permissions.md](permissions.md)「判定顺序」。要点:
|
|
182
|
+
|
|
183
|
+
- default / auto-edit:bash 调用若 (a) 将在沙箱内运行(没请求 `sandbox: false`)、(b) 沙箱拒绝网络、(c) 命令
|
|
184
|
+
文本(含嵌套的 `sh -c` 等)不碰机密路径、(d) 嵌套不超深,模式产生的「询问」变「放行」。deny 规则、危险命令表、
|
|
185
|
+
Hook ask 仍先于它生效。
|
|
186
|
+
- auto:沙箱不直接放行。规则层(网络、删除、受保护路径、项目外写入)与静态判定照旧;交给分类器的调用附一行
|
|
187
|
+
`os_sandbox`(写入受限、网络是否拒绝)作为输入之一。理由:auto 的规则层是有意比 default 更细的防线,分类器
|
|
188
|
+
仍是最后一关;直接放行会让 `rm -r` 这类规则层本该询问的命令绕过它。代价是 default + 沙箱放行的部分命令
|
|
189
|
+
(例如工作区里的 `rm -r dist`)在 auto 下仍会询问。
|
|
190
|
+
- plan、allowlist、full-auto 语义不变。
|
|
191
|
+
|
|
192
|
+
### 已知绕过与限制
|
|
193
|
+
|
|
194
|
+
- **工作区内的写入不再逐次审批**:default 模式下 `write` / `edit` 工具仍询问,而沙箱里的 `echo … > src/a.ts`、
|
|
195
|
+
`rm -r build` 免审批。这是设计取舍(同类产品的 auto-allow-if-sandboxed 也如此);需要逐条看就别开 `sandbox.bash`。
|
|
196
|
+
- **读工作区里的机密文件**:OS 沙箱不挡工作区内的读,输出会进模型上下文。文本里出现机密路径(`cat .env`)的命令
|
|
197
|
+
不免审批,但 `cat $(ls -a | grep env)` 这类动态拼出的路径看不出来。需要更严时对 `.env` 加 deny 规则。
|
|
198
|
+
- **留给沙箱外执行的内容**:沙箱里可以改 `package.json` 的 scripts、`Makefile` 等,之后在沙箱外(用户自己、
|
|
199
|
+
`sandbox: false`)运行时生效。`.ama/`、`.git/hooks`、`.git/config` 已只读,其它构建配置不在名单里。
|
|
200
|
+
- `sandbox.writable` 加了家目录下的缓存目录时,沙箱里的命令能改它们(例如往 `~/.npm` 写入被污染的包缓存)。
|
|
201
|
+
- macOS `allow default`:mach IPC 到其它系统服务、`process-exec` 未限制;DNS 已拒绝,其余 XPC 服务理论上可能
|
|
202
|
+
被用来间接联网或写文件(未逐个审计)。
|
|
203
|
+
- Linux bwrap 不用 `--new-session`(保留进程组,超时杀树才有效),终端注入面不存在:bash 的 stdio 是管道或
|
|
204
|
+
文件,不是终端。不用 `--unshare-pid`:沙箱里能看到并向同用户的进程发信号。
|
|
205
|
+
- 后台 bash 由 ama 打开输出文件再交给子进程,输出目录无论在不在可写列表都能写。
|
|
206
|
+
- SDK(`createAgent`)不读 `sandbox.bash`,bash 不包装、权限照旧。
|
|
207
|
+
|
|
208
|
+
### 测试
|
|
209
|
+
|
|
210
|
+
- `src/permissions/sandbox-pipeline.test.ts`:假状态的真值表(模式 × 是否在沙箱内 × 危险命令 / deny / Hook ask /
|
|
211
|
+
机密路径 / `sandbox: false` × 无人值守)。
|
|
212
|
+
- `src/tools/bash-sandbox.test.ts`、`src/cli/bash-sandbox-e2e.test.ts`:真机(macOS CI 的 sandbox-exec;Linux 有
|
|
213
|
+
bwrap 时),写工作区成功、写工作区外失败并带提示、`.git/hooks` 只读、凭据目录不可读、`network: deny` 连不上
|
|
214
|
+
本机端口、`sandbox: false` 不包装且无人值守时被拒、后台 bash 也被包装、从用户级配置生效且项目级关不掉。
|
|
215
|
+
没有能限制写入的沙箱时跳过(Linux runner 没装 bubblewrap 或不允许用户命名空间时这组跳过)。
|
package/docs/session-format.md
CHANGED
|
@@ -31,19 +31,19 @@
|
|
|
31
31
|
|
|
32
32
|
全部条目都有 `id`、`parentId`(根条目为 `null`)、`timestamp`(ISO 8601)。
|
|
33
33
|
|
|
34
|
-
| `type` | 字段
|
|
35
|
-
| ----------------------- |
|
|
36
|
-
| `message` | `message`:`system` / `user` / `assistant` / `toolResult` 四种 LLM 消息
|
|
37
|
-
| `compaction` | `summary`、`firstKeptEntryId`、`tokensBefore`、`usage?`、`details?`(`readFiles` / `modifiedFiles`)
|
|
38
|
-
| `branch_summary` | `fromId`、`summary`、`usage?`、`details?`
|
|
39
|
-
| `context_edit` | `targetId`、`replacement: string \| null`、`reason: prune \| abort \| retry \| overflow \| manual`
|
|
40
|
-
| `model_change` | `provider`、`modelId`、可选 `channel`(多渠道供应商的渠道名)
|
|
41
|
-
| `thinking_level_change` | `thinkingLevel`
|
|
42
|
-
| `custom` | `customType`、`data`
|
|
43
|
-
| `custom_message` | `customType`、`content`(字符串或内容块)、`display`、`details?`
|
|
44
|
-
| `label` | `targetId`、`label?`(缺省 = 清除标签)
|
|
45
|
-
| `session_info` | `name?`
|
|
46
|
-
| `usage` | `kind`、`provider`、`model`(不含 provider 的模型 id)、`usage`
|
|
34
|
+
| `type` | 字段 | 进上下文 |
|
|
35
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
|
|
36
|
+
| `message` | `message`:`system` / `user` / `assistant` / `toolResult` 四种 LLM 消息 | 是 |
|
|
37
|
+
| `compaction` | `summary`、`firstKeptEntryId`、`tokensBefore`、`usage?`、`details?`(`readFiles` / `modifiedFiles`) | 是,作为摘要消息 |
|
|
38
|
+
| `branch_summary` | `fromId`、`summary`、`usage?`、`details?` | 是,作为分支摘要消息 |
|
|
39
|
+
| `context_edit` | `targetId`、`replacement: string \| null`、`reason: prune \| abort \| retry \| overflow \| manual \| image_budget` | 改写目标条目 |
|
|
40
|
+
| `model_change` | `provider`、`modelId`、可选 `channel`(多渠道供应商的渠道名) | 否(决定续会话时的模型) |
|
|
41
|
+
| `thinking_level_change` | `thinkingLevel` | 否(决定续会话时的思考级别) |
|
|
42
|
+
| `custom` | `customType`、`data` | 否 |
|
|
43
|
+
| `custom_message` | `customType`、`content`(字符串或内容块)、`display`、`details?` | 是,作为 custom 消息 |
|
|
44
|
+
| `label` | `targetId`、`label?`(缺省 = 清除标签) | 否 |
|
|
45
|
+
| `session_info` | `name?` | 否 |
|
|
46
|
+
| `usage` | `kind`、`provider`、`model`(不含 provider 的模型 id)、`usage` | 否 |
|
|
47
47
|
|
|
48
48
|
### 消息
|
|
49
49
|
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
### `usage` 条目
|
|
56
56
|
|
|
57
|
-
不进上下文的请求用量,计入 `/session` 费用与 RPC
|
|
57
|
+
不进上下文的请求用量,计入 `/session` 费用与 RPC 统计,投影时跳过。`kind` 目前有 `"cache_warm"`(缓存保温请求,见 [providers.md](providers.md)「缓存」)与 `"permission_classify"`(auto 权限模式的分类请求,见 [permissions.md](permissions.md)):
|
|
58
58
|
|
|
59
59
|
```json
|
|
60
60
|
{
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
当前分支 → 上下文消息(`src/session/projection.ts`):
|
|
88
88
|
|
|
89
89
|
1. **压缩**:分支上若有 `compaction`,取最新一条。上下文 = 该 compaction(作为摘要消息)+ `firstKeptEntryId` 到它之间的非 system 条目 + 它之后的全部条目。compaction 之前的 system 消息依次重放后折成一条完整的 system **检查点**放在最前(文件里不另存检查点)。
|
|
90
|
-
2. **改写**:对分支上每个目标取最新一条 `context_edit`:`replacement` 为 `null` → 从上下文剔除;字符串 → 只换内容,保留角色与元数据(assistant 换成一个文本块,摘要类换 `summary`,system 不改)。用途:档一裁剪旧工具结果(`prune`)、中断(`abort`)、失败重试的尝试(`retry`)、溢出恢复(`overflow`)、手动(`manual
|
|
90
|
+
2. **改写**:对分支上每个目标取最新一条 `context_edit`:`replacement` 为 `null` → 从上下文剔除;字符串 → 只换内容,保留角色与元数据(assistant 换成一个文本块,摘要类换 `summary`,system 不改)。用途:档一裁剪旧工具结果(`prune`)、中断(`abort`)、失败重试的尝试(`retry`)、溢出恢复(`overflow`)、手动(`manual`)、单请求图片总量超预算时把最旧的图换成占位文本(`image_budget`,第五波 W5-I)。
|
|
91
91
|
3. **映射**:`message` → 原消息;`custom_message` → `{ role: "custom", customType, content, display, details? }`;`compaction` → `{ role: "compactionSummary", summary, tokensBefore }`;`branch_summary` → `{ role: "branchSummary", summary, fromId }`;其余类型(含 `usage` 与未知类型)不进上下文。
|
|
92
92
|
4. **模型与思考级别**:分支上最近的 `model_change` / `thinking_level_change`,续会话时据此恢复。
|
|
93
93
|
|
|
@@ -103,17 +103,38 @@
|
|
|
103
103
|
|
|
104
104
|
`custom` 不进上下文,`custom_message` 进上下文。ama 自己使用的 `customType`:
|
|
105
105
|
|
|
106
|
-
| `customType` | 条目类型 | 内容
|
|
107
|
-
| -------------------- | ---------------- |
|
|
108
|
-
| `ama.todo` | `custom` | `data: { items: { id, text, status: pending \| in_progress \| done }[] }`,整表快照 | `todo` 工具 `set
|
|
109
|
-
| `ama.task` | `custom` | `data: { parentToolCallId, description, parentSession? }
|
|
110
|
-
| `ama.codemode-store` | `custom` | `data: { entries }`,`store()` 的完整快照
|
|
111
|
-
| `ama.aborted` | `custom_message` | `content`:告诉模型上一条回复被用户中断;`display: false`
|
|
112
|
-
| `ama.hook_context` | `custom_message` | `content`:UserPromptSubmit Hook 的 `additionalContext`;`display: false`
|
|
106
|
+
| `customType` | 条目类型 | 内容 | 写入时机 |
|
|
107
|
+
| -------------------- | ---------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
108
|
+
| `ama.todo` | `custom` | `data: { items: { id, text, status: pending \| in_progress \| done, planStep? }[] }`,整表快照 | `todo` 工具 `set` / `update`、计划获批时由步骤生成(W5-F);`get` 取分支上最近一条 |
|
|
109
|
+
| `ama.task` | `custom` | `data: { parentToolCallId, description, parentSession? }`;第五波见表后说明 | `task` 子会话的首条条目;第五波起父会话也写 |
|
|
110
|
+
| `ama.codemode-store` | `custom` | `data: { entries }`,`store()` 的完整快照 | codemode 脚本成功结束且写过 store;读取取分支上最近一条 |
|
|
111
|
+
| `ama.aborted` | `custom_message` | `content`:告诉模型上一条回复被用户中断;`display: false` | 用户中断运行 |
|
|
112
|
+
| `ama.hook_context` | `custom_message` | `content`:UserPromptSubmit Hook 的 `additionalContext`;`display: false` | 随用户提示进上下文 |
|
|
113
|
+
| `ama.rewind-note` | `custom_message` | `content`:回滚后哪些文件与对话不一致(最多列 20 个);`display: false` | 仅对话 / 仅代码回滚后,下一次提示之前追加在末尾 |
|
|
114
|
+
|
|
115
|
+
`ama.task`(第五波 W5-G):子会话首条的 `data` 另带 `taskId`、`agent`;父会话在任务开始、每次续聊与结束时各写一条,
|
|
116
|
+
`data` = `TaskInfo`(`taskId, agent, runner, description, background, status, startedAt, endedAt?, turns?, usage?, costUsd?,
|
|
117
|
+
outputFile?, sessionRef?`)+ `parentToolCallId`、`cwd`。同一 `taskId` 取分支上最后一条;resume 时据此重建任务注册表,
|
|
118
|
+
`status: "running"` 视为 `interrupted`(`taskId` 续聊重开 `sessionRef.sessionFile`)。没有 `status` 的是子会话自己的首条。
|
|
119
|
+
|
|
120
|
+
第五波登记的类型(docs/wave5-plan.md;括号里是开始写入的批次,之前的版本不会产生,读到未知 `customType` 一律忽略)。`custom_message` 类都是 `display: false`,经扩展点 `beforePrompts` 追加在末尾,不改缓存前缀:
|
|
121
|
+
|
|
122
|
+
| `customType` | 条目类型 | 内容 | 写入时机 |
|
|
123
|
+
| -------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
124
|
+
| `ama.plan` | `custom` | `data: PlanData`:`{ id, version, status: proposed \| approved \| rejected \| superseded, markdown, steps[], sourceEntryId, filePath? }` | 根会话在 plan 下一回合以纯文本结束、回复里有 `<proposed_plan>` 时;审批结果(approved / rejected / superseded)另记一条(W5-F) |
|
|
125
|
+
| `ama.plan_state` | `custom` | `data: { active, prePlanMode, planId?, executionModel?, executionThinking? }`(后两项:`plan.model` 切走的执行模型) | 进入 / 退出 plan 模式;resume 时据此回到 plan(W5-F) |
|
|
126
|
+
| `ama.plan_mode` | `custom_message` | `content`:plan 模式说明(完整版或简版) | 进入 plan 后的首个提示前,之后每 5 回合简版、压缩后补完整版(W5-F) |
|
|
127
|
+
| `ama.plan_mode_exit` | `custom_message` | `content`:已退出 plan 模式 | 手动退出 plan 后的下一次提示前(获批时由 `ama.plan_approved` 说明,不另发)(W5-F) |
|
|
128
|
+
| `ama.plan_approved` | `custom_message` | `content`:获批计划全文、文件路径与进度记法(有 todo 工具时「按 todo 推进」,没有时「每完成一步单独一行写 `[DONE:<步骤>]`」) | 计划获批交接时(W5-F) |
|
|
129
|
+
| `ama.post_compact` | (不单独成条) | 回注改为 `compaction.summary` 末尾的 `<post-compact-state>` 块(清单与指针,不含正文;见 `compaction/post-compact.ts`) | 写 compaction 条目时(W5-H1),模型看到「摘要 → 回注 → 保留区」 |
|
|
130
|
+
| `ama.reminder` | `custom_message` | `content`:提醒(todo 复述、外部文件改动、上下文用量、预算余量、后台命令退出),`<system-reminder>` 包起来 | 新提示之前按 `reminders.*` 追加(W5-H2);run 进行中的提醒不单独成条,追加在工具批次最后一条 toolResult 的末尾 |
|
|
131
|
+
| `ama.agent-session` | `custom` | `data: { agent, runner, sessionId, cwd?, taskId? }`:外部 Agent 自己的会话引用(不含原始事件与转录) | 外部 Agent 会话建立 / 续聊时(W5-E) |
|
|
132
|
+
| `ama.agent-usage` | `custom` | `data: { agent, sessionId, unit: usd \| tokens \| requests, amount, tokens? }` | 外部 Agent 每个回合结束(W5-E);`SessionStats.external` 据此汇总 |
|
|
113
133
|
|
|
114
134
|
其它程序(宿主、SDK 工具经 `ToolContext.session.appendCustom`)可以写自己的 `customType`;建议加前缀避免冲突,`ama.` 前缀保留给 ama。
|
|
115
135
|
|
|
116
136
|
## 读取方
|
|
117
137
|
|
|
118
138
|
- `ama sessions list|show`、交互模式 `/resume`、RPC `get_entries{since}`(以 entry id 为游标返回 `{ entries, leafId }`)、`get_tree`。
|
|
139
|
+
- 只读扫描(不加锁、不修复):`ama stats`、`ama sessions search|export`、`--from`,见 [sessions.md](sessions.md)。
|
|
119
140
|
- 嵌入方可以直接读文件:按行解析,首行为头,跳过 `type: "leaf"` 的行后按 `parentId` 建树;遇到不认识的条目类型保留但不进上下文。
|
package/docs/sessions.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# 会话统计、检索、复用、导出与检查点
|
|
2
|
+
|
|
3
|
+
这几条命令都只读会话目录(`<数据目录>/sessions`,`--session-dir` 可改;文件格式见 [session-format.md](session-format.md)):不加锁、不修复半行、不改文件,正在运行的会话也能读。范围缺省是**当前目录**的会话,`--all` 看全部。
|
|
4
|
+
|
|
5
|
+
## 统计:`ama stats`
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
ama stats [--since 7d|30d|today|YYYY-MM-DD] [--until …]
|
|
9
|
+
[--by day|week|month|provider|channel|model|project]
|
|
10
|
+
[--project <目录> | --all] [--top N] [--json] [--no-cache]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
$ ama stats --by model
|
|
15
|
+
全部时间 · 项目 /home/me/proj · 2 个会话
|
|
16
|
+
请求 9(对话 7 · permission_classify 1 · cache_warm 1)
|
|
17
|
+
回合 3 · 平均耗时 23.3s
|
|
18
|
+
Token 输入 8.7k · 输出 1.7k · 缓存读 74.3k · 缓存写 0
|
|
19
|
+
缓存命中率 89.5%(报告缓存的端点 2/2,其余不进分母)
|
|
20
|
+
费用 $0.0398(另有 3 次请求无价,未计入)
|
|
21
|
+
错误 / 重试 0 / 0
|
|
22
|
+
|
|
23
|
+
会话 请求 回合 输入 输出 缓存读 缓存写 命中率 费用
|
|
24
|
+
anthropic/claude-sonnet-4-5 1 6 2 4.1k 731 72.3k 0 94.6% $0.0398
|
|
25
|
+
packy/deepseek-v4-flash 1 3 1 4.6k 980 2k 0 30.8% —
|
|
26
|
+
|
|
27
|
+
工具调用 Top 5
|
|
28
|
+
read 3
|
|
29
|
+
edit 2
|
|
30
|
+
…
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- `--since` / `--until`:`7d` 是含今天的最近 7 天,`today` 是今天,日期是本地日期;两端都含。
|
|
34
|
+
- `--by project` 没给 `--project` 时看全部项目。`--json` 输出同样的数据(另带 `files`:扫描 / 命中缓存 / 无效的文件数)。
|
|
35
|
+
|
|
36
|
+
### 口径
|
|
37
|
+
|
|
38
|
+
| 项 | 怎么算 |
|
|
39
|
+
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| 请求 | 每次模型请求一次:回合里的 assistant 消息记「对话」;`usage` 条目按 `kind` 分开(`cache_warm` 保温、`permission_classify` auto 分类…);`compaction` / `branch_summary` 带的用量记同名 kind。失败后重试的那次也算请求 |
|
|
41
|
+
| 回合 | 一条非 `steer` 的用户消息开始一个回合,到下一条为止;至少有一条 assistant 才计。耗时 = 最后一条 assistant 的落盘时间 − 用户消息的落盘时间 |
|
|
42
|
+
| token | `input` 不含缓存部分(同会话层);缓存读 / 写分开列 |
|
|
43
|
+
| 缓存命中率 | cacheRead /(input + cacheRead + cacheWrite),只算**报告缓存**的端点:同一 `provider/model@channel` 在扫描范围内出现过任何非零缓存读写才算;其余端点不进分母(与会话层三态一致,不报缓存的中转不会把命中率拉成 0) |
|
|
44
|
+
| 费用 | 只加带 `usage.cost` 的请求(模型有价格);无价请求数单独报,全部无价时只给 token |
|
|
45
|
+
| 工具调用 | assistant 里的工具调用块按名字计;codemode 脚本内的调用不展开 |
|
|
46
|
+
| 错误 / 重试 | `stopReason: "error"` 的 assistant;`context_edit{reason:"retry"}`(自动重试剔除的失败尝试) |
|
|
47
|
+
| 渠道 | 最近一条 `model_change` 与请求同 provider / model 时取它的 `channel` |
|
|
48
|
+
|
|
49
|
+
`task` 子会话是独立文件,按它自己的 cwd 计入。
|
|
50
|
+
|
|
51
|
+
### 性能与索引
|
|
52
|
+
|
|
53
|
+
- 扫描按行进行;`toolResult`、`custom`、`label` 等与统计无关的行按行首的 `{"type":…,"message":{"role":…` 直接跳过、不解析(ama 写的行 type 总是第一个键;别的程序写的行退回完整解析)。
|
|
54
|
+
- 每个文件的摘要缓存在 `<数据目录>/stats-index.json`,按文件 mtime 与大小失效;时区变化整份作废;扫描全部时顺带删掉已不存在的文件。`--no-cache` 不读也不写。
|
|
55
|
+
- 实测(本机,`src/session/stats-perf.test.ts`):1000 个会话、67 MB(每个 12 回合、24 次工具调用、2 KB 工具结果),冷扫描约 160 ms,命中索引约 15 ms。
|
|
56
|
+
|
|
57
|
+
## 检索:`ama sessions search`
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
ama sessions search <关键词|/正则/标志> [--all] [--role user|assistant|tool] [--since 7d] [--limit N] [--json]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
$ ama sessions search parser
|
|
65
|
+
3f9a1c2e#1 2026-09-29 01:00 /home/me/proj user 修复 parser 在空输入时崩溃的 bug
|
|
66
|
+
3f9a1c2e@4 2026-09-29 01:00 /home/me/proj tool src/parser.ts:42: if (input.length === 0)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- 关键词不区分大小写;`/…/` 是 JavaScript 正则(标志照写,如 `/todo|fixme/i`)。
|
|
70
|
+
- 检索用户文本、助手文本与工具调用(`名字 参数 JSON`)、工具结果;不检索思考、system 与 custom。`--role` 可逗号分隔多个。
|
|
71
|
+
- 每行:会话 id 前 8 位 + 编号(user 是 `#n`,可直接给 `--from`;其它是条目序号 `@k`,即文件里第 k 条条目)、时间、项目、角色、片段。stdout 是终端且没设 `NO_COLOR` 时命中处高亮,否则纯文本。`--json` 每条命中一行。
|
|
72
|
+
- 最新的会话在前;`--limit` 缺省 20。关键词不含引号与反斜杠时先在原始行上预筛,不命中的行不解析。
|
|
73
|
+
|
|
74
|
+
## 复用:`sessions show` 编号与 `--from`
|
|
75
|
+
|
|
76
|
+
`ama sessions show <id>` 在末尾列出用户消息,按文件顺序编号(含插话 `steer`、排队 `followUp` 与宿主注入,标出 origin 与图片数):
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
用户消息(ama --from 3f9a1c2e#<编号> 复用):
|
|
80
|
+
#1 2026-09-29 01:00:06 修复 parser 在空输入时崩溃的 bug
|
|
81
|
+
#2 2026-09-29 01:00:44 顺便把错误信息改成中文
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`--from <id>[#编号]` 用那条消息作新提示(不写编号取最后一条),开的是新会话,可以换模型:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
ama -p --from 3f9a1c2e#1 --model packy/deepseek-v4-flash # 同一个问题换个模型问
|
|
88
|
+
ama -p --from 3f9a1c2e "只改测试,不动实现" # 位置参数接在原文后面(空一行)
|
|
89
|
+
ama --from 3f9a1c2e#2 # 交互界面:作为初始提示直接发送
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- `-p` 时原消息里的图片一并发送(写进临时目录、走 `--image` 的校验,模型不收图片时退出 2;运行后删除)。交互 / 行式界面只带文本,有图片时在 stderr 提示一行。
|
|
93
|
+
- 编号越界、格式不对 → 退出 2;会话不存在 → 退出 5。`--mode rpc` 不支持。
|
|
94
|
+
|
|
95
|
+
## 导出:`ama sessions export`
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
ama sessions export <id> [--format md|json|jsonl] [--output <文件>] [--branch leaf|all]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
| 格式 | 内容 |
|
|
102
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
103
|
+
| `md`(缺省) | 给人读:用户消息(带编号)、助手文本、工具调用(参数 JSON 截到 500 字符)与结果(截到 2000 字符)、压缩 / 分支摘要、切换模型、末尾用量表;思考与 system 不写,图片写占位 |
|
|
104
|
+
| `json` | `{ format: "ama.session-export", version: 1, session, branch, leafId, userMessages, usage, entries }`,`entries` 是原条目 |
|
|
105
|
+
| `jsonl` | 头 + 所选条目,与会话文件同形状,可以再被 ama 读回(不带 `leaf` 行) |
|
|
106
|
+
|
|
107
|
+
- `--branch leaf`(缺省)是根到当前叶子的分支(与 `/tree` 当前位置一致);`all` 是文件里全部条目。
|
|
108
|
+
- `--output` 写文件(权限 0600),否则写 stdout。
|
|
109
|
+
- **脱敏**:导出前把 key / token 形态的字符串换成 `[REDACTED]`——`sk-…`、`sk-ant-…`、`ghp_…`、`github_pat_…`、`xox?-…`、`AIza…`、`AKIA…`、`npm_…`、JWT、`Bearer` / `Basic` 凭据、PEM 私钥块,以及 `apiKey` / `secret` / `token` / `password` / `authorization` 之后紧跟 `:` 或 `=` 的值;json / jsonl 里键名像机密的字符串值整段遮掉。图片的 base64 保留。只认形态,不保证遮全,分享前仍请自己看一遍。
|
|
110
|
+
|
|
111
|
+
## 检查点与文件备份
|
|
112
|
+
|
|
113
|
+
回滚代码(`/rewind`,设计见 [rewind-plan.md](rewind-plan.md))依赖检查点:每个新回合开始时,ama 记下 edit / write 改过的文件当时的内容。
|
|
114
|
+
|
|
115
|
+
- **存储位置**:备份按内容 sha256 存在 `<数据目录>/file-history/blobs/<前 2 位>/<sha256>`,原字节、不压缩;多个会话、多个检查点共用,同内容只存一份。会话文件里只有 `ama.checkpoint` / `ama.checkpoint-track` 两类 `custom` 条目(记哈希,不进上下文)。会话目录不在缺省位置时(`--session-dir`、宿主 profile 的 `sessionDir`),目录登记在 `file-history/roots.json`,清理时一并扫描。
|
|
116
|
+
- **跟踪范围**:edit / write(含 codemode 内层调用与 task 子会话)第一次写某文件之前备份它;之后每个新回合按当前磁盘内容重拍已跟踪的文件,所以 bash 或手动对这些文件的改动也会进下一个检查点。bash 新建或改动的其它文件不跟踪。
|
|
117
|
+
- **清理**:`ama sessions prune` 结束后扫描全部会话文件(含 `.trash/` 里还能找回的)里的检查点引用,删除未被引用且超过 1 天的备份;`--dry-run` 只报告。`ama doctor` 的「目录」一节显示备份数与占用。
|
|
118
|
+
- **配置**:`checkpoints.mode`(`tools` 缺省 / `shadow-git` / `off`,环境变量 `AMA_CHECKPOINTS` 覆盖;`shadow-git` 见下)、`checkpoints.maxFileBytes`(缺省 5 MiB)、`checkpoints.keep`(缺省 100,更早的检查点不再列为回滚点)。项目级 `.ama/config.json` 只能把 `mode` 设为 `off`、把 `maxFileBytes` 调小。
|
|
119
|
+
- **限制**:
|
|
120
|
+
- 超过 `maxFileBytes` 的文件、符号链接与非普通文件不备份,回滚时报告无法恢复。
|
|
121
|
+
- 恢复时目标是符号链接、硬链接(链接数 > 1)、非普通文件,或父目录已被移动 / 换成链接,都跳过并列出原因;备份已被清理时报告 `backup_missing`。
|
|
122
|
+
- 冲突检测:文件当前内容既不是 ama 最后写入的、也不是最近检查点记录的,视为回合外的手动修改,缺省跳过。「ama 最后写入」只在进程内存里;恢复会话后以最近检查点为准,上一回合 ama 写过、之后未再建检查点的文件会被当作冲突(可选择覆盖)。
|
|
123
|
+
- git 状态不动:只记 HEAD,回滚时 HEAD 变了给出提示。
|
|
124
|
+
- 内存会话(不落盘)没有检查点。
|
|
125
|
+
|
|
126
|
+
### 影子 git 模式(`checkpoints.mode: "shadow-git"`)
|
|
127
|
+
|
|
128
|
+
`tools` 模式只看 edit / write 碰过的文件;影子 git 在此之外,每个新回合把整个工作目录快照进一个独立的 git 仓库,bash 或手动的新增、修改、删除、重命名也能回滚。
|
|
129
|
+
|
|
130
|
+
- **仓库**:`<数据目录>/file-history/shadow/<sha256(工作目录) 前 16 位>/`,以 `--git-dir` / `--work-tree` 指向工作目录,不碰你自己仓库的对象、索引、引用与 HEAD。同一工作目录的会话共用一个影子仓库(每个进程用自己的索引文件);`ama sessions prune` 不清理影子仓库,不再需要时可整个删掉对应目录(删掉后这些检查点按 `tools` 记录恢复)。`ama doctor` 在 file-history 一行里显示影子仓库个数与占用。
|
|
131
|
+
- **快照**:新回合开始时 `git add -A` + `write-tree` + `commit-tree`(父为上一个影子提交),提交 id 记进检查点的 `shadowCommit`。影子仓库用固定身份、空的全局 / 系统配置(不读你的签名、钩子、过滤器与模板),`core.autocrlf=false` 且关掉换行转换,存的是磁盘原字节;`gc.auto=0`。
|
|
132
|
+
- **忽略**:工作目录里的 `.gitignore` 生效;工作目录在 git 仓库里时,你的仓库判定为忽略的路径(上级目录的 `.gitignore`、`info/exclude`、全局忽略文件)同样不进影子仓库;`.git` 一律排除。
|
|
133
|
+
- **恢复**:把当前工作目录写成树,与目标提交比较,只处理有差异的文件;冲突与安全检查与 `tools` 相同(符号链接、硬链接、非普通文件、路径上的目录被换成链接都跳过)。「已知」的当前内容 = 最近一个影子快照里的、ama 最后写入的或最近检查点记录的,其余视为回合外的改动,缺省跳过。被忽略的文件不碰;edit / write 改过、但不在影子仓库里的文件(工作目录外、被忽略)按 `tools` 记录恢复。目标检查点没有影子提交(降级之后、或影子仓库已删)时整次按 `tools` 恢复。
|
|
134
|
+
- **护栏**:以下情况本会话降级为 `tools` 并提示一次——PATH 里找不到 `git`;工作目录(不含忽略的)超过 20 000 个文件(第一次快照前检查);单次快照超过 3 秒(这次的提交保留)。工作目录是家目录或文件系统根目录时不启用。
|
|
135
|
+
- **限制**:
|
|
136
|
+
- 最近一个回合里 bash 的改动要到下一个回合开始才进快照;在那之前回滚,这些改动与手动修改分不开,算冲突(可选择覆盖)。
|
|
137
|
+
- git 只记可执行位:恢复时只调整可执行位,其它权限位保留;符号链接与子模块不恢复。
|
|
138
|
+
- 影子仓库收录全部未忽略的文件,大文件也会存进去(不受 `maxFileBytes` 限制,恢复时超过它的报告无法恢复);没有 `.gitignore` 的大目录建议用 `tools`。
|
|
139
|
+
|
|
140
|
+
## 回滚(会话内)
|
|
141
|
+
|
|
142
|
+
`/rewind`、RPC `rewind`、SDK `session.rewind()` 回到某条用户消息之前(设计见 [rewind-plan.md](rewind-plan.md)):
|
|
143
|
+
|
|
144
|
+
- 回滚点是活动路径上开启新回合的用户消息,从旧到新;运行中插话、排队消息与 Stop Hook 续跑的消息并入当前回合,不单列。运行中回滚报 `busy`。
|
|
145
|
+
- 对话回滚复用 `/tree` 换叶子:离开的分支留在文件里,可以再从 `/tree` 回去;模型、思考级别与权限模式保持当前,不随回滚改变。之后第一次请求的 system、工具表与落点之前的消息和回滚前逐字节相同,提示缓存照常命中。
|
|
146
|
+
- 「已读」集合按新路径上成功的 read / write 调用重算,再去掉被恢复、删除或与目标检查点不一致的文件——模型要改这些文件得先重新 read。
|
|
147
|
+
- 仅对话或仅代码时,下一次提示前在末尾追加一条 `ama.rewind-note` 告诉模型哪些文件与对话不一致;对话 + 代码不追加。
|
|
148
|
+
- 内存会话与 `checkpoints.mode: "off"` 不建检查点,只能仅对话。
|
|
149
|
+
- 运行中 Esc 中断、本回合还没有任何回复或工具调用时,撤回该回合并回填原消息(`ui.restoreOnCancel`,缺省 true)。
|
|
150
|
+
|
|
151
|
+
## 请求明细(设计,未实现)
|
|
152
|
+
|
|
153
|
+
计划在会话里追加 `custom{customType:"ama.request"}`(不进上下文),每次模型请求一条:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"type": "custom",
|
|
158
|
+
"customType": "ama.request",
|
|
159
|
+
"data": {
|
|
160
|
+
"purpose": "turn",
|
|
161
|
+
"provider": "packy",
|
|
162
|
+
"model": "kimi-k2.5",
|
|
163
|
+
"channel": "messages",
|
|
164
|
+
"startedAt": "…",
|
|
165
|
+
"firstByteMs": 820,
|
|
166
|
+
"durationMs": 6400,
|
|
167
|
+
"httpStatus": 200,
|
|
168
|
+
"attempt": 1,
|
|
169
|
+
"stopReason": "toolUse"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
暂不实现的原因:HTTP 状态与首字节时间只在协议层(`src/ai/http.ts`、各 `apis/*`)可见,重试在 `agent/session-run.ts`,记录点要同时碰这几处,正与超时 / 重试反馈的改动重叠。现阶段 `ama stats` 用已有数据近似:回合耗时取落盘时间差,重试取 `context_edit{reason:"retry"}`,失败取 `stopReason: "error"`。实现时在 `StreamOptions.onResponse` 旁加一个请求结束回调,由会话层把上面的字段写成 `custom` 条目;`ama stats` 读到后按请求给出耗时分布与 HTTP 状态计数。
|