mixdog 1.1.1 → 1.2.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/README.md +1 -0
- package/package.json +2 -2
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/release-paths.mjs +39 -2
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +6 -0
- package/src/defaults/skills/setup/references/actions.md +5 -2
- package/src/defaults/skills/visualize/SKILL.md +157 -0
- package/src/defaults/skills/visualize/references/craft.md +88 -0
- package/src/headless-command.mjs +56 -3
- package/src/headless-exec.mjs +17 -1
- package/src/headless-role.mjs +2 -2
- package/src/help.mjs +2 -0
- package/src/lib/rules-builder.cjs +0 -23
- package/src/rules/lead/LEAD.md +2 -2
- package/src/rules/shared/70-delivery.md +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
- package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +9 -1
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +47 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +51 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +25 -5
- package/src/runtime/agent/orchestrator/mcp/client.mjs +348 -122
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +12 -4
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +67 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +521 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +15 -1
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +12 -11
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +11 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +11 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +18 -11
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +12 -14
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +17 -7
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +1 -5
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
- package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +29 -19
- package/src/runtime/agent/orchestrator/session/read-dedup.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +28 -8
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +140 -0
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +31 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +80 -66
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -10
- package/src/runtime/attachments/store.mjs +38 -0
- package/src/runtime/channels/index.mjs +1 -5
- package/src/runtime/channels/lib/runtime-paths.mjs +8 -23
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -13
- package/src/runtime/channels/lib/worker-ipc.mjs +2 -2
- package/src/runtime/channels/lib/worker-main.mjs +4 -34
- package/src/runtime/shared/atomic-file.mjs +8 -2
- package/src/runtime/shared/best-effort-stderr.mjs +8 -0
- package/src/runtime/shared/code-graph-state.mjs +12 -0
- package/src/runtime/shared/defaults-separation.mjs +2 -0
- package/src/runtime/shared/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- package/src/runtime/shared/llm/default-context-window.mjs +6 -0
- package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
- package/src/runtime/shared/llm/model-catalog.mjs +240 -118
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +156 -0
- package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
- package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
- package/src/runtime/shared/model-proxy-mode.mjs +19 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -2
- package/src/runtime/shared/provider-api-key.mjs +21 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/semver.d.mts +1 -0
- package/src/runtime/shared/semver.mjs +57 -0
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
- package/src/runtime/shared/tool-surface.mjs +9 -2
- package/src/runtime/shared/tool-work-units.mjs +14 -0
- package/src/runtime/shared/transcript-metadata.mjs +17 -1
- package/src/runtime/shared/turn-changes.mjs +791 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
- package/src/runtime/shared/turn-snapshot.mjs +690 -81
- package/src/runtime/shared/turn-worktree-snapshot.mjs +161 -11
- package/src/runtime/shared/update-checker.mjs +2 -31
- package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
- package/src/runtime/shared/worktrees/contract.mjs +551 -0
- package/src/runtime/shared/worktrees/disk.mjs +57 -0
- package/src/runtime/shared/worktrees/git.mjs +247 -0
- package/src/runtime/shared/worktrees/include.mjs +480 -0
- package/src/runtime/shared/worktrees/lock.mjs +46 -0
- package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
- package/src/runtime/shared/worktrees/manager.mjs +1215 -0
- package/src/runtime/shared/worktrees/merge.mjs +182 -0
- package/src/runtime/shared/worktrees/owner.mjs +46 -0
- package/src/runtime/shared/worktrees/paths.mjs +62 -0
- package/src/runtime/shared/worktrees/registry.mjs +110 -0
- package/src/runtime/shared/worktrees/settings.mjs +84 -0
- package/src/runtime/shared/worktrees/slug.mjs +62 -0
- package/src/runtime/shared/worktrees/test-support.mjs +96 -0
- package/src/runtime/visualize-bridge/client.mjs +181 -0
- package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
- package/src/session-runtime/boot/apis.mjs +35 -0
- package/src/session-runtime/boot/begin.mjs +0 -2
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +20 -0
- package/src/session-runtime/boot/infrastructure.mjs +1 -0
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +9 -4
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +11 -1
- package/src/session-runtime/global-extensions.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
- package/src/session-runtime/internal-tool-executor.mjs +9 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
- package/src/session-runtime/mcp-glue/connect.mjs +11 -6
- package/src/session-runtime/mcp-glue/server-catalog.mjs +7 -3
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -0
- package/src/session-runtime/model-route/set-route.mjs +15 -2
- package/src/session-runtime/notification-bus.mjs +9 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- package/src/session-runtime/resource-extension-sync.mjs +30 -7
- package/src/session-runtime/resource-mcp-api.mjs +27 -10
- package/src/session-runtime/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-bootstrap.mjs +0 -4
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-paths.mjs +0 -1
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
- package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-worker.mjs +1 -1
- package/src/session-runtime/services/daemon-candidate.mjs +3 -2
- package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
- package/src/session-runtime/session-create/session-options.mjs +10 -1
- package/src/session-runtime/session-turn-api.mjs +1 -0
- package/src/session-runtime/settings-api.mjs +4 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
- package/src/session-runtime/settings-profile-api.mjs +27 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +11 -4
- package/src/session-runtime/setup-tool/settings-contract.mjs +3 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +31 -3
- package/src/session-runtime/starter-guide-state.mjs +62 -0
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +13 -3
- package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
- package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
- package/src/session-runtime/turn/turn-run.mjs +6 -7
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -2
- package/src/session-runtime/workspace/admission-gate.mjs +197 -0
- package/src/session-runtime/workspace/project-branches.mjs +136 -0
- package/src/session-runtime/workspace/transition-steps.mjs +364 -0
- package/src/session-runtime/workspace/transitions.mjs +651 -0
- package/src/session-runtime/workspace/workspace-state.mjs +112 -0
- package/src/standalone/channel-binding.mjs +1 -2
- package/src/standalone/channel-transport/call-dispatch.mjs +4 -10
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-channels-loader.mjs +2 -3
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-owner.mjs +372 -0
- package/src/standalone/daemon-stored-session-views.mjs +4 -1
- package/src/standalone/daemon.mjs +139 -5
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +13 -78
- package/src/standalone/session-client/attachment-calls.mjs +3 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
- package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
- package/src/standalone/session-client.mjs +104 -13
- package/src/standalone/session-protocol.mjs +17 -0
- package/src/standalone/session-proxy.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
- package/src/standalone/session-service/projection/revisions.mjs +2 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
- package/src/standalone/session-service/projection/workspace.mjs +14 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +11 -3
- package/src/standalone/session-transport/call-route.mjs +13 -0
- package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
- package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
- package/src/standalone/session-transport/client-registry.mjs +20 -3
- package/src/standalone/session-transport/routes.mjs +79 -2
- package/src/standalone/session-transport/stack.mjs +2 -0
- package/src/standalone/session-transport.mjs +24 -1
- package/src/tui/app/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +35 -5
- package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
- package/src/tui/app/model-picker.mjs +4 -2
- package/src/tui/dist/index.mjs +332 -36
- package/src/tui/index.jsx +10 -2
- package/src/tui/session/compaction-view.mjs +147 -0
- package/src/tui/session/context-state.mjs +6 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/quota-resume.mjs +2 -1
- package/src/tui/session/session-api/commands.mjs +10 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +12 -8
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +18 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
- package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
- package/src/tui/session/session-api/routes.mjs +10 -1
- package/src/tui/session/session-api/settings.mjs +2 -0
- package/src/tui/session/session-api/shared.mjs +10 -6
- package/src/tui/session/session-api/worktree.mjs +60 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +31 -12
- package/src/tui/session/session-flow/drain.mjs +15 -1
- package/src/tui/session/session-flow/session-reset.mjs +4 -3
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/transcript-intake.mjs +14 -5
- package/src/tui/session/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +39 -10
- package/src/runtime/channels/tool-defs.mjs +0 -17
|
@@ -20,6 +20,7 @@ function bootParams({
|
|
|
20
20
|
fast,
|
|
21
21
|
modelParameters,
|
|
22
22
|
contextPercent,
|
|
23
|
+
contextTokens,
|
|
23
24
|
selectedContextWindow,
|
|
24
25
|
cwd = process.cwd(),
|
|
25
26
|
toolMode = 'full',
|
|
@@ -30,6 +31,7 @@ function bootParams({
|
|
|
30
31
|
initialConfig = null,
|
|
31
32
|
desktopSession = null,
|
|
32
33
|
sessionProfile = null,
|
|
34
|
+
worktree = null,
|
|
33
35
|
executeAgentControl = null,
|
|
34
36
|
} = {}) {
|
|
35
37
|
return {
|
|
@@ -39,6 +41,7 @@ function bootParams({
|
|
|
39
41
|
fast,
|
|
40
42
|
modelParameters,
|
|
41
43
|
contextPercent,
|
|
44
|
+
contextTokens,
|
|
42
45
|
selectedContextWindow,
|
|
43
46
|
cwd,
|
|
44
47
|
toolMode,
|
|
@@ -49,6 +52,8 @@ function bootParams({
|
|
|
49
52
|
initialConfig,
|
|
50
53
|
desktopSession,
|
|
51
54
|
sessionProfile,
|
|
55
|
+
// Creation-time worktree intent (workspace/transitions.mjs creationIntent).
|
|
56
|
+
worktree,
|
|
52
57
|
executeAgentControl,
|
|
53
58
|
};
|
|
54
59
|
}
|
|
@@ -74,6 +74,10 @@ export function createRuntimeFacade({
|
|
|
74
74
|
get fast() {
|
|
75
75
|
return state.route.fast === true;
|
|
76
76
|
},
|
|
77
|
+
// The route's Auto effort switch; absent means on.
|
|
78
|
+
get autoEffort() {
|
|
79
|
+
return state.route.autoEffort !== false;
|
|
80
|
+
},
|
|
77
81
|
get fastCapable() {
|
|
78
82
|
return state.route.fastCapable === true;
|
|
79
83
|
},
|
|
@@ -94,6 +98,10 @@ export function createRuntimeFacade({
|
|
|
94
98
|
// Picker preference for a new/inherited session, not the live gauge.
|
|
95
99
|
return state.route?.contextPercent ?? state.session?.contextPercent ?? null;
|
|
96
100
|
},
|
|
101
|
+
get contextTokens() {
|
|
102
|
+
// Exact window preference in tokens; null when the route uses a percent stop.
|
|
103
|
+
return state.route ? state.route.contextTokens || null : state.session?.contextTokens || null;
|
|
104
|
+
},
|
|
97
105
|
get rawContextWindow() {
|
|
98
106
|
return state.session?.rawContextWindow || state.session?.contextWindow || null;
|
|
99
107
|
},
|
|
@@ -6,7 +6,6 @@ export const RUNTIME = '../runtime/agent/orchestrator';
|
|
|
6
6
|
export const WEB_SEARCH_RUNTIME = '../runtime/web-search/index.mjs';
|
|
7
7
|
export const WEB_SEARCH_TOOL_DEFS = '../runtime/web-search/tool-defs.mjs';
|
|
8
8
|
export const MEMORY_TOOL_DEFS = '../runtime/memory/tool-defs.mjs';
|
|
9
|
-
export const CHANNEL_TOOL_DEFS = '../runtime/channels/tool-defs.mjs';
|
|
10
9
|
export const CODE_GRAPH_TOOL_DEFS = '../runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs';
|
|
11
10
|
export const CODE_GRAPH_RUNTIME = '../runtime/agent/orchestrator/tools/code-graph.mjs';
|
|
12
11
|
export const STATUSLINE_SESSION_ROUTES = '../vendor/statusline/src/gateway/session-routes.mjs';
|
|
@@ -2,7 +2,10 @@ import { registerCacheInvalidationListener } from '../runtime/agent/orchestrator
|
|
|
2
2
|
import { turnReviewReply } from '../runtime/shared/turn-review-reply.mjs';
|
|
3
3
|
import {
|
|
4
4
|
getSessionReviewDiff,
|
|
5
|
+
getTurnChanges,
|
|
5
6
|
getTurnReviewDiff,
|
|
7
|
+
reapplyTurnChanges,
|
|
8
|
+
revertTurnChanges,
|
|
6
9
|
revertTurnReview,
|
|
7
10
|
revertTurnReviewFile,
|
|
8
11
|
} from '../runtime/shared/turn-snapshot.mjs';
|
|
@@ -22,5 +25,11 @@ export function createRuntimeReviewApi({ getCwd, getSessionId }) {
|
|
|
22
25
|
getSessionReviewDiff: () => getSessionReviewDiff(getCwd(), getSessionId()),
|
|
23
26
|
revertTurnReview: (checkpointId) => revertTurnReview(getCwd(), getSessionId(), checkpointId),
|
|
24
27
|
revertTurnReviewFile: (file, checkpointId) => revertTurnReviewFile(getCwd(), getSessionId(), file, checkpointId),
|
|
28
|
+
// Historical per-turn changes, addressed by checkpointId (TurnChangesReply).
|
|
29
|
+
getTurnChanges: (options = {}) => getTurnChanges(getSessionId(), options),
|
|
30
|
+
revertTurnChanges: (checkpointId, file, revision) =>
|
|
31
|
+
revertTurnChanges(getSessionId(), checkpointId, file, revision),
|
|
32
|
+
reapplyTurnChanges: (checkpointId, file, revision) =>
|
|
33
|
+
reapplyTurnChanges(getSessionId(), checkpointId, file, revision),
|
|
25
34
|
};
|
|
26
35
|
}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { PRESET_ALIASES } from './tool-def.mjs';
|
|
13
13
|
import { positiveInt } from '../../../runtime/shared/numbers.mjs';
|
|
14
14
|
import { clean } from '../../../runtime/shared/clean.mjs';
|
|
15
|
+
import { normalizeContextTokens } from '../../../runtime/shared/llm/default-context-window.mjs';
|
|
15
16
|
|
|
16
17
|
export { positiveInt };
|
|
17
18
|
|
|
@@ -220,10 +221,14 @@ export function normalizeAgentRoute(routeLike) {
|
|
|
220
221
|
model,
|
|
221
222
|
effort: clean(routeLike?.effort) || undefined,
|
|
222
223
|
fast: routeLike?.fast === true,
|
|
224
|
+
...(routeLike?.autoEffort === false ? { autoEffort: false } : {}),
|
|
223
225
|
...(routeLike?.modelParameters && typeof routeLike.modelParameters === 'object'
|
|
224
226
|
? { modelParameters: { ...routeLike.modelParameters } }
|
|
225
227
|
: {}),
|
|
226
228
|
...(Number(routeLike?.contextPercent) > 0 ? { contextPercent: Number(routeLike.contextPercent) } : {}),
|
|
229
|
+
...(normalizeContextTokens(routeLike?.contextTokens)
|
|
230
|
+
? { contextTokens: normalizeContextTokens(routeLike.contextTokens) }
|
|
231
|
+
: {}),
|
|
227
232
|
};
|
|
228
233
|
}
|
|
229
234
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// progress, filtered by default to workers that can still do work.
|
|
4
4
|
import { ACTIVE_STAGES } from '../tool-def.mjs';
|
|
5
5
|
import { isTerminalWorkerStatus } from '../worker-rows.mjs';
|
|
6
|
+
import { sessionUsageTotals } from '../../../../runtime/shared/session-usage-totals.mjs';
|
|
6
7
|
|
|
7
8
|
// Idle, closed, errored and reaped/unknown rows are history and stay reachable
|
|
8
9
|
// through the task section (status/read keep their terminal result).
|
|
@@ -36,6 +37,7 @@ function agentRow({ tag, session, runtime, progress, now, indexRow = null }) {
|
|
|
36
37
|
preset: session.presetName || null,
|
|
37
38
|
effort: session.effort || null,
|
|
38
39
|
fast: session.fast === true,
|
|
40
|
+
...(session.autoEffort === false ? { autoEffort: false } : {}),
|
|
39
41
|
// Additive: route model parameters (e.g. Daybreak Blue) when the route has any.
|
|
40
42
|
...(session.modelParameters && Object.keys(session.modelParameters).length
|
|
41
43
|
? { modelParameters: { ...session.modelParameters } }
|
|
@@ -51,6 +53,7 @@ function agentRow({ tag, session, runtime, progress, now, indexRow = null }) {
|
|
|
51
53
|
clientHostPid: session.clientHostPid || null,
|
|
52
54
|
lastStreamDeltaAt: runtime?.lastStreamDeltaAt ? new Date(runtime.lastStreamDeltaAt).toISOString() : null,
|
|
53
55
|
staleSeconds: runtime?.lastStreamDeltaAt ? Math.floor((now - runtime.lastStreamDeltaAt) / 1000) : null,
|
|
56
|
+
...sessionUsageTotals(session),
|
|
54
57
|
windowTokens: Number(session.lastContextTokens ?? session.lastInputTokens) || 0,
|
|
55
58
|
windowCap: Number(session.contextWindow) || null,
|
|
56
59
|
permission: session.permission || null,
|
|
@@ -16,6 +16,7 @@ export function preparedSpawnMeta(prepared, extras = {}) {
|
|
|
16
16
|
model: prepared.preset.model,
|
|
17
17
|
effort: prepared.preset.effort || null,
|
|
18
18
|
fast: prepared.preset.fast === true,
|
|
19
|
+
...(prepared.preset.autoEffort === false ? { autoEffort: false } : {}),
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -72,6 +72,20 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
|
|
|
72
72
|
return true;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/** A workspace transition moved the Lead: its existing row follows (status,
|
|
76
|
+
* reap deadline and liveness stamps unchanged). No row: nothing to write. */
|
|
77
|
+
function updateLeadWorkerCwd(sessionId, cwd) {
|
|
78
|
+
const id = clean(sessionId);
|
|
79
|
+
const next = clean(cwd);
|
|
80
|
+
if (!id || !next) return false;
|
|
81
|
+
index.write((byKey) => {
|
|
82
|
+
const current = byKey.get(id);
|
|
83
|
+
if (!current || current.cwd === next) return;
|
|
84
|
+
byKey.set(id, { ...current, cwd: next });
|
|
85
|
+
});
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
/** Graceful-exit settlement: every turn this process still claims goes idle
|
|
76
90
|
* before the runtime disappears. */
|
|
77
91
|
function flushActiveLeadRows() {
|
|
@@ -147,6 +161,7 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
|
|
|
147
161
|
/** Resolves once every queued Lead index write is on disk. */
|
|
148
162
|
flushLeadWorkerIndexWrites: index.flush,
|
|
149
163
|
upsertLeadSession,
|
|
164
|
+
updateLeadWorkerCwd,
|
|
150
165
|
removeLeadWorkerRow,
|
|
151
166
|
flushActiveLeadRows,
|
|
152
167
|
recoverStaleLeadRows,
|
|
@@ -180,6 +180,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
180
180
|
preset: session.presetName || null,
|
|
181
181
|
effort: session.effort || null,
|
|
182
182
|
fast: session.fast === true,
|
|
183
|
+
...(session.autoEffort === false ? { autoEffort: false } : {}),
|
|
183
184
|
},
|
|
184
185
|
(job, ownerNotifyContext) => runSend(prepared, ownerNotifyContext, job),
|
|
185
186
|
notifyContext
|
|
@@ -17,6 +17,7 @@ import { isAgentDisabled } from '../../../../runtime/shared/agent-route-config.m
|
|
|
17
17
|
import { normalizeAgentPermission } from '../../../../runtime/shared/markdown-frontmatter.mjs';
|
|
18
18
|
import { resolveAgentSpawnPreset } from '../spawn-preset.mjs';
|
|
19
19
|
import { AGENT_OWNER } from '../../../../runtime/agent/orchestrator/agent-owner.mjs';
|
|
20
|
+
import { workspaceCwdLock } from '../../../workspace/admission-gate.mjs';
|
|
20
21
|
|
|
21
22
|
export function createSpawnPlanner({
|
|
22
23
|
cfgMod,
|
|
@@ -52,8 +53,15 @@ export function createSpawnPlanner({
|
|
|
52
53
|
if (resolveTag(tag, context, { scanSessions: wantsSessionScan(args) })) {
|
|
53
54
|
throw new Error(`agent spawn: tag "${tag}" already exists`);
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
// Workers share their Lead's execution root. While the Lead runs in its
|
|
57
|
+
// worktree, that root is locked: neither args.cwd nor an inherited
|
|
58
|
+
// (pre-transition) cwd can send a worker elsewhere.
|
|
59
|
+
const lockedCwd = workspaceCwdLock([
|
|
60
|
+
context?.ownerSessionId,
|
|
61
|
+
context?.callerSessionId || context?.sessionId,
|
|
62
|
+
]);
|
|
63
|
+
const baseCwd = resolve(lockedCwd || callerCwd || defaultCwd || process.cwd());
|
|
64
|
+
const workerCwd = !lockedCwd && clean(args.cwd) ? resolve(baseCwd, args.cwd) : baseCwd;
|
|
57
65
|
const prompt = await resolvePrompt(args, workerCwd);
|
|
58
66
|
if (prepState?.timedOut) {
|
|
59
67
|
throw new Error('agent spawn prep timed out before session bind');
|
|
@@ -10,6 +10,7 @@ import { prepareAgentSession } from '../../../../runtime/agent/orchestrator/agen
|
|
|
10
10
|
import { getProvider } from '../../../../runtime/agent/orchestrator/providers/registry.mjs';
|
|
11
11
|
import { resolveRouteContextState } from '../../../route-state.mjs';
|
|
12
12
|
import { createSpawnPlanner } from './spawn-plan.mjs';
|
|
13
|
+
import { enterWorkerSpawn } from '../../../workspace/admission-gate.mjs';
|
|
13
14
|
|
|
14
15
|
/** The route fields every worker-row and tag record carries. */
|
|
15
16
|
export function presetDescriptor(agent, preset, presetName) {
|
|
@@ -20,6 +21,7 @@ export function presetDescriptor(agent, preset, presetName) {
|
|
|
20
21
|
model: preset.model,
|
|
21
22
|
effort: preset.effort || null,
|
|
22
23
|
fast: preset.fast === true,
|
|
24
|
+
...(preset.autoEffort === false ? { autoEffort: false } : {}),
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -84,9 +86,9 @@ export function createSpawnPreparer({
|
|
|
84
86
|
// A sub-100 context share needs the window it selects; a percent alone
|
|
85
87
|
// keeps the full served window.
|
|
86
88
|
const sessionSpec = { ...spec };
|
|
87
|
-
if (plan.preset.contextPercent) {
|
|
88
|
-
const { contextPercent, selectedContextWindow } = resolveRouteContextState(plan.preset, null);
|
|
89
|
-
Object.assign(sessionSpec, { contextPercent, selectedContextWindow });
|
|
89
|
+
if (plan.preset.contextPercent || plan.preset.contextTokens) {
|
|
90
|
+
const { contextPercent, selectedContextWindow, contextTokens } = resolveRouteContextState(plan.preset, null);
|
|
91
|
+
Object.assign(sessionSpec, { contextPercent, selectedContextWindow }, contextTokens ? { contextTokens } : {});
|
|
90
92
|
}
|
|
91
93
|
if (sessionSurface?.canonical === true && typeof sessionSurface.createChild === 'function') {
|
|
92
94
|
return sessionSurface.createChild({ spec: sessionSpec, prompt: plan.prompt, tag: plan.tag });
|
|
@@ -99,10 +101,20 @@ export function createSpawnPreparer({
|
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
async function prepareSpawnInProcess(args, callerCwd = null, context = {}, prepState = null) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
104
|
+
// Shared admission with Lead workspace transitions: no spawn is prepared
|
|
105
|
+
// while the Lead's workspace changes, no transition starts mid-spawn.
|
|
106
|
+
const leaveSpawn = enterWorkerSpawn([context?.ownerSessionId, context?.callerSessionId || context?.sessionId]);
|
|
107
|
+
let plan;
|
|
108
|
+
let session;
|
|
109
|
+
let effectiveCwd;
|
|
110
|
+
try {
|
|
111
|
+
plan = await resolveSpawnPlan(args, callerCwd, context, prepState);
|
|
112
|
+
const spec = spawnSessionSpec(plan, args, context);
|
|
113
|
+
({ session, effectiveCwd } = await createSpawnedSession(plan, spec, prepState));
|
|
114
|
+
bindSpawnedSession(session, plan);
|
|
115
|
+
} finally {
|
|
116
|
+
leaveSpawn();
|
|
117
|
+
}
|
|
106
118
|
if (sessionSurface?.canonical !== true) {
|
|
107
119
|
maybePrewarmSpawnTransport(plan, session);
|
|
108
120
|
}
|
|
@@ -20,6 +20,7 @@ export function resolveAgentSpawnPreset(config, args = {}) {
|
|
|
20
20
|
model: clean(args.model),
|
|
21
21
|
effort: clean(args.effort) || undefined,
|
|
22
22
|
fast: args.fast === true,
|
|
23
|
+
...(args.autoEffort === false ? { autoEffort: false } : {}),
|
|
23
24
|
tools: 'full',
|
|
24
25
|
},
|
|
25
26
|
};
|
|
@@ -42,8 +43,10 @@ export function resolveAgentSpawnPreset(config, args = {}) {
|
|
|
42
43
|
model: agentRoute.model,
|
|
43
44
|
effort: agentRoute.effort,
|
|
44
45
|
fast: agentRoute.fast === true,
|
|
46
|
+
...(agentRoute.autoEffort === false ? { autoEffort: false } : {}),
|
|
45
47
|
...(agentRoute.modelParameters ? { modelParameters: agentRoute.modelParameters } : {}),
|
|
46
48
|
...(agentRoute.contextPercent ? { contextPercent: agentRoute.contextPercent } : {}),
|
|
49
|
+
...(agentRoute.contextTokens ? { contextTokens: agentRoute.contextTokens } : {}),
|
|
47
50
|
tools: 'full',
|
|
48
51
|
},
|
|
49
52
|
};
|
|
@@ -29,7 +29,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
29
29
|
workerRowFromSession: index.workerRowFromSession,
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
const { upsertLeadSession } = leadIndex;
|
|
32
|
+
const { upsertLeadSession, updateLeadWorkerCwd } = leadIndex;
|
|
33
33
|
|
|
34
34
|
function dispose(options) {
|
|
35
35
|
try {
|
|
@@ -103,6 +103,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
103
103
|
upsertWorkerSession: index.upsertWorkerSession,
|
|
104
104
|
upsertWorkerSessionDeferred,
|
|
105
105
|
upsertLeadSession,
|
|
106
|
+
updateLeadWorkerCwd,
|
|
106
107
|
removeWorkerRow,
|
|
107
108
|
refreshTagsFromIndex,
|
|
108
109
|
tags,
|
|
@@ -38,6 +38,7 @@ export function normalizeWorkerRows(value) {
|
|
|
38
38
|
preset: clean(row.preset) || null,
|
|
39
39
|
effort: clean(row.effort) || null,
|
|
40
40
|
fast: typeof row.fast === 'boolean' ? row.fast : null,
|
|
41
|
+
...(row.autoEffort === false ? { autoEffort: false } : {}),
|
|
41
42
|
status: clean(row.status) || 'idle',
|
|
42
43
|
stage: clean(row.stage) || clean(row.status) || 'idle',
|
|
43
44
|
createdAt: clean(row.createdAt) || null,
|
|
@@ -87,6 +88,10 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
|
|
|
87
88
|
preset: clean(extra.preset) || clean(session?.presetName) || null,
|
|
88
89
|
effort: clean(extra.effort) || clean(session?.effort) || null,
|
|
89
90
|
fast: fastFlag(extra.fast, session?.fast),
|
|
91
|
+
// Absent means Auto effort is on; an explicit boolean wins over the session's.
|
|
92
|
+
...((typeof extra.autoEffort === 'boolean' ? extra.autoEffort : session?.autoEffort) === false
|
|
93
|
+
? { autoEffort: false }
|
|
94
|
+
: {}),
|
|
90
95
|
status,
|
|
91
96
|
stage,
|
|
92
97
|
createdAt: clean(session?.createdAt) || clean(extra.createdAt) || nowIso,
|
|
@@ -133,6 +133,7 @@ export function workerRowToSession(row = {}) {
|
|
|
133
133
|
presetName: row.preset || null,
|
|
134
134
|
effort: row.effort || null,
|
|
135
135
|
fast: row.fast === true,
|
|
136
|
+
...(row.autoEffort === false ? { autoEffort: false } : {}),
|
|
136
137
|
status: row.status || 'idle',
|
|
137
138
|
stage: row.stage || row.status || 'idle',
|
|
138
139
|
createdAt: row.createdAt || null,
|
|
@@ -146,6 +146,7 @@ export function createStandaloneAgent({
|
|
|
146
146
|
getStatus,
|
|
147
147
|
recoverWorkers,
|
|
148
148
|
upsertLeadSession: registry.upsertLeadSession,
|
|
149
|
+
updateLeadWorkerCwd: registry.updateLeadWorkerCwd,
|
|
149
150
|
closeAll: closeFlow.closeAll,
|
|
150
151
|
dispose: (options) => registry.dispose(options),
|
|
151
152
|
};
|
|
@@ -18,7 +18,7 @@ import { daemonEnv, spawnDaemonCandidate } from './channel-worker/daemon-spawn.m
|
|
|
18
18
|
|
|
19
19
|
export { pruneStaleChannelClientHeartbeats };
|
|
20
20
|
|
|
21
|
-
const CHANNEL_TOOLS = new Set(['activate_channel_bridge', 'reload_config'
|
|
21
|
+
const CHANNEL_TOOLS = new Set(['activate_channel_bridge', 'reload_config']);
|
|
22
22
|
const CALL_RETRIES = 3;
|
|
23
23
|
|
|
24
24
|
function logLine(path, line) {
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
// ready handoff so the daemon's code/signal is recorded against its pid, boot
|
|
6
6
|
// time and ready state. Resolves once the candidate reported ready, exited,
|
|
7
7
|
// failed to spawn, or the timeout elapsed; the caller then re-reads discovery
|
|
8
|
-
// and attaches to whoever won.
|
|
8
|
+
// and attaches to whoever won. The resolved `summary()` describes this boot as
|
|
9
|
+
// observed when called, for a caller that has to give up.
|
|
9
10
|
import { fork } from 'node:child_process';
|
|
10
11
|
import { beginDaemonSpawnCapture } from './daemon-crash-capture.mjs';
|
|
11
12
|
|
|
@@ -34,7 +35,7 @@ export function forkDaemonCandidate({
|
|
|
34
35
|
// Boot diagnostics written to fd 2 reach this log exactly once, even when
|
|
35
36
|
// the candidate never reached ready.
|
|
36
37
|
capture.mirror();
|
|
37
|
-
resolve();
|
|
38
|
+
resolve({ summary: capture.summary });
|
|
38
39
|
};
|
|
39
40
|
let child;
|
|
40
41
|
try {
|
|
@@ -20,6 +20,11 @@ const CAPTURE_ID_ATTEMPTS = 8;
|
|
|
20
20
|
const MIRROR_MAX_BYTES = 16 * 1024;
|
|
21
21
|
const MESSAGE_MAX_CHARS = 512;
|
|
22
22
|
const HEAP_FLAG_RE = /^--max-(?:old-space|semi-space|heap)-size=/;
|
|
23
|
+
// Bytes of fd 2 a failure summary scans (the newest ones when larger).
|
|
24
|
+
const SUMMARY_SCAN_MAX_BYTES = 256 * 1024;
|
|
25
|
+
// Node's uncaught-error report (`TypeError: …`, `Error [ERR_…]: …`), V8's
|
|
26
|
+
// fatal abort and the daemon's own `fatal boot error` log line.
|
|
27
|
+
const STDERR_ERROR_LINE_RE = /\b[A-Z][A-Za-z]*Error\b(?: \[[A-Z0-9_]+\])?:|^Error\b|FATAL ERROR|(?<!non-)\bfatal\b/;
|
|
23
28
|
|
|
24
29
|
function stamp(ms) {
|
|
25
30
|
const iso = new Date(ms).toISOString();
|
|
@@ -256,6 +261,8 @@ function noteSpawnError(capture, error) {
|
|
|
256
261
|
// this stream, so nothing here extends its lifetime.
|
|
257
262
|
function drainStderrPipe(capture, stream) {
|
|
258
263
|
const onData = (chunk) => {
|
|
264
|
+
// No capture file to read back: keep the newest bytes for summary().
|
|
265
|
+
capture.pipeText = `${capture.pipeText}${chunk}`.slice(-SUMMARY_SCAN_MAX_BYTES);
|
|
259
266
|
mirrorText(capture.log, chunk);
|
|
260
267
|
};
|
|
261
268
|
stream.on('data', onData);
|
|
@@ -272,6 +279,52 @@ function drainStderrPipe(capture, stream) {
|
|
|
272
279
|
});
|
|
273
280
|
}
|
|
274
281
|
|
|
282
|
+
/** The candidate's fd 2 as text: the capture file (its newest bytes when
|
|
283
|
+
* large) or, when fd 2 fell back to a pipe, what that pipe delivered. */
|
|
284
|
+
function stderrText(capture) {
|
|
285
|
+
if (!capture.capturePath || capture.removed) return capture.pipeText;
|
|
286
|
+
try {
|
|
287
|
+
const handle = fs.openSync(capture.capturePath, 'r');
|
|
288
|
+
try {
|
|
289
|
+
const size = fs.fstatSync(handle).size;
|
|
290
|
+
const length = Math.min(size, SUMMARY_SCAN_MAX_BYTES);
|
|
291
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
292
|
+
const bytesRead = fs.readSync(handle, buffer, 0, length, size - length);
|
|
293
|
+
return buffer.subarray(0, bytesRead).toString('utf8');
|
|
294
|
+
} finally {
|
|
295
|
+
fs.closeSync(handle);
|
|
296
|
+
}
|
|
297
|
+
} catch {
|
|
298
|
+
return capture.pipeText;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** What a launcher that gave up on this boot needs to name its cause: the
|
|
303
|
+
* lifecycle as far as observed, the first error line on fd 2 (else its last
|
|
304
|
+
* line, where a stalled boot stopped) and where the full text is. */
|
|
305
|
+
function summarize(capture) {
|
|
306
|
+
const { record } = capture;
|
|
307
|
+
const lines = stderrText(capture)
|
|
308
|
+
.split(/\r?\n/)
|
|
309
|
+
.map((line) => line.trim())
|
|
310
|
+
.filter(Boolean);
|
|
311
|
+
const errorLine = lines.find((line) => STDERR_ERROR_LINE_RE.test(line));
|
|
312
|
+
return {
|
|
313
|
+
pid: record.pid,
|
|
314
|
+
ready: record.ready,
|
|
315
|
+
spawnedAt: record.spawnedAt,
|
|
316
|
+
exitedAt: record.exitedAt,
|
|
317
|
+
exitCode: record.exitCode,
|
|
318
|
+
exitSignal: record.exitSignal,
|
|
319
|
+
exitReason: record.exitReason ?? null,
|
|
320
|
+
uptimeMs: record.uptimeMs,
|
|
321
|
+
error: record.error,
|
|
322
|
+
stderrErrorLine: errorLine ? boundedMessage(errorLine) : null,
|
|
323
|
+
stderrLastLine: lines.length > 0 ? boundedMessage(lines.at(-1)) : null,
|
|
324
|
+
stderrPath: capture.removed ? null : capture.capturePath,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
275
328
|
/** Attach to the forked child: record its identity and keep a lifetime
|
|
276
329
|
* listener that survives the ready handoff, so a later exit is still
|
|
277
330
|
* correlated to this pid, boot time and ready state. */
|
|
@@ -347,6 +400,7 @@ export function beginDaemonSpawnCapture({
|
|
|
347
400
|
readOffset: 0,
|
|
348
401
|
removed: false,
|
|
349
402
|
pipeDrained: null,
|
|
403
|
+
pipeText: '',
|
|
350
404
|
stderrStdio: 'pipe',
|
|
351
405
|
};
|
|
352
406
|
openCapture(capture, { captureDir, prune, launcherPid, nonce });
|
|
@@ -377,5 +431,6 @@ export function beginDaemonSpawnCapture({
|
|
|
377
431
|
* recording anything — the child, if any, keeps its duplicate. */
|
|
378
432
|
release: () => closeWriteFd(capture),
|
|
379
433
|
snapshot: () => ({ ...capture.record }),
|
|
434
|
+
summary: () => summarize(capture),
|
|
380
435
|
};
|
|
381
436
|
}
|
|
@@ -6,6 +6,7 @@ import { hasOwn } from '../../runtime/agent/orchestrator/runtime-core/session-te
|
|
|
6
6
|
import { toolSpecForMode } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
|
|
7
7
|
import { pluginDataDir } from '../runtime-paths.mjs';
|
|
8
8
|
import { LEAD_DISALLOWED_TOOLS } from '../../runtime/agent/orchestrator/runtime-core/tool-defs.mjs';
|
|
9
|
+
import { HEADLESS_TOOL_PROFILE } from '../../runtime/agent/orchestrator/runtime-core/tool-profile.mjs';
|
|
9
10
|
|
|
10
11
|
// Ownership and permission fields an agent-owned session inherits from its profile.
|
|
11
12
|
function agentOwnedSessionFields(sessionProfile) {
|
|
@@ -47,7 +48,13 @@ export function sessionOptions(deps, coreMemoryContext) {
|
|
|
47
48
|
owner: agentOwned ? 'agent' : 'cli',
|
|
48
49
|
agent: agentOwned ? sessionProfile?.agent || 'worker' : 'lead',
|
|
49
50
|
lane: agentOwned ? 'agent' : 'cli',
|
|
50
|
-
|
|
51
|
+
// One-shot `mixdog exec` runs carry their own source so session catalogs
|
|
52
|
+
// can keep them out of the user's resumable list.
|
|
53
|
+
sourceType: agentOwned
|
|
54
|
+
? sessionProfile?.sourceType || 'agent'
|
|
55
|
+
: rt.toolProfile === HEADLESS_TOOL_PROFILE
|
|
56
|
+
? 'exec'
|
|
57
|
+
: 'lead',
|
|
51
58
|
sourceName: agentOwned ? sessionProfile?.sourceName || sessionProfile?.agent || 'agent' : 'main',
|
|
52
59
|
...(rt.approvalMode ? { approvalMode: rt.approvalMode } : {}),
|
|
53
60
|
clientHostPid: sessionProfile?.clientHostPid || process.pid,
|
|
@@ -64,8 +71,10 @@ export function sessionOptions(deps, coreMemoryContext) {
|
|
|
64
71
|
workflowContext,
|
|
65
72
|
orchestrationMode,
|
|
66
73
|
fast: rt.route.fast === true,
|
|
74
|
+
autoEffort: rt.route.autoEffort !== false,
|
|
67
75
|
modelParameters: rt.route.modelParameters || {},
|
|
68
76
|
contextPercent: rt.route.contextPercent,
|
|
77
|
+
contextTokens: rt.route.contextTokens || null,
|
|
69
78
|
selectedContextWindow: rt.route.selectedContextWindow || null,
|
|
70
79
|
compaction:
|
|
71
80
|
rt.config.compaction && typeof rt.config.compaction === 'object'
|
|
@@ -34,6 +34,7 @@ export function createSessionTurnApi(deps) {
|
|
|
34
34
|
sessionOwnerGone: share.sessionOwnerGone,
|
|
35
35
|
agentControl: agent.agentControl,
|
|
36
36
|
taskControl: agent.taskControl,
|
|
37
|
+
stopShellJob: agent.stopShellJob,
|
|
37
38
|
onNotification: agent.onNotification,
|
|
38
39
|
toolsStatus: agent.toolsStatus,
|
|
39
40
|
selectTools: agent.selectTools,
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// `this.*` resolve against the spread target, so cross-member calls (e.g.
|
|
6
6
|
// setProfile -> this.getProfile) keep working when spread into the facade.
|
|
7
7
|
//
|
|
8
|
-
// The members live in
|
|
8
|
+
// The members live in six topic modules: profile/onboarding/skills,
|
|
9
9
|
// compaction/auto-clear, built-in tool modules, system (channels, shell,
|
|
10
|
-
// updates) and
|
|
10
|
+
// updates), developer options and worktree defaults; the local provider's own methods come from
|
|
11
11
|
// local-provider-settings.mjs.
|
|
12
12
|
import { createLocalProviderSettings } from './local-provider-settings.mjs';
|
|
13
13
|
import { createProfileSettings } from './settings-profile-api.mjs';
|
|
@@ -15,6 +15,7 @@ import { createCompactionSettings } from './settings-compaction-api.mjs';
|
|
|
15
15
|
import { createBuiltinToolSettings } from './settings-builtin-tools-api.mjs';
|
|
16
16
|
import { createSystemSettings } from './settings-system-api.mjs';
|
|
17
17
|
import { createDeveloperSettings } from './settings-developer-api.mjs';
|
|
18
|
+
import { createWorktreeSettings } from './settings-worktree-api.mjs';
|
|
18
19
|
|
|
19
20
|
export function createSettingsApi(deps) {
|
|
20
21
|
// Optional: callers without a live local provider / gate fall back to the
|
|
@@ -38,5 +39,6 @@ export function createSettingsApi(deps) {
|
|
|
38
39
|
...createBuiltinToolSettings(shared, localSettings),
|
|
39
40
|
...createSystemSettings(shared),
|
|
40
41
|
...createDeveloperSettings(shared),
|
|
42
|
+
...createWorktreeSettings(shared),
|
|
41
43
|
};
|
|
42
44
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
builtinInstalled,
|
|
8
8
|
setBuiltinInstalledInConfig,
|
|
9
9
|
} from '../runtime/agent/orchestrator/runtime-core/builtin-features.mjs';
|
|
10
|
+
import { featureEnvOverride, moduleEnabled } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
10
11
|
import { LOCAL_PROVIDER_ID } from '../runtime/local-provider/managed-runtime.mjs';
|
|
11
12
|
import {
|
|
12
13
|
INSTRUCTION_FILES_MODES,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
shutdownEffortJudge,
|
|
24
25
|
} from '../runtime/effort-judge/judge-client.mjs';
|
|
25
26
|
|
|
26
|
-
const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort'];
|
|
27
|
+
const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort', 'visualize'];
|
|
27
28
|
|
|
28
29
|
function setLocalProviderEnabledInConfig(configLike, enabled) {
|
|
29
30
|
const next = { ...(configLike || {}) };
|
|
@@ -97,6 +98,12 @@ export function createBuiltinToolSettings(
|
|
|
97
98
|
enabled: tidyToolEnabledFn ? tidyToolEnabledFn() : builtinFeatureActive(config, 'tidy'),
|
|
98
99
|
installed: builtinInstalled(config, 'tidy'),
|
|
99
100
|
},
|
|
101
|
+
// Ships with the runtime and needs no install; the toggle reflects the
|
|
102
|
+
// module flag, not live bridge presence.
|
|
103
|
+
visualize: {
|
|
104
|
+
enabled: featureEnvOverride('MIXDOG_FEATURE_VISUALIZE') ?? moduleEnabled(config, 'visualize', true),
|
|
105
|
+
installed: true,
|
|
106
|
+
},
|
|
100
107
|
localProvider: {
|
|
101
108
|
...localProvider,
|
|
102
109
|
...localSettings.status(),
|
|
@@ -152,7 +159,7 @@ export function createBuiltinToolSettings(
|
|
|
152
159
|
},
|
|
153
160
|
async setBuiltinToolEnabled(name, enabled) {
|
|
154
161
|
if (!TOGGLEABLE_BUILTINS.includes(name)) {
|
|
155
|
-
throw new TypeError('Built-in tool must be git, office, tidy, localProvider, or
|
|
162
|
+
throw new TypeError('Built-in tool must be git, office, tidy, localProvider, autoEffort, or visualize.');
|
|
156
163
|
}
|
|
157
164
|
if (name === 'autoEffort' && enabled !== false && !onnxRuntimeSupported()) {
|
|
158
165
|
throw new Error(EFFORT_JUDGE_UNSUPPORTED);
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// Onboarding, the user profile (/profile) and the disabled-skill list. Methods
|
|
2
2
|
// reference `this.*` so cross-member calls resolve against the facade object
|
|
3
3
|
// these are spread into.
|
|
4
|
+
import {
|
|
5
|
+
mergeStarterGuide,
|
|
6
|
+
requiredStarterGuideState,
|
|
7
|
+
storedStarterGuide,
|
|
8
|
+
withStarterGuideOnCompletion,
|
|
9
|
+
} from './starter-guide-state.mjs';
|
|
10
|
+
|
|
4
11
|
export function createProfileSettings({
|
|
5
12
|
getConfig,
|
|
6
13
|
adoptConfig,
|
|
@@ -19,21 +26,39 @@ export function createProfileSettings({
|
|
|
19
26
|
version: nextConfig?.onboarding?.version || 0,
|
|
20
27
|
default: nextConfig?.default || null,
|
|
21
28
|
workflowRoutes: summarizeWorkflowRoutes(nextConfig),
|
|
29
|
+
starterGuide: storedStarterGuide(nextConfig?.onboarding?.starterGuide),
|
|
22
30
|
};
|
|
23
31
|
},
|
|
32
|
+
// Persist the desktop "Getting started" guide state beside the onboarding
|
|
33
|
+
// flags so it survives a lost renderer localStorage. Malformed input is
|
|
34
|
+
// rejected; a valid save merges forward, so a stale one cannot reopen a
|
|
35
|
+
// closed guide or forget a visited step.
|
|
36
|
+
saveStarterGuideState(state) {
|
|
37
|
+
const next = requiredStarterGuideState(state);
|
|
38
|
+
const config = getConfig();
|
|
39
|
+
const onboarding = config.onboarding || {};
|
|
40
|
+
saveConfigAndAdopt({
|
|
41
|
+
...config,
|
|
42
|
+
onboarding: {
|
|
43
|
+
...onboarding,
|
|
44
|
+
starterGuide: mergeStarterGuide(storedStarterGuide(onboarding.starterGuide), next),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
return this.getOnboardingStatus();
|
|
48
|
+
},
|
|
24
49
|
// Mark onboarding as done WITHOUT touching routes/agents/provider. Used by
|
|
25
50
|
// the TUI "skip" (Esc) path so the wizard doesn't reappear next launch,
|
|
26
51
|
// while leaving any existing config routes untouched.
|
|
27
52
|
skipOnboarding() {
|
|
28
53
|
const config = getConfig();
|
|
29
54
|
const nextConfig = { ...config };
|
|
30
|
-
nextConfig.onboarding = {
|
|
55
|
+
nextConfig.onboarding = withStarterGuideOnCompletion(config.onboarding, {
|
|
31
56
|
...(nextConfig.onboarding || {}),
|
|
32
57
|
completed: true,
|
|
33
58
|
version: ONBOARDING_VERSION,
|
|
34
59
|
completedAt: new Date().toISOString(),
|
|
35
60
|
skipped: true,
|
|
36
|
-
};
|
|
61
|
+
});
|
|
37
62
|
saveConfigAndAdopt(nextConfig);
|
|
38
63
|
return this.getOnboardingStatus();
|
|
39
64
|
},
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Settings → Worktrees: defaults for Lead-session git worktrees
|
|
2
|
+
// (runtime/shared/worktrees/settings.mjs). Values persist at agent config
|
|
3
|
+
// `worktree.<key>`; defaults are not stored.
|
|
4
|
+
import { applyWorktreeSettingsPatch, normalizeWorktreeSettings } from '../runtime/shared/worktrees/settings.mjs';
|
|
5
|
+
|
|
6
|
+
export function createWorktreeSettings({ getConfig, saveConfigAndAdopt }) {
|
|
7
|
+
return {
|
|
8
|
+
getWorktreeSettings() {
|
|
9
|
+
return normalizeWorktreeSettings(getConfig()?.worktree);
|
|
10
|
+
},
|
|
11
|
+
setWorktreeSettings(patch) {
|
|
12
|
+
const config = getConfig() || {};
|
|
13
|
+
saveConfigAndAdopt({ ...config, worktree: applyWorktreeSettingsPatch(config.worktree, patch) });
|
|
14
|
+
return this.getWorktreeSettings();
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|