@armadra/agent 0.5.1 → 0.6.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 +177 -304
- package/CHANGELOG.zh-CN.md +442 -0
- package/README.md +408 -364
- package/README.zh-CN.md +705 -0
- package/dist/agent/session-plan.js +2 -2
- package/dist/agent/session-state.d.ts +3 -0
- package/dist/agent/session-state.js +20 -0
- package/dist/agent/session-subagent.d.ts +15 -1
- package/dist/agent/session-subagent.js +26 -3
- package/dist/agent/session-telemetry.d.ts +16 -2
- package/dist/agent/session-telemetry.js +29 -7
- package/dist/agent/session-tools.js +5 -2
- package/dist/agent/session-trace-writer.d.ts +27 -0
- package/dist/agent/session-trace-writer.js +253 -0
- package/dist/agent/session.d.ts +2 -0
- package/dist/agent/session.js +12 -0
- package/dist/agent/subagent-direct.d.ts +20 -0
- package/dist/agent/subagent-direct.js +76 -0
- package/dist/agent/subagent-registry.d.ts +8 -1
- package/dist/agent/subagent-registry.js +28 -1
- package/dist/agent/system-prompt.d.ts +3 -1
- package/dist/agent/system-prompt.js +3 -0
- package/dist/agent/tool-runner.d.ts +2 -1
- package/dist/agent/tool-runner.js +5 -4
- package/dist/agent/types-w6.d.ts +39 -0
- package/dist/agent/types-w6.js +4 -0
- package/dist/agent/types.d.ts +5 -2
- package/dist/agents/external.js +1 -1
- package/dist/agents/task-record.d.ts +74 -1
- package/dist/agents/task-record.js +100 -0
- package/dist/ai/apis/cache-params.js +2 -1
- package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
- package/dist/ai/apis/chatgpt-backend.js +224 -0
- package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
- package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
- package/dist/ai/apis/openai-responses-request.d.ts +2 -1
- package/dist/ai/apis/openai-responses-request.js +8 -2
- package/dist/ai/apis/openai-responses.d.ts +2 -0
- package/dist/ai/apis/openai-responses.js +51 -16
- package/dist/ai/overflow.d.ts +1 -1
- package/dist/ai/overflow.js +10 -7
- package/dist/ai/providers/auth.d.ts +15 -2
- package/dist/ai/providers/auth.js +69 -2
- package/dist/ai/providers/builtin.js +27 -0
- package/dist/ai/providers/catalog-data.js +1 -0
- package/dist/ai/providers/enrich.js +2 -7
- package/dist/ai/providers/models-dev-cache.js +15 -19
- package/dist/ai/providers/models-dev-snapshot.js +8 -7
- package/dist/ai/providers/models-dev.js +5 -15
- package/dist/ai/providers/suggest.js +2 -16
- package/dist/ai/types.d.ts +27 -1
- package/dist/auth/chatgpt/backend-client.d.ts +26 -0
- package/dist/auth/chatgpt/backend-client.js +74 -0
- package/dist/auth/chatgpt/claims.d.ts +17 -0
- package/dist/auth/chatgpt/claims.js +46 -0
- package/dist/auth/chatgpt/cli.d.ts +33 -0
- package/dist/auth/chatgpt/cli.js +252 -0
- package/dist/auth/chatgpt/doctor.d.ts +17 -0
- package/dist/auth/chatgpt/doctor.js +36 -0
- package/dist/auth/chatgpt/host-id.d.ts +7 -0
- package/dist/auth/chatgpt/host-id.js +26 -0
- package/dist/auth/chatgpt/login.d.ts +30 -0
- package/dist/auth/chatgpt/login.js +130 -0
- package/dist/auth/chatgpt/presets.d.ts +66 -0
- package/dist/auth/chatgpt/presets.js +120 -0
- package/dist/auth/chatgpt/quota-text.d.ts +13 -0
- package/dist/auth/chatgpt/quota-text.js +36 -0
- package/dist/auth/oauth/browser.d.ts +12 -0
- package/dist/auth/oauth/browser.js +27 -0
- package/dist/auth/oauth/callback-server.d.ts +47 -0
- package/dist/auth/oauth/callback-server.js +147 -0
- package/dist/auth/oauth/flows.d.ts +62 -0
- package/dist/auth/oauth/flows.js +113 -0
- package/dist/auth/oauth/jwt.d.ts +24 -0
- package/dist/auth/oauth/jwt.js +81 -0
- package/dist/auth/oauth/live.d.ts +21 -0
- package/dist/auth/oauth/live.js +25 -0
- package/dist/auth/oauth/oidc.d.ts +26 -0
- package/dist/auth/oauth/oidc.js +72 -0
- package/dist/auth/oauth/pkce.d.ts +15 -0
- package/dist/auth/oauth/pkce.js +20 -0
- package/dist/auth/oauth/refresh.d.ts +35 -0
- package/dist/auth/oauth/refresh.js +129 -0
- package/dist/auth/oauth/token-client.d.ts +33 -0
- package/dist/auth/oauth/token-client.js +121 -0
- package/dist/auth/oauth/token-store.d.ts +23 -0
- package/dist/auth/oauth/token-store.js +125 -0
- package/dist/auth/testing/fake-oauth.d.ts +73 -0
- package/dist/auth/testing/fake-oauth.js +271 -0
- package/dist/auth/testing/refresh-child.d.ts +5 -0
- package/dist/auth/testing/refresh-child.js +16 -0
- package/dist/bundle/ama.cjs +25928 -11144
- package/dist/checkpoints/backend.js +6 -5
- package/dist/checkpoints/restore.js +3 -2
- package/dist/checkpoints/settings.js +2 -1
- package/dist/checkpoints/shadow-git.js +7 -6
- package/dist/checkpoints/shadow-restore.js +3 -2
- package/dist/checkpoints/tracker.js +4 -3
- package/dist/cli/args.d.ts +9 -2
- package/dist/cli/args.js +74 -27
- package/dist/cli/bootstrap.js +53 -31
- package/dist/cli/choice-prompt.js +8 -6
- package/dist/cli/codemode-notice.js +2 -2
- package/dist/cli/compose-agents.js +2 -1
- package/dist/cli/compose-extensions.js +2 -0
- package/dist/cli/compose-memory.d.ts +53 -0
- package/dist/cli/compose-memory.js +127 -0
- package/dist/cli/compose-providers.d.ts +5 -0
- package/dist/cli/compose-providers.js +32 -2
- package/dist/cli/compose-session.d.ts +5 -0
- package/dist/cli/compose-session.js +27 -13
- package/dist/cli/compose-store.d.ts +2 -0
- package/dist/cli/compose-store.js +9 -5
- package/dist/cli/compose.d.ts +2 -0
- package/dist/cli/compose.js +13 -5
- package/dist/cli/default-model.d.ts +0 -2
- package/dist/cli/default-model.js +5 -8
- package/dist/cli/deps.d.ts +5 -1
- package/dist/cli/exit-codes.d.ts +1 -1
- package/dist/cli/exit-codes.js +7 -16
- package/dist/cli/from-prompt.js +3 -2
- package/dist/cli/help-text.d.ts +2 -1
- package/dist/cli/help-text.js +5 -99
- package/dist/cli/main.d.ts +5 -0
- package/dist/cli/main.js +21 -2
- package/dist/cli/proxy.js +14 -9
- package/dist/cli/runtime.d.ts +5 -0
- package/dist/cli/startup-screen.js +20 -27
- package/dist/cli/startup-steps.js +6 -8
- package/dist/cli/subcommands/auth.d.ts +6 -3
- package/dist/cli/subcommands/auth.js +52 -22
- package/dist/cli/subcommands/config-set.d.ts +21 -0
- package/dist/cli/subcommands/config-set.js +137 -0
- package/dist/cli/subcommands/config.d.ts +2 -1
- package/dist/cli/subcommands/config.js +51 -37
- package/dist/cli/subcommands/doctor.d.ts +2 -1
- package/dist/cli/subcommands/doctor.js +97 -58
- package/dist/cli/subcommands/init.d.ts +1 -1
- package/dist/cli/subcommands/init.js +8 -7
- package/dist/cli/subcommands/memory.d.ts +18 -0
- package/dist/cli/subcommands/memory.js +189 -0
- package/dist/cli/subcommands/model-meta.js +11 -9
- package/dist/cli/subcommands/models-cache-probe.js +23 -20
- package/dist/cli/subcommands/models-discover.d.ts +3 -0
- package/dist/cli/subcommands/models-discover.js +44 -21
- package/dist/cli/subcommands/models.d.ts +1 -1
- package/dist/cli/subcommands/models.js +29 -22
- package/dist/cli/subcommands/probe-runner.js +8 -7
- package/dist/cli/subcommands/providers-list.js +32 -21
- package/dist/cli/subcommands/providers-plan.js +24 -25
- package/dist/cli/subcommands/providers-probe.js +5 -6
- package/dist/cli/subcommands/providers.d.ts +1 -1
- package/dist/cli/subcommands/providers.js +45 -50
- package/dist/cli/subcommands/sessions-export.d.ts +1 -1
- package/dist/cli/subcommands/sessions-export.js +10 -9
- package/dist/cli/subcommands/sessions-search.d.ts +1 -1
- package/dist/cli/subcommands/sessions-search.js +11 -10
- package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
- package/dist/cli/subcommands/sessions-trace.js +156 -0
- package/dist/cli/subcommands/sessions.d.ts +4 -3
- package/dist/cli/subcommands/sessions.js +40 -37
- package/dist/cli/subcommands/stats.d.ts +1 -1
- package/dist/cli/subcommands/stats.js +49 -30
- package/dist/cli/system-prompt-arg.js +3 -2
- package/dist/codemode/capability.js +3 -2
- package/dist/compaction/post-compact.d.ts +1 -0
- package/dist/compaction/post-compact.js +15 -1
- package/dist/compaction/prune-tier.d.ts +1 -1
- package/dist/compaction/prune-tier.js +3 -3
- package/dist/compaction/serialize.js +2 -1
- package/dist/config/auth-file.d.ts +12 -2
- package/dist/config/auth-file.js +32 -10
- package/dist/config/checker.js +12 -11
- package/dist/config/context-files.js +3 -2
- package/dist/config/edit.d.ts +106 -0
- package/dist/config/edit.js +350 -0
- package/dist/config/init.d.ts +4 -3
- package/dist/config/init.js +10 -18
- package/dist/config/json-schema.d.ts +2 -1
- package/dist/config/json-schema.js +101 -68
- package/dist/config/key-docs.d.ts +18 -7
- package/dist/config/key-docs.js +43 -128
- package/dist/config/load.js +7 -6
- package/dist/config/merge.d.ts +4 -1
- package/dist/config/merge.js +42 -22
- package/dist/config/paths.js +6 -5
- package/dist/config/profile.d.ts +5 -1
- package/dist/config/profile.js +7 -2
- package/dist/config/schema-w5.js +3 -2
- package/dist/config/schema-w6.d.ts +19 -0
- package/dist/config/schema-w6.js +115 -0
- package/dist/config/schema.js +34 -20
- package/dist/config/settings-registry.d.ts +78 -0
- package/dist/config/settings-registry.js +184 -0
- package/dist/config/types-w6.d.ts +109 -0
- package/dist/config/types-w6.js +19 -0
- package/dist/config/types.d.ts +11 -8
- package/dist/config/types.js +1 -0
- package/dist/drivers/acp/client.js +1 -1
- package/dist/drivers/acp/driver.js +13 -8
- package/dist/drivers/agents.js +4 -3
- package/dist/drivers/base.js +3 -2
- package/dist/drivers/host-runners.js +2 -1
- package/dist/drivers/native/claude-stream.js +12 -11
- package/dist/drivers/native/codex-app-server.js +17 -12
- package/dist/drivers/native/oneshot.js +8 -7
- package/dist/drivers/pool.js +1 -1
- package/dist/drivers/runner.d.ts +3 -1
- package/dist/drivers/runner.js +68 -20
- package/dist/drivers/turn.js +1 -1
- package/dist/hooks/config.js +3 -2
- package/dist/hooks/protocol.js +18 -12
- package/dist/host/api-impl.js +11 -10
- package/dist/host/loader.js +9 -8
- package/dist/host/types.d.ts +3 -0
- package/dist/i18n/catalog.d.ts +2169 -0
- package/dist/i18n/catalog.js +72 -0
- package/dist/i18n/format.d.ts +21 -0
- package/dist/i18n/format.js +58 -0
- package/dist/i18n/index.d.ts +58 -0
- package/dist/i18n/index.js +72 -0
- package/dist/i18n/messages/agents.d.ts +84 -0
- package/dist/i18n/messages/agents.js +85 -0
- package/dist/i18n/messages/approval.d.ts +99 -0
- package/dist/i18n/messages/approval.js +100 -0
- package/dist/i18n/messages/auth.d.ts +187 -0
- package/dist/i18n/messages/auth.js +189 -0
- package/dist/i18n/messages/cli-args.d.ts +46 -0
- package/dist/i18n/messages/cli-args.js +46 -0
- package/dist/i18n/messages/cli-help.d.ts +12 -0
- package/dist/i18n/messages/cli-help.js +244 -0
- package/dist/i18n/messages/cli.d.ts +336 -0
- package/dist/i18n/messages/cli.js +311 -0
- package/dist/i18n/messages/config-keys.d.ts +289 -0
- package/dist/i18n/messages/config-keys.js +292 -0
- package/dist/i18n/messages/config.d.ts +502 -0
- package/dist/i18n/messages/config.js +239 -0
- package/dist/i18n/messages/drivers.d.ts +123 -0
- package/dist/i18n/messages/drivers.js +124 -0
- package/dist/i18n/messages/errors.d.ts +83 -0
- package/dist/i18n/messages/errors.js +171 -0
- package/dist/i18n/messages/interactive-line.d.ts +61 -0
- package/dist/i18n/messages/interactive-line.js +69 -0
- package/dist/i18n/messages/interactive-startup.d.ts +103 -0
- package/dist/i18n/messages/interactive-startup.js +104 -0
- package/dist/i18n/messages/interactive-view.d.ts +140 -0
- package/dist/i18n/messages/interactive-view.js +141 -0
- package/dist/i18n/messages/interactive.d.ts +493 -0
- package/dist/i18n/messages/interactive.js +248 -0
- package/dist/i18n/messages/memory.d.ts +123 -0
- package/dist/i18n/messages/memory.js +128 -0
- package/dist/i18n/messages/panels.d.ts +190 -0
- package/dist/i18n/messages/panels.js +189 -0
- package/dist/i18n/messages/permissions.d.ts +126 -0
- package/dist/i18n/messages/permissions.js +151 -0
- package/dist/i18n/messages/plan.d.ts +123 -0
- package/dist/i18n/messages/plan.js +124 -0
- package/dist/i18n/messages/print.d.ts +86 -0
- package/dist/i18n/messages/print.js +91 -0
- package/dist/i18n/messages/report.d.ts +391 -0
- package/dist/i18n/messages/report.js +490 -0
- package/dist/i18n/messages/rewind.d.ts +198 -0
- package/dist/i18n/messages/rewind.js +217 -0
- package/dist/i18n/messages/session.d.ts +230 -0
- package/dist/i18n/messages/session.js +258 -0
- package/dist/i18n/messages/settings.d.ts +348 -0
- package/dist/i18n/messages/settings.js +336 -0
- package/dist/i18n/messages/subcommands-config.d.ts +111 -0
- package/dist/i18n/messages/subcommands-config.js +127 -0
- package/dist/i18n/messages/subcommands.d.ts +548 -0
- package/dist/i18n/messages/subcommands.js +474 -0
- package/dist/i18n/messages/trace.d.ts +243 -0
- package/dist/i18n/messages/trace.js +238 -0
- package/dist/i18n/types.d.ts +15 -0
- package/dist/i18n/types.js +7 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/dist/memory/edit.d.ts +24 -0
- package/dist/memory/edit.js +63 -0
- package/dist/memory/frontmatter.d.ts +37 -0
- package/dist/memory/frontmatter.js +79 -0
- package/dist/memory/index.d.ts +28 -0
- package/dist/memory/index.js +126 -0
- package/dist/memory/lock.d.ts +17 -0
- package/dist/memory/lock.js +62 -0
- package/dist/memory/paths.d.ts +57 -0
- package/dist/memory/paths.js +175 -0
- package/dist/memory/report.d.ts +36 -0
- package/dist/memory/report.js +86 -0
- package/dist/memory/runtime.d.ts +42 -0
- package/dist/memory/runtime.js +36 -0
- package/dist/memory/secrets.d.ts +8 -0
- package/dist/memory/secrets.js +27 -0
- package/dist/memory/section.d.ts +28 -0
- package/dist/memory/section.js +59 -0
- package/dist/memory/store.d.ts +70 -0
- package/dist/memory/store.js +284 -0
- package/dist/memory/tool.d.ts +31 -0
- package/dist/memory/tool.js +94 -0
- package/dist/modes/acp/acp-events.js +2 -1
- package/dist/modes/acp/acp-server.js +13 -12
- package/dist/modes/commands-core.d.ts +11 -0
- package/dist/modes/commands-core.js +93 -62
- package/dist/modes/image-input.js +20 -6
- package/dist/modes/interactive/agent-bar.d.ts +95 -0
- package/dist/modes/interactive/agent-bar.js +248 -0
- package/dist/modes/interactive/agent-panels.js +27 -26
- package/dist/modes/interactive/agent-transcript.d.ts +47 -0
- package/dist/modes/interactive/agent-transcript.js +191 -0
- package/dist/modes/interactive/agent-ui.d.ts +36 -1
- package/dist/modes/interactive/agent-ui.js +180 -14
- package/dist/modes/interactive/agent-view.d.ts +72 -0
- package/dist/modes/interactive/agent-view.js +281 -0
- package/dist/modes/interactive/approval-dialog.js +46 -34
- package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
- package/dist/modes/interactive/clipboard-paste.js +9 -4
- package/dist/modes/interactive/commands.d.ts +19 -1
- package/dist/modes/interactive/commands.js +84 -40
- package/dist/modes/interactive/completion.js +2 -1
- package/dist/modes/interactive/config-panel.d.ts +70 -0
- package/dist/modes/interactive/config-panel.js +319 -0
- package/dist/modes/interactive/config-ui.d.ts +96 -0
- package/dist/modes/interactive/config-ui.js +397 -0
- package/dist/modes/interactive/confirm-dialog.js +6 -7
- package/dist/modes/interactive/event-notices.js +11 -9
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.js +19 -22
- package/dist/modes/interactive/key-dispatch.d.ts +12 -0
- package/dist/modes/interactive/key-dispatch.js +24 -9
- package/dist/modes/interactive/line/line-editor.js +2 -1
- package/dist/modes/interactive/line/line-mode.js +18 -7
- package/dist/modes/interactive/line/line-render.js +25 -24
- package/dist/modes/interactive/memory-panel.d.ts +64 -0
- package/dist/modes/interactive/memory-panel.js +221 -0
- package/dist/modes/interactive/message-view.d.ts +4 -2
- package/dist/modes/interactive/message-view.js +42 -33
- package/dist/modes/interactive/panels.js +39 -31
- package/dist/modes/interactive/pickers.d.ts +2 -1
- package/dist/modes/interactive/pickers.js +10 -6
- package/dist/modes/interactive/plan-command.d.ts +1 -1
- package/dist/modes/interactive/plan-command.js +24 -27
- package/dist/modes/interactive/plan-dialog.js +18 -17
- package/dist/modes/interactive/plan-flow.js +6 -5
- package/dist/modes/interactive/rewind-command.d.ts +1 -1
- package/dist/modes/interactive/rewind-command.js +18 -16
- package/dist/modes/interactive/rewind-flow.d.ts +0 -1
- package/dist/modes/interactive/rewind-flow.js +13 -14
- package/dist/modes/interactive/rewind-list.js +7 -6
- package/dist/modes/interactive/rewind-panel.js +40 -40
- package/dist/modes/interactive/rewind-text.d.ts +5 -3
- package/dist/modes/interactive/rewind-text.js +48 -38
- package/dist/modes/interactive/run-indicator.js +15 -12
- package/dist/modes/interactive/session-events.js +3 -2
- package/dist/modes/interactive/startup-header.js +22 -23
- package/dist/modes/interactive/startup-ui.js +38 -30
- package/dist/modes/interactive/status-area.d.ts +2 -0
- package/dist/modes/interactive/status-area.js +8 -2
- package/dist/modes/interactive/status-bar.js +4 -3
- package/dist/modes/interactive/subagent-view.js +9 -7
- package/dist/modes/interactive/tasks-report.d.ts +6 -0
- package/dist/modes/interactive/tasks-report.js +28 -31
- package/dist/modes/interactive/terminal-setup.d.ts +9 -0
- package/dist/modes/interactive/terminal-setup.js +23 -0
- package/dist/modes/interactive/tool-summary.js +19 -17
- package/dist/modes/interactive/tool-view.js +7 -4
- package/dist/modes/interactive/trace-view.d.ts +89 -0
- package/dist/modes/interactive/trace-view.js +332 -0
- package/dist/modes/print/print-mode.js +14 -15
- package/dist/modes/rpc/commands.js +7 -3
- package/dist/modes/rpc/rpc-mode.js +9 -3
- package/dist/modes/session-report.d.ts +2 -0
- package/dist/modes/session-report.js +101 -105
- package/dist/modes/startup-ui-text.js +11 -6
- package/dist/permissions/bypass.d.ts +8 -10
- package/dist/permissions/bypass.js +19 -10
- package/dist/permissions/memory-class.d.ts +23 -0
- package/dist/permissions/memory-class.js +54 -0
- package/dist/permissions/modes.d.ts +3 -3
- package/dist/permissions/modes.js +21 -16
- package/dist/permissions/pipeline.d.ts +1 -1
- package/dist/permissions/pipeline.js +9 -2
- package/dist/permissions/preview.js +49 -42
- package/dist/permissions/rules.js +5 -2
- package/dist/permissions/types.d.ts +4 -0
- package/dist/plan/store.js +2 -1
- package/dist/rpc.d.ts +39 -1
- package/dist/rpc.js +3 -0
- package/dist/sandbox/bash.js +11 -8
- package/dist/sandbox/detect.js +14 -11
- package/dist/sdk.d.ts +17 -1
- package/dist/sdk.js +29 -7
- package/dist/session/export.js +31 -30
- package/dist/session/manager.d.ts +1 -1
- package/dist/session/manager.js +5 -3
- package/dist/session/reuse.js +5 -4
- package/dist/session/scan.js +3 -2
- package/dist/session/stats-aggregate.d.ts +3 -1
- package/dist/session/stats-aggregate.js +5 -1
- package/dist/session/stats-index.js +2 -1
- package/dist/session/stats-scan.d.ts +4 -1
- package/dist/session/stats-scan.js +6 -2
- package/dist/session/store.d.ts +11 -0
- package/dist/session/store.js +48 -1
- package/dist/session/types.d.ts +2 -0
- package/dist/skills/builtin.js +2 -1
- package/dist/tools/image-file.d.ts +26 -1
- package/dist/tools/image-file.js +55 -13
- package/dist/tools/presets.d.ts +14 -1
- package/dist/tools/presets.js +3 -3
- package/dist/tools/registry.js +1 -1
- package/dist/tools/truncate.d.ts +1 -1
- package/dist/tools/truncate.js +2 -2
- package/dist/tools/types.d.ts +17 -1
- package/dist/trace/build-index.d.ts +91 -0
- package/dist/trace/build-index.js +127 -0
- package/dist/trace/build-nodes.d.ts +24 -0
- package/dist/trace/build-nodes.js +279 -0
- package/dist/trace/build-util.d.ts +43 -0
- package/dist/trace/build-util.js +120 -0
- package/dist/trace/build.d.ts +82 -0
- package/dist/trace/build.js +382 -0
- package/dist/trace/detail.d.ts +35 -0
- package/dist/trace/detail.js +205 -0
- package/dist/trace/flatten.d.ts +69 -0
- package/dist/trace/flatten.js +173 -0
- package/dist/trace/format.d.ts +47 -0
- package/dist/trace/format.js +329 -0
- package/dist/trace/html-template.d.ts +19 -0
- package/dist/trace/html-template.js +150 -0
- package/dist/trace/html.d.ts +104 -0
- package/dist/trace/html.js +292 -0
- package/dist/trace/preview.d.ts +29 -0
- package/dist/trace/preview.js +59 -0
- package/dist/trace/query-session.d.ts +14 -0
- package/dist/trace/query-session.js +38 -0
- package/dist/trace/query.d.ts +55 -0
- package/dist/trace/query.js +188 -0
- package/dist/trace/session.d.ts +40 -0
- package/dist/trace/session.js +168 -0
- package/dist/trace/types.d.ts +243 -0
- package/dist/trace/types.js +13 -0
- package/dist/tui/components/editor-paste.d.ts +2 -0
- package/dist/tui/components/editor-paste.js +6 -3
- package/dist/tui/components/editor.js +2 -2
- package/dist/tui/components/loader.d.ts +3 -0
- package/dist/tui/components/loader.js +14 -0
- package/dist/tui/components/settings-list.d.ts +61 -0
- package/dist/tui/components/settings-list.js +135 -0
- package/dist/tui/keybindings.d.ts +5 -0
- package/dist/tui/keybindings.js +17 -5
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +2 -0
- package/docs/en/host-api.md +167 -0
- package/docs/en/permissions.md +214 -0
- package/docs/en/providers.md +625 -0
- package/docs/en/rpc.md +361 -0
- package/docs/en/sessions.md +219 -0
- package/docs/en/tui.md +527 -0
- package/docs/host-api.md +18 -17
- package/docs/memory.md +172 -0
- package/docs/permissions.md +2 -2
- package/docs/providers.md +67 -1
- package/docs/rpc.md +31 -3
- package/docs/session-format.md +8 -2
- package/docs/sessions.md +29 -1
- package/docs/tui.md +132 -3
- package/package.json +8 -3
package/dist/config/checker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 配置校验的诊断收集器(从 schema.ts 抽出,schema-w5.ts 共用)。[W5-C0]
|
|
3
3
|
*/
|
|
4
|
+
import { msg } from "../i18n/index.js";
|
|
4
5
|
export const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"];
|
|
5
6
|
export class Checker {
|
|
6
7
|
diagnostics = [];
|
|
@@ -13,44 +14,44 @@ export class Checker {
|
|
|
13
14
|
object(value, path) {
|
|
14
15
|
if (typeof value === "object" && value !== null && !Array.isArray(value))
|
|
15
16
|
return true;
|
|
16
|
-
this.error(path,
|
|
17
|
+
this.error(path, msg().config.schema.object);
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
19
20
|
/** 未知字段只警告(前向兼容)。 */
|
|
20
21
|
keys(value, path, allowed) {
|
|
21
22
|
for (const key of Object.keys(value)) {
|
|
22
23
|
if (!allowed.includes(key))
|
|
23
|
-
this.warn(join(path, key),
|
|
24
|
+
this.warn(join(path, key), msg().config.schema.unknownKey);
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
version(value, path) {
|
|
27
28
|
if (value["version"] !== 1)
|
|
28
|
-
this.error(join(path, "version"),
|
|
29
|
+
this.error(join(path, "version"), msg().config.schema.version);
|
|
29
30
|
}
|
|
30
31
|
string(value, key, path, required = false) {
|
|
31
32
|
const v = value[key];
|
|
32
33
|
if (v === undefined) {
|
|
33
34
|
if (required)
|
|
34
|
-
this.error(join(path, key),
|
|
35
|
+
this.error(join(path, key), msg().config.schema.requiredString);
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
38
|
if (typeof v !== "string")
|
|
38
|
-
this.error(join(path, key),
|
|
39
|
+
this.error(join(path, key), msg().config.schema.string);
|
|
39
40
|
}
|
|
40
41
|
boolean(value, key, path) {
|
|
41
42
|
const v = value[key];
|
|
42
43
|
if (v !== undefined && typeof v !== "boolean")
|
|
43
|
-
this.error(join(path, key),
|
|
44
|
+
this.error(join(path, key), msg().config.schema.boolean);
|
|
44
45
|
}
|
|
45
46
|
number(value, key, path, min = 0, max = Number.MAX_SAFE_INTEGER) {
|
|
46
47
|
const v = value[key];
|
|
47
48
|
if (v === undefined)
|
|
48
49
|
return;
|
|
49
50
|
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
50
|
-
this.error(join(path, key),
|
|
51
|
+
this.error(join(path, key), msg().config.schema.number);
|
|
51
52
|
}
|
|
52
53
|
else if (v < min || v > max) {
|
|
53
|
-
this.error(join(path, key),
|
|
54
|
+
this.error(join(path, key), msg().config.schema.range(min, max));
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
oneOf(value, key, path, choices) {
|
|
@@ -58,7 +59,7 @@ export class Checker {
|
|
|
58
59
|
if (v === undefined)
|
|
59
60
|
return;
|
|
60
61
|
if (typeof v !== "string" || !choices.includes(v)) {
|
|
61
|
-
this.error(join(path, key),
|
|
62
|
+
this.error(join(path, key), msg().config.schema.oneOf(choices));
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
stringArray(value, key, path) {
|
|
@@ -66,7 +67,7 @@ export class Checker {
|
|
|
66
67
|
if (v === undefined)
|
|
67
68
|
return;
|
|
68
69
|
if (!Array.isArray(v) || v.some((item) => typeof item !== "string")) {
|
|
69
|
-
this.error(join(path, key),
|
|
70
|
+
this.error(join(path, key), msg().config.schema.stringArray);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
stringRecord(value, key, path) {
|
|
@@ -77,7 +78,7 @@ export class Checker {
|
|
|
77
78
|
return;
|
|
78
79
|
for (const [k, item] of Object.entries(v)) {
|
|
79
80
|
if (typeof item !== "string")
|
|
80
|
-
this.error(join(join(path, key), k),
|
|
81
|
+
this.error(join(join(path, key), k), msg().config.schema.string);
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { readFileSync, realpathSync, statSync } from "node:fs";
|
|
12
12
|
import { join } from "node:path";
|
|
13
|
+
import { msg } from "../i18n/index.js";
|
|
13
14
|
import { ancestorsOf } from "./trust.js";
|
|
14
15
|
export const CONTEXT_FILE_NAMES = ["AGENTS.override.md", "AGENTS.md", "AGENTS.MD"];
|
|
15
16
|
function isFile(path) {
|
|
@@ -51,12 +52,12 @@ export function findContextFiles(input) {
|
|
|
51
52
|
content = readFileSync(path, "utf8");
|
|
52
53
|
}
|
|
53
54
|
catch (error) {
|
|
54
|
-
warnings.push(
|
|
55
|
+
warnings.push(msg().config.context.readFailed(path, error.message));
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
58
|
if (Buffer.byteLength(content) > maxBytes) {
|
|
58
59
|
content = Buffer.from(content).subarray(0, maxBytes).toString("utf8");
|
|
59
|
-
warnings.push(
|
|
60
|
+
warnings.push(msg().config.context.truncated(path, maxBytes));
|
|
60
61
|
}
|
|
61
62
|
if (seenContent.has(content))
|
|
62
63
|
return;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings edit core (docs/wave6-plan.md §6.2, D24-D26). [W6-S]
|
|
3
|
+
*
|
|
4
|
+
* Shared by the `/config` panel, `/config key=value` and `ama config get | set | unset | list`:
|
|
5
|
+
* - `readSnapshot()` reads the user and project files fresh and merges them with the profile / command
|
|
6
|
+
* line layers the same way bootstrap does (default <- user <- profile <- project, tighten only <- cli);
|
|
7
|
+
* - `getConfigValue()` gives the effective value of a key and which layer it came from (env vars that
|
|
8
|
+
* override a key count as a layer `env`);
|
|
9
|
+
* - `setConfigValue()` / `unsetConfigValue()` re-read the target file right before writing, change one
|
|
10
|
+
* path, run `validateConfig`, check project writes with `restrictProjectConfig` (anything that would be
|
|
11
|
+
* ignored there -- a loosening or a user-only key -- is refused), then write atomically with `.bak`
|
|
12
|
+
* (`writeConfigFile`). Refusals leave the file byte-for-byte untouched.
|
|
13
|
+
* There is no file lock: a concurrent `ama config edit` between our read and write is lost (R12).
|
|
14
|
+
*/
|
|
15
|
+
import { AmaError } from "../errors.js";
|
|
16
|
+
import { type CliConfigOverrides, type ConfigLayerName } from "./merge.js";
|
|
17
|
+
import { type SettingApply } from "./settings-registry.js";
|
|
18
|
+
import { type AmaConfig } from "./types.js";
|
|
19
|
+
export type SettingSource = ConfigLayerName | "env";
|
|
20
|
+
export type EditScope = "user" | "project";
|
|
21
|
+
export type ConfigEditCode = "config_unknown_key" | "config_invalid_value" | "config_project_denied" | "config_locked" | "config_read_failed" | "config_write_failed";
|
|
22
|
+
/** Refused edit; `exitCode` 3 (`ExitCode.Config`) except write failures (1). */
|
|
23
|
+
export declare class ConfigEditError extends AmaError {
|
|
24
|
+
readonly code: ConfigEditCode;
|
|
25
|
+
constructor(code: ConfigEditCode, message: string);
|
|
26
|
+
}
|
|
27
|
+
type Env = Readonly<Record<string, string | undefined>>;
|
|
28
|
+
type Obj = Record<string, unknown>;
|
|
29
|
+
export interface ConfigLayerInput {
|
|
30
|
+
/** User config directory (`AMA_CONFIG_DIR` / XDG). */
|
|
31
|
+
configDir: string;
|
|
32
|
+
/** Project root (`.ama/config.json` lives here). */
|
|
33
|
+
cwd: string;
|
|
34
|
+
env: Env;
|
|
35
|
+
/** Embedded host profile: its `config` layer (PROFILE_DEFAULTS are added when `hasProfile`). */
|
|
36
|
+
profile?: {
|
|
37
|
+
config?: AmaConfig | undefined;
|
|
38
|
+
} | undefined;
|
|
39
|
+
hasProfile?: boolean;
|
|
40
|
+
/** Command line overrides of this process. */
|
|
41
|
+
cli?: CliConfigOverrides | undefined;
|
|
42
|
+
}
|
|
43
|
+
export interface ConfigSnapshot {
|
|
44
|
+
input: ConfigLayerInput;
|
|
45
|
+
userPath: string;
|
|
46
|
+
projectPath: string;
|
|
47
|
+
user: AmaConfig | undefined;
|
|
48
|
+
project: AmaConfig | undefined;
|
|
49
|
+
/** default <- user <- profile (the baseline project-level tightening is measured against). */
|
|
50
|
+
base: AmaConfig;
|
|
51
|
+
/** Effective config (what bootstrap would build now). */
|
|
52
|
+
config: AmaConfig;
|
|
53
|
+
/** Each layer as it contributes (project = accepted part only), lowest first. */
|
|
54
|
+
layers: readonly {
|
|
55
|
+
name: ConfigLayerName;
|
|
56
|
+
value: unknown;
|
|
57
|
+
}[];
|
|
58
|
+
}
|
|
59
|
+
export interface SettingValue {
|
|
60
|
+
key: string;
|
|
61
|
+
/** Effective value (built-in default when no layer sets it; undefined = unset / decided at run time). */
|
|
62
|
+
value: unknown;
|
|
63
|
+
source: SettingSource;
|
|
64
|
+
/** Env var that overrides it (when source is `env`). */
|
|
65
|
+
envName?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface EditResult {
|
|
68
|
+
key: string;
|
|
69
|
+
scope: EditScope;
|
|
70
|
+
path: string;
|
|
71
|
+
before: SettingValue;
|
|
72
|
+
after: SettingValue;
|
|
73
|
+
apply: SettingApply | undefined;
|
|
74
|
+
/** The key changes the cache prefix and its effective value changed. */
|
|
75
|
+
prefixChanged: boolean;
|
|
76
|
+
/** The written value is still hidden by a higher layer. */
|
|
77
|
+
overriddenBy: SettingSource | undefined;
|
|
78
|
+
snapshot: ConfigSnapshot;
|
|
79
|
+
}
|
|
80
|
+
export declare function getPath(value: unknown, key: string): unknown;
|
|
81
|
+
/** Set (or with `undefined` delete) one dotted path; empty parent objects are removed. */
|
|
82
|
+
export declare function setPath(target: Obj, key: string, value: unknown): void;
|
|
83
|
+
/** Read both files and merge all layers. */
|
|
84
|
+
export declare function readSnapshot(input: ConfigLayerInput): ConfigSnapshot;
|
|
85
|
+
/** Effective value and source of one key. */
|
|
86
|
+
export declare function getConfigValue(snapshot: ConfigSnapshot, key: string): SettingValue;
|
|
87
|
+
export declare function overriddenFor(value: SettingValue, scope: EditScope): SettingSource | undefined;
|
|
88
|
+
/** Throws `config_unknown_key` unless `ama config set` accepts the key. */
|
|
89
|
+
export declare function assertSettable(key: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Parse a command line / panel value. `undefined` means unset (`none`, `unset`; `default` too unless it
|
|
92
|
+
* is a valid enum value). `jsonValue` takes JSON (lists and objects need it).
|
|
93
|
+
*/
|
|
94
|
+
export declare function parseValue(key: string, raw: string, jsonValue?: boolean): unknown;
|
|
95
|
+
export interface SetOptions extends ConfigLayerInput {
|
|
96
|
+
scope: EditScope;
|
|
97
|
+
key: string;
|
|
98
|
+
/** Parsed value; `undefined` unsets. */
|
|
99
|
+
value: unknown;
|
|
100
|
+
}
|
|
101
|
+
/** Write one key into the user or project file (or unset it with `value: undefined`). */
|
|
102
|
+
export declare function setConfigValue(options: SetOptions): EditResult;
|
|
103
|
+
export declare function unsetConfigValue(options: Omit<SetOptions, "value">): EditResult;
|
|
104
|
+
/** Display text of a value (JSON for lists / objects, plain otherwise). */
|
|
105
|
+
export declare function formatSettingValue(value: unknown): string;
|
|
106
|
+
export {};
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings edit core (docs/wave6-plan.md §6.2, D24-D26). [W6-S]
|
|
3
|
+
*
|
|
4
|
+
* Shared by the `/config` panel, `/config key=value` and `ama config get | set | unset | list`:
|
|
5
|
+
* - `readSnapshot()` reads the user and project files fresh and merges them with the profile / command
|
|
6
|
+
* line layers the same way bootstrap does (default <- user <- profile <- project, tighten only <- cli);
|
|
7
|
+
* - `getConfigValue()` gives the effective value of a key and which layer it came from (env vars that
|
|
8
|
+
* override a key count as a layer `env`);
|
|
9
|
+
* - `setConfigValue()` / `unsetConfigValue()` re-read the target file right before writing, change one
|
|
10
|
+
* path, run `validateConfig`, check project writes with `restrictProjectConfig` (anything that would be
|
|
11
|
+
* ignored there -- a loosening or a user-only key -- is refused), then write atomically with `.bak`
|
|
12
|
+
* (`writeConfigFile`). Refusals leave the file byte-for-byte untouched.
|
|
13
|
+
* There is no file lock: a concurrent `ama config edit` between our read and write is lost (R12).
|
|
14
|
+
*/
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
16
|
+
import { AmaError } from "../errors.js";
|
|
17
|
+
import { msg } from "../i18n/index.js";
|
|
18
|
+
import { minimalConfig } from "./init.js";
|
|
19
|
+
import { DISPLAY_DEFAULTS } from "./key-docs.js";
|
|
20
|
+
import { loadConfigFile, parseJsonText } from "./load.js";
|
|
21
|
+
import { PROFILE_DEFAULTS, cliOverridesToConfig, mergeBaseLayers, mergeProjectAndCli, restrictProjectConfig, } from "./merge.js";
|
|
22
|
+
import { CONFIG_FILE, projectFile, userFile } from "./paths.js";
|
|
23
|
+
import { hasErrors, validateConfig } from "./schema.js";
|
|
24
|
+
import { schemaAt, settableKeys, settingDefault, settingSpec, } from "./settings-registry.js";
|
|
25
|
+
import { CONFIG_FILE_VERSION, DEFAULT_CHECKPOINTS_CONFIG } from "./types.js";
|
|
26
|
+
import { writeConfigFile } from "./write.js";
|
|
27
|
+
/** Refused edit; `exitCode` 3 (`ExitCode.Config`) except write failures (1). */
|
|
28
|
+
export class ConfigEditError extends AmaError {
|
|
29
|
+
constructor(code, message) {
|
|
30
|
+
super(code, message, { exitCode: code === "config_write_failed" ? 1 : 3 });
|
|
31
|
+
this.name = "ConfigEditError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isObject(value) {
|
|
35
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36
|
+
}
|
|
37
|
+
export function getPath(value, key) {
|
|
38
|
+
let node = value;
|
|
39
|
+
for (const part of key.split(".")) {
|
|
40
|
+
if (!isObject(node))
|
|
41
|
+
return undefined;
|
|
42
|
+
node = node[part];
|
|
43
|
+
}
|
|
44
|
+
return node;
|
|
45
|
+
}
|
|
46
|
+
/** Set (or with `undefined` delete) one dotted path; empty parent objects are removed. */
|
|
47
|
+
export function setPath(target, key, value) {
|
|
48
|
+
const parts = key.split(".");
|
|
49
|
+
const chain = [target];
|
|
50
|
+
let node = target;
|
|
51
|
+
for (const part of parts.slice(0, -1)) {
|
|
52
|
+
const next = node[part];
|
|
53
|
+
if (!isObject(next)) {
|
|
54
|
+
if (value === undefined)
|
|
55
|
+
return;
|
|
56
|
+
node[part] = {};
|
|
57
|
+
}
|
|
58
|
+
node = node[part];
|
|
59
|
+
chain.push(node);
|
|
60
|
+
}
|
|
61
|
+
const leaf = parts.at(-1);
|
|
62
|
+
if (value !== undefined) {
|
|
63
|
+
node[leaf] = value;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
delete node[leaf];
|
|
67
|
+
for (let i = chain.length - 1; i > 0; i--) {
|
|
68
|
+
if (Object.keys(chain[i]).length > 0)
|
|
69
|
+
break;
|
|
70
|
+
delete chain[i - 1][parts[i - 1]];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
74
|
+
function loadLayerFile(path) {
|
|
75
|
+
try {
|
|
76
|
+
return loadConfigFile("config", path)?.value;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new ConfigEditError("config_read_failed", msg().settings.errors.readFailed(errorText(error)));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function errorText(error) {
|
|
83
|
+
return error instanceof Error ? error.message : String(error);
|
|
84
|
+
}
|
|
85
|
+
/** Read both files and merge all layers. */
|
|
86
|
+
export function readSnapshot(input) {
|
|
87
|
+
const userPath = userFile({ configDir: input.configDir }, CONFIG_FILE);
|
|
88
|
+
const projectPath = projectFile(input.cwd, CONFIG_FILE);
|
|
89
|
+
const user = loadLayerFile(userPath);
|
|
90
|
+
const project = loadLayerFile(projectPath);
|
|
91
|
+
const hasProfile = input.hasProfile ?? input.profile !== undefined;
|
|
92
|
+
const base = mergeBaseLayers({ user, profile: input.profile?.config, hasProfile });
|
|
93
|
+
const merged = mergeProjectAndCli(base, project, input.cli);
|
|
94
|
+
const layers = [
|
|
95
|
+
{ name: "default", value: DISPLAY_DEFAULTS },
|
|
96
|
+
];
|
|
97
|
+
if (user !== undefined)
|
|
98
|
+
layers.push({ name: "user", value: user });
|
|
99
|
+
if (hasProfile)
|
|
100
|
+
layers.push({ name: "profile", value: PROFILE_DEFAULTS });
|
|
101
|
+
if (input.profile?.config !== undefined)
|
|
102
|
+
layers.push({ name: "profile", value: input.profile.config });
|
|
103
|
+
if (project !== undefined)
|
|
104
|
+
layers.push({ name: "project", value: restrictAgainst(project, base.config) });
|
|
105
|
+
if (input.cli !== undefined)
|
|
106
|
+
layers.push({ name: "cli", value: cliOverridesToConfig(input.cli) });
|
|
107
|
+
return {
|
|
108
|
+
input,
|
|
109
|
+
userPath,
|
|
110
|
+
projectPath,
|
|
111
|
+
user,
|
|
112
|
+
project,
|
|
113
|
+
base: base.config,
|
|
114
|
+
config: merged.config,
|
|
115
|
+
layers,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function restrictAgainst(project, base) {
|
|
119
|
+
return restrictProjectConfig(project, base.permission?.mode ?? "default", ".ama/config.json", base.tools?.preset ?? "default", base.checkpoints?.maxFileBytes ?? DEFAULT_CHECKPOINTS_CONFIG.maxFileBytes, base.plan?.bash ?? "readonly").accepted;
|
|
120
|
+
}
|
|
121
|
+
/** Effective value and source of one key. */
|
|
122
|
+
export function getConfigValue(snapshot, key) {
|
|
123
|
+
const envName = settingSpec(key)?.envOverride;
|
|
124
|
+
const envValue = envName === undefined ? undefined : snapshot.input.env[envName]?.trim();
|
|
125
|
+
if (envName !== undefined && envValue !== undefined && envValue !== "")
|
|
126
|
+
return { key, value: envValue, source: "env", envName };
|
|
127
|
+
let source = "default";
|
|
128
|
+
for (const layer of snapshot.layers) {
|
|
129
|
+
if (getPath(layer.value, key) !== undefined)
|
|
130
|
+
source = layer.name;
|
|
131
|
+
}
|
|
132
|
+
const value = getPath(snapshot.config, key) ?? settingDefault(key);
|
|
133
|
+
return { key, value, source };
|
|
134
|
+
}
|
|
135
|
+
/** Layers above the write scope: a value from one of them hides what the scope writes. */
|
|
136
|
+
const ABOVE = {
|
|
137
|
+
user: ["profile", "project", "cli", "env"],
|
|
138
|
+
project: ["cli", "env"],
|
|
139
|
+
};
|
|
140
|
+
export function overriddenFor(value, scope) {
|
|
141
|
+
return ABOVE[scope].includes(value.source) ? value.source : undefined;
|
|
142
|
+
}
|
|
143
|
+
// ---- parsing ---------------------------------------------------------------
|
|
144
|
+
const TRUE = new Set(["true", "on", "1", "yes"]);
|
|
145
|
+
const FALSE = new Set(["false", "off", "0", "no"]);
|
|
146
|
+
const UNSET = new Set(["none", "unset"]);
|
|
147
|
+
function invalid(message) {
|
|
148
|
+
return new ConfigEditError("config_invalid_value", message);
|
|
149
|
+
}
|
|
150
|
+
function rangeText(spec) {
|
|
151
|
+
if (spec.minimum !== undefined && spec.maximum !== undefined)
|
|
152
|
+
return `${spec.minimum}–${spec.maximum}`;
|
|
153
|
+
if (spec.minimum !== undefined)
|
|
154
|
+
return `≥ ${spec.minimum}`;
|
|
155
|
+
return `≤ ${spec.maximum}`;
|
|
156
|
+
}
|
|
157
|
+
function parseNumber(key, raw, spec) {
|
|
158
|
+
const text = raw.trim().replace(/_/g, "");
|
|
159
|
+
const value = text === "" ? Number.NaN : Number(text);
|
|
160
|
+
if (!Number.isFinite(value))
|
|
161
|
+
throw invalid(msg().settings.errors.invalidNumber(key, raw));
|
|
162
|
+
if ((spec.minimum !== undefined && value < spec.minimum) ||
|
|
163
|
+
(spec.maximum !== undefined && value > spec.maximum))
|
|
164
|
+
throw invalid(msg().settings.errors.outOfRange(key, rangeText(spec)));
|
|
165
|
+
return value;
|
|
166
|
+
}
|
|
167
|
+
/** Registry spec, or one derived from the schema for documented keys outside the panel. */
|
|
168
|
+
function specFor(key) {
|
|
169
|
+
const spec = settingSpec(key);
|
|
170
|
+
if (spec !== undefined)
|
|
171
|
+
return spec;
|
|
172
|
+
if (!settableKeys().includes(key))
|
|
173
|
+
throw new ConfigEditError("config_unknown_key", msg().settings.errors.unknownKey(key));
|
|
174
|
+
return { key, schema: schemaAt(key) ?? {} };
|
|
175
|
+
}
|
|
176
|
+
/** Throws `config_unknown_key` unless `ama config set` accepts the key. */
|
|
177
|
+
export function assertSettable(key) {
|
|
178
|
+
specFor(key);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Parse a command line / panel value. `undefined` means unset (`none`, `unset`; `default` too unless it
|
|
182
|
+
* is a valid enum value). `jsonValue` takes JSON (lists and objects need it).
|
|
183
|
+
*/
|
|
184
|
+
export function parseValue(key, raw, jsonValue = false) {
|
|
185
|
+
const m = msg().settings.errors;
|
|
186
|
+
const spec = specFor(key);
|
|
187
|
+
if (jsonValue) {
|
|
188
|
+
try {
|
|
189
|
+
return JSON.parse(raw) ?? undefined;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
throw invalid(m.invalidJson(key, errorText(error)));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const text = raw.trim();
|
|
196
|
+
const lower = text.toLowerCase();
|
|
197
|
+
if (UNSET.has(lower))
|
|
198
|
+
return undefined;
|
|
199
|
+
if (!("kind" in spec)) {
|
|
200
|
+
const type = spec.schema["type"];
|
|
201
|
+
if (type === "array" || type === "object" || spec.schema["anyOf"] !== undefined)
|
|
202
|
+
throw invalid(m.needsJson(key));
|
|
203
|
+
if (type === "boolean")
|
|
204
|
+
return parseBool(key, text);
|
|
205
|
+
if (type === "number")
|
|
206
|
+
return parseNumber(key, text, spec.schema);
|
|
207
|
+
if (Array.isArray(spec.schema["enum"]))
|
|
208
|
+
return parseEnum(key, text, spec.schema["enum"]);
|
|
209
|
+
if (text === "")
|
|
210
|
+
throw invalid(m.emptyText(key));
|
|
211
|
+
return text;
|
|
212
|
+
}
|
|
213
|
+
switch (spec.kind) {
|
|
214
|
+
case "bool":
|
|
215
|
+
if (lower === "default")
|
|
216
|
+
return undefined;
|
|
217
|
+
return parseBool(key, text);
|
|
218
|
+
case "enum":
|
|
219
|
+
return parseEnum(key, text, spec.options ?? []);
|
|
220
|
+
case "number":
|
|
221
|
+
if (lower === "default")
|
|
222
|
+
return undefined;
|
|
223
|
+
return parseNumber(key, text, spec);
|
|
224
|
+
case "optionalNumber": {
|
|
225
|
+
const keyword = spec.keywords?.find((k) => k.toLowerCase() === lower);
|
|
226
|
+
if (keyword !== undefined)
|
|
227
|
+
return keyword;
|
|
228
|
+
if (lower === "default" || lower === "unlimited" || lower === "off")
|
|
229
|
+
return undefined;
|
|
230
|
+
return parseNumber(key, text, spec);
|
|
231
|
+
}
|
|
232
|
+
case "model":
|
|
233
|
+
if (lower === "default")
|
|
234
|
+
return undefined;
|
|
235
|
+
if (!/^[^/\s]+\/\S+$/.test(text))
|
|
236
|
+
throw invalid(m.invalidModel(key, raw));
|
|
237
|
+
return text;
|
|
238
|
+
case "text":
|
|
239
|
+
if (text === "")
|
|
240
|
+
throw invalid(m.emptyText(key));
|
|
241
|
+
return text;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function parseBool(key, text) {
|
|
245
|
+
const lower = text.toLowerCase();
|
|
246
|
+
if (TRUE.has(lower))
|
|
247
|
+
return true;
|
|
248
|
+
if (FALSE.has(lower))
|
|
249
|
+
return false;
|
|
250
|
+
throw invalid(msg().settings.errors.invalidBool(key, text));
|
|
251
|
+
}
|
|
252
|
+
function parseEnum(key, text, options) {
|
|
253
|
+
const lower = text.toLowerCase();
|
|
254
|
+
const hit = options.find((o) => o.toLowerCase() === lower);
|
|
255
|
+
if (hit !== undefined)
|
|
256
|
+
return hit;
|
|
257
|
+
if (lower === "default")
|
|
258
|
+
return undefined;
|
|
259
|
+
throw invalid(msg().settings.errors.invalidEnum(key, text, options.join(" | ")));
|
|
260
|
+
}
|
|
261
|
+
function readTarget(path, scope) {
|
|
262
|
+
let text;
|
|
263
|
+
try {
|
|
264
|
+
text = readFileSync(path, "utf8");
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
if (error.code === "ENOENT")
|
|
268
|
+
return scope === "user"
|
|
269
|
+
? minimalConfig()
|
|
270
|
+
: { version: CONFIG_FILE_VERSION };
|
|
271
|
+
throw new ConfigEditError("config_read_failed", msg().settings.errors.readFailed(errorText(error)));
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
const parsed = parseJsonText(text);
|
|
275
|
+
if (isObject(parsed))
|
|
276
|
+
return parsed;
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
throw new ConfigEditError("config_read_failed", msg().settings.errors.readFailed(`${path}: ${errorText(error)}`));
|
|
280
|
+
}
|
|
281
|
+
throw new ConfigEditError("config_read_failed", msg().settings.errors.readFailed(path));
|
|
282
|
+
}
|
|
283
|
+
/** Refuse a project write that `restrictProjectConfig` would ignore. */
|
|
284
|
+
function checkProject(key, value, next, base) {
|
|
285
|
+
if (value === undefined)
|
|
286
|
+
return;
|
|
287
|
+
const accepted = restrictAgainst(next, base);
|
|
288
|
+
const got = getPath(accepted, key);
|
|
289
|
+
const ok = Array.isArray(value) ? Array.isArray(got) : same(got, value);
|
|
290
|
+
if (ok)
|
|
291
|
+
return;
|
|
292
|
+
const m = msg().settings.errors;
|
|
293
|
+
const spec = settingSpec(key);
|
|
294
|
+
if (spec?.project === "tighten") {
|
|
295
|
+
const current = getPath(base, key) ?? settingDefault(key);
|
|
296
|
+
throw new ConfigEditError("config_project_denied", m.projectTighten(key, current === undefined ? "-" : String(current)));
|
|
297
|
+
}
|
|
298
|
+
throw new ConfigEditError("config_project_denied", m.projectDenied(key));
|
|
299
|
+
}
|
|
300
|
+
/** Write one key into the user or project file (or unset it with `value: undefined`). */
|
|
301
|
+
export function setConfigValue(options) {
|
|
302
|
+
const { scope, key, value } = options;
|
|
303
|
+
const spec = specFor(key);
|
|
304
|
+
const before = readSnapshot(options);
|
|
305
|
+
const beforeValue = getConfigValue(before, key);
|
|
306
|
+
const path = scope === "user" ? before.userPath : before.projectPath;
|
|
307
|
+
const current = readTarget(path, scope);
|
|
308
|
+
const next = structuredClone(current);
|
|
309
|
+
setPath(next, key, value);
|
|
310
|
+
const errors = validateConfig(next).filter((d) => d.severity === "error");
|
|
311
|
+
if (hasErrors(errors)) {
|
|
312
|
+
const first = errors.find((d) => d.path === key) ?? errors[0];
|
|
313
|
+
throw invalid(msg().settings.errors.invalid(key, first.message));
|
|
314
|
+
}
|
|
315
|
+
if (scope === "project")
|
|
316
|
+
checkProject(key, value, next, before.base);
|
|
317
|
+
if (!same(current, next)) {
|
|
318
|
+
try {
|
|
319
|
+
writeConfigFile(path, next, { backup: true });
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
throw new ConfigEditError("config_write_failed", msg().settings.errors.writeFailed(path, errorText(error)));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const snapshot = readSnapshot(options);
|
|
326
|
+
const after = getConfigValue(snapshot, key);
|
|
327
|
+
const registry = "kind" in spec ? spec : undefined;
|
|
328
|
+
return {
|
|
329
|
+
key,
|
|
330
|
+
scope,
|
|
331
|
+
path,
|
|
332
|
+
before: beforeValue,
|
|
333
|
+
after,
|
|
334
|
+
apply: registry?.apply,
|
|
335
|
+
prefixChanged: registry?.prefix === true && !same(beforeValue.value, after.value),
|
|
336
|
+
overriddenBy: overriddenFor(after, scope),
|
|
337
|
+
snapshot,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
export function unsetConfigValue(options) {
|
|
341
|
+
return setConfigValue({ ...options, value: undefined });
|
|
342
|
+
}
|
|
343
|
+
/** Display text of a value (JSON for lists / objects, plain otherwise). */
|
|
344
|
+
export function formatSettingValue(value) {
|
|
345
|
+
if (value === undefined)
|
|
346
|
+
return msg().settings.unset;
|
|
347
|
+
if (typeof value === "string")
|
|
348
|
+
return value;
|
|
349
|
+
return JSON.stringify(value);
|
|
350
|
+
}
|
package/dist/config/init.d.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* - 目录 0700;`config.json` 只在不存在时写最小内容(`--force` 时先备份再重写):只有 `$schema`、
|
|
5
5
|
* `version` 与空 `providers`,不写死任何缺省值——缺省值以后调整(例如 codemode 跟随预设)对老用户
|
|
6
6
|
* 同样生效,`config show` 的来源也显示 default 而不是 user;
|
|
7
|
-
* - `config.schema.json` 不是用户文件,每次 init
|
|
7
|
+
* - `config.schema.json` 不是用户文件,每次 init 都按当前版本与当前界面语言重写(内容相同则不动;
|
|
8
|
+
* 说明跟随界面语言,D21);
|
|
8
9
|
* - 不创建 auth.json(只有 `ama auth set` / `ama providers add` 才写,0600)。
|
|
9
10
|
* - 自动初始化只在 CLI 里、配置目录不存在时触发,`AMA_NO_INIT=1` 关闭;SDK 与测试不走这里。
|
|
10
11
|
*/
|
|
@@ -29,6 +30,6 @@ export declare function initConfigDir(dir: string, options?: {
|
|
|
29
30
|
}): InitResult;
|
|
30
31
|
/** CLI 启动时:配置目录不存在就静默初始化;返回是否初始化了。失败不影响启动。 */
|
|
31
32
|
export declare function autoInitConfigDir(dir: string, env: Readonly<Record<string, string | undefined>>): boolean;
|
|
32
|
-
/** init 之后的下一步(配 key / 接中转站 /
|
|
33
|
-
export declare
|
|
33
|
+
/** init 之后的下一步(配 key / 接中转站 / 自检;当前界面语言)。 */
|
|
34
|
+
export declare function initNextSteps(): string[];
|
|
34
35
|
export declare function describeInit(result: InitResult): string;
|
package/dist/config/init.js
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
* - 目录 0700;`config.json` 只在不存在时写最小内容(`--force` 时先备份再重写):只有 `$schema`、
|
|
5
5
|
* `version` 与空 `providers`,不写死任何缺省值——缺省值以后调整(例如 codemode 跟随预设)对老用户
|
|
6
6
|
* 同样生效,`config show` 的来源也显示 default 而不是 user;
|
|
7
|
-
* - `config.schema.json` 不是用户文件,每次 init
|
|
7
|
+
* - `config.schema.json` 不是用户文件,每次 init 都按当前版本与当前界面语言重写(内容相同则不动;
|
|
8
|
+
* 说明跟随界面语言,D21);
|
|
8
9
|
* - 不创建 auth.json(只有 `ama auth set` / `ama providers add` 才写,0600)。
|
|
9
10
|
* - 自动初始化只在 CLI 里、配置目录不存在时触发,`AMA_NO_INIT=1` 关闭;SDK 与测试不走这里。
|
|
10
11
|
*/
|
|
11
12
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
12
13
|
import { join } from "node:path";
|
|
14
|
+
import { msg } from "../i18n/index.js";
|
|
13
15
|
import { CONFIG_SCHEMA_FILE, configSchemaText } from "./json-schema.js";
|
|
14
16
|
import { AUTH_FILE, CONFIG_FILE } from "./paths.js";
|
|
15
17
|
import { CONFIG_FILE_VERSION } from "./types.js";
|
|
@@ -76,24 +78,14 @@ export function autoInitConfigDir(dir, env) {
|
|
|
76
78
|
return false;
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
unchanged: "已是当前版本",
|
|
84
|
-
overwritten: "已重写(原文件备份为 .bak)",
|
|
85
|
-
};
|
|
86
|
-
/** init 之后的下一步(配 key / 接中转站 / 自检)。 */
|
|
87
|
-
export const INIT_NEXT_STEPS = [
|
|
88
|
-
"下一步:",
|
|
89
|
-
" ama auth set anthropic 保存内置供应商的 key(或设置 ANTHROPIC_API_KEY 等环境变量)",
|
|
90
|
-
" ama providers add <id> --base-url <url> 接入中转站或自建服务",
|
|
91
|
-
" ama doctor 检查配置、key 与运行环境",
|
|
92
|
-
" ama config show 查看生效配置与每项来源",
|
|
93
|
-
];
|
|
81
|
+
/** init 之后的下一步(配 key / 接中转站 / 自检;当前界面语言)。 */
|
|
82
|
+
export function initNextSteps() {
|
|
83
|
+
return msg().config.init.nextSteps.split("\n");
|
|
84
|
+
}
|
|
94
85
|
export function describeInit(result) {
|
|
95
|
-
const
|
|
86
|
+
const m = msg().config.init;
|
|
87
|
+
const lines = [`${result.dir} ${result.dirCreated ? m.dirCreated : m.dirExists}`];
|
|
96
88
|
for (const file of result.files)
|
|
97
|
-
lines.push(` ${file.path} ${
|
|
89
|
+
lines.push(` ${file.path} ${m.status[file.status]}`);
|
|
98
90
|
return `${lines.join("\n")}\n`;
|
|
99
91
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* (docs/providers.md「配置目录」)。规则与 schema.ts 的 `validateConfig` 一一对应:未知字段在那里是
|
|
4
4
|
* warning、这里是 `additionalProperties: false`;渠道引用(模型 `channels` 指向已定义的渠道)这类跨字段
|
|
5
5
|
* 规则 JSON Schema 表达不了,只在 `validateConfig` 里查。一致性由 json-schema.test.ts 的正反例守住。
|
|
6
|
-
* 顶层与各段的键(供应商内部除外)的 description / default 来自 key-docs.ts(`annotate
|
|
6
|
+
* 顶层与各段的键(供应商内部除外)的 description / default 来自 key-docs.ts(`annotate`);说明跟随界面
|
|
7
|
+
* 语言(D21),`ama init` 按当前语言重写。
|
|
7
8
|
*/
|
|
8
9
|
type Schema = Record<string, unknown>;
|
|
9
10
|
export declare const CONFIG_SCHEMA_FILE = "config.schema.json";
|