mixdog 1.2.3 → 1.2.5
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/package.json +1 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/mobile-release.mjs +5 -4
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +128 -38
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/maintainer/AGENT.md +1 -1
- package/src/agents/maintainer/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -4
- package/src/agents/security/AGENT.md +1 -2
- package/src/agents/writer/AGENT.md +2 -3
- package/src/defaults/shipped-history.json +7 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/output-styles/common.md +2 -1
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +13 -13
- package/src/rules/shared/45-destructive.md +4 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
- package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
- package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +160 -212
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
- package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
- package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
- package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
- package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
- package/src/runtime/attachments/store.d.mts +9 -0
- package/src/runtime/attachments/store.mjs +80 -9
- package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
- package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
- package/src/runtime/computer-bridge/action-schema.mjs +178 -178
- package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
- package/src/runtime/effort-judge/judge-client.mjs +21 -4
- package/src/runtime/effort-judge/judge-worker.mjs +4 -1
- package/src/runtime/github/tool.mjs +118 -17
- package/src/runtime/media/adapters/codex-image.mjs +140 -21
- package/src/runtime/media/catalog.mjs +4 -4
- package/src/runtime/media/chatgpt-usage.mjs +55 -0
- package/src/runtime/media/defaults.mjs +37 -0
- package/src/runtime/media/jobs.mjs +12 -2
- package/src/runtime/media/lanes.mjs +12 -0
- package/src/runtime/media/tool-defs.mjs +15 -4
- package/src/runtime/media/tool.mjs +41 -12
- package/src/runtime/media/upstream-error.mjs +72 -6
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/html-browser.mjs +18 -8
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/session-search/session-search-ingest.mjs +1 -1
- package/src/runtime/shared/agent-reap-state.mjs +13 -0
- package/src/runtime/shared/atomic-file.d.mts +1 -1
- package/src/runtime/shared/background-tasks.mjs +6 -1
- package/src/runtime/shared/bounded-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/model-route-chain.d.mts +8 -0
- package/src/runtime/shared/model-route-chain.mjs +48 -0
- package/src/runtime/shared/model-route-fallback.mjs +22 -0
- package/src/runtime/shared/pid-liveness.mjs +12 -0
- package/src/runtime/shared/provider-api-key.mjs +6 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
- package/src/runtime/shared/quiet-progress.d.mts +35 -0
- package/src/runtime/shared/quiet-progress.mjs +101 -0
- package/src/runtime/shared/quota-resume-store.mjs +32 -1
- package/src/runtime/shared/read-row-numbers.mjs +44 -0
- package/src/runtime/shared/remote-intent.mjs +2 -42
- package/src/runtime/shared/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- package/src/runtime/shared/transcript-metadata.mjs +49 -1
- package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
- package/src/runtime/shared/worktrees/carry.mjs +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- package/src/runtime/shared/worktrees/include.mjs +125 -7
- package/src/runtime/shared/worktrees/lock.mjs +1 -1
- package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
- package/src/runtime/shared/worktrees/manager.mjs +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
- package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
- package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
- package/src/runtime/terminal-bridge/client.mjs +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
- package/src/session-runtime/lifecycle/shared.mjs +5 -6
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
- package/src/session-runtime/lifecycle/teardown.mjs +7 -16
- package/src/session-runtime/media-api.mjs +8 -0
- package/src/session-runtime/model-route/route-ownership.mjs +60 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -2
- package/src/session-runtime/model-route/set-route.mjs +114 -34
- package/src/session-runtime/model-route/web-search-route.mjs +7 -2
- package/src/session-runtime/model-route-api.mjs +4 -2
- package/src/session-runtime/native-web-search/routes.mjs +37 -24
- package/src/session-runtime/native-web-search.mjs +9 -8
- package/src/session-runtime/provider-auth/setup.mjs +4 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
- package/src/session-runtime/provider-models.mjs +1 -0
- package/src/session-runtime/provider-usage.mjs +4 -0
- package/src/session-runtime/route-resolution.mjs +3 -1
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +6 -0
- package/src/session-runtime/services/agent-task-status.mjs +2 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
- package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
- package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
- package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
- package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
- package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
- package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
- package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
- package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- package/src/session-runtime/session-create/session-options.mjs +7 -5
- package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
- package/src/session-runtime/workspace/admission-gate.mjs +44 -15
- package/src/session-runtime/workspace/project-branches.mjs +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/desktop-service-registry.mjs +32 -5
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
- package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
- package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
- package/src/standalone/session-service/agent-tree.mjs +28 -2
- package/src/standalone/session-service/entries/session-loads.mjs +16 -5
- package/src/standalone/session-service/entries.mjs +1 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
- package/src/standalone/session-service/quota-resume.mjs +28 -13
- package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/provider-setup/provider-items.mjs +8 -0
- package/src/tui/app/provider-setup-picker.mjs +15 -3
- package/src/tui/app/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +529 -270
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
- package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
- package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
- package/src/tui/session/quota-resume.mjs +140 -61
- package/src/tui/session/session-api/commands.mjs +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -11
- package/src/tui/session/session-api/media.mjs +2 -0
- package/src/tui/session/session-api/routes.mjs +81 -57
- package/src/tui/session/session-api/settings.mjs +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-flow/auto-clear.mjs +1 -3
- package/src/tui/session/session-flow/drain.mjs +6 -4
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
- package/src/tui/session/session-flow/queue.mjs +1 -1
- package/src/tui/session/tool-approval.mjs +17 -8
- package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
- package/src/tui/session/tui-steering-persist.mjs +3 -5
- package/src/tui/session/turn-quiet.mjs +53 -0
- package/src/tui/session/turn-stream.mjs +5 -1
- package/src/tui/session/turn.mjs +38 -31
- package/src/tui/session/worktree-setup-notice.mjs +38 -0
- package/src/tui/spinner-meta.mjs +10 -0
- package/src/tui/spinner-verbs.mjs +3 -0
- package/src/ui/statusline.mjs +13 -3
- package/src/ui/streaming-markdown-heal.mjs +70 -18
- package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
- package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
- package/src/session-runtime/turn/share-ops.mjs +0 -77
- package/src/tui/session/cross-surface-share.mjs +0 -406
- package/src/tui/session/live-share/delta.mjs +0 -153
- package/src/tui/session/live-share/mirror.mjs +0 -106
- package/src/tui/session/live-share/owner.mjs +0 -254
- package/src/tui/session/live-share/retry.mjs +0 -54
- package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
- package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
- package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
- package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
- package/src/tui/session/live-share/viewer.mjs +0 -99
- package/src/tui/session/live-share/wire.mjs +0 -44
- package/src/tui/session/live-share.mjs +0 -154
- package/src/tui/session/shared-dir-watch.mjs +0 -69
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { readFileSync, readdirSync } from 'node:fs';
|
|
6
6
|
import { Worker } from 'node:worker_threads';
|
|
7
7
|
import { getPluginData } from '../../config.mjs';
|
|
8
|
-
import { getStoreDir } from './paths
|
|
8
|
+
import { getStoreDir } from './session-paths.mjs';
|
|
9
9
|
import { probePath, PROBE_PRESENT, PROBE_ABSENT } from './fs-probe.mjs';
|
|
10
10
|
import { isCancelledWrite as _isCancelledWrite } from './write-guards.mjs';
|
|
11
11
|
import {
|
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
import { _saveAsyncQueued, _saveWorkerPending } from './save-worker.mjs';
|
|
30
30
|
import { STORED_SESSION_UNREADABLE, _ensureLifecycleFields, _storedSessionFromFile } from './serialize.mjs';
|
|
31
31
|
import { _savePending } from './pending-saves.mjs';
|
|
32
|
-
import { isOrdinarySession } from '../store-summary-visibility.mjs';
|
|
33
32
|
import { closeSessionCatalogDb } from '../catalog-db/index.mjs';
|
|
34
33
|
|
|
35
34
|
// Disk mtime of the summary index when the in-memory cache was last refreshed
|
|
@@ -63,10 +62,7 @@ export function listStoredSessions(options = {}) {
|
|
|
63
62
|
options.includeLive === true
|
|
64
63
|
? _withUnpersistedSessions(stored, invalidStorageIds)
|
|
65
64
|
: stored.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
66
|
-
|
|
67
|
-
// uses the durable summary/worker indexes instead; callers that explicitly
|
|
68
|
-
// own an Agent surface can request the unfiltered internal rows.
|
|
69
|
-
return options.includeAgentOnly === true ? listed : listed.filter(isOrdinarySession);
|
|
65
|
+
return listed;
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
function _withUnpersistedSessions(stored, invalidStorageIds = new Set()) {
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from './live-state.mjs';
|
|
14
14
|
import { _summaryCacheVersions } from './summary-cache.mjs';
|
|
15
15
|
import { probePath, PROBE_PRESENT } from './fs-probe.mjs';
|
|
16
|
-
import { sessionPath } from './paths
|
|
16
|
+
import { sessionPath } from './session-paths.mjs';
|
|
17
17
|
import { _hasPendingPersistence } from './pending-saves.mjs';
|
|
18
18
|
import { forgetSessionLoadCache } from './load-cache.mjs';
|
|
19
19
|
|
|
@@ -1,53 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime-liveness
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Runtime-liveness veto for the destructive paths (close, delete): the
|
|
3
|
+
* caller-supplied `isSessionLive` probe over the daemon's in-memory runtime
|
|
4
|
+
* state, plus — for the sweep (`legacyOwnerVeto`) — the legacy `.hb` / `.own`
|
|
5
|
+
* markers an OLDER Mixdog process still running beside this one (mid-upgrade)
|
|
6
|
+
* keeps publishing. No current build writes those markers; they are only ever
|
|
7
|
+
* READ here, never refreshed.
|
|
5
8
|
*
|
|
6
9
|
* Separate from the write pipeline on purpose — a veto is a pure READ taken
|
|
7
10
|
* before any commit lock is held, and markSessionClosed / deleteSession must
|
|
8
|
-
* apply exactly the same
|
|
11
|
+
* apply exactly the same rule.
|
|
9
12
|
*/
|
|
10
|
-
import { existsSync, statSync } from 'node:fs';
|
|
11
13
|
import { join } from 'node:path';
|
|
12
|
-
import { getStoreDir
|
|
14
|
+
import { getStoreDir } from './session-paths.mjs';
|
|
15
|
+
import { probePath, readTextFile, PROBE_PRESENT } from './fs-probe.mjs';
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
export const LEGACY_MARKER_SUFFIXES = ['.hb', '.own'];
|
|
18
|
+
// An older live owner rewrote `.hb` every ≤5s mid-turn and `.own` every ~20s
|
|
19
|
+
// while holding the session open; one untouched this long holds nothing.
|
|
20
|
+
export const LEGACY_MARKER_FRESH_MS = 2 * 60 * 1000;
|
|
21
|
+
|
|
22
|
+
function processAlive(pid) {
|
|
15
23
|
try {
|
|
16
|
-
|
|
17
|
-
return
|
|
18
|
-
} catch {
|
|
19
|
-
|
|
24
|
+
process.kill(pid, 0);
|
|
25
|
+
return true;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
// ESRCH: no such process. EPERM means the pid exists.
|
|
28
|
+
return error?.code === 'EPERM';
|
|
20
29
|
}
|
|
21
30
|
}
|
|
22
31
|
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
/** A legacy marker's evidence, or null when it is not there to judge. The
|
|
33
|
+
* marker holds `<msTimestamp>\n<pid>\n`; a pid-less (pre-pid) marker names
|
|
34
|
+
* no owner, so it is neither live nor dead. */
|
|
35
|
+
export function readLegacyMarker(path, now = Date.now()) {
|
|
36
|
+
const probe = probePath(path);
|
|
37
|
+
if (probe.state !== PROBE_PRESENT) return null;
|
|
38
|
+
const read = readTextFile(path);
|
|
39
|
+
const pid = read.state === PROBE_PRESENT ? Number(read.text.split('\n')[1]) || 0 : 0;
|
|
40
|
+
const alive = pid > 0 && processAlive(pid);
|
|
41
|
+
return {
|
|
42
|
+
fresh: now - (probe.mtimeMs || 0) <= LEGACY_MARKER_FRESH_MS,
|
|
43
|
+
ownerAlive: alive,
|
|
44
|
+
ownerDead: pid > 0 && !alive,
|
|
45
|
+
};
|
|
35
46
|
}
|
|
36
47
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
/** Whether a legacy marker of the session names a live owner pid with a
|
|
49
|
+
* fresh heartbeat: that session is driven by another live process. */
|
|
50
|
+
export function _legacyOwnerLivenessVeto(id, now = Date.now()) {
|
|
51
|
+
if (typeof id !== 'string' || !/^[A-Za-z0-9_-]+$/.test(id)) return false;
|
|
52
|
+
const dir = getStoreDir();
|
|
53
|
+
return LEGACY_MARKER_SUFFIXES.some((suffix) => {
|
|
54
|
+
const marker = readLegacyMarker(join(dir, `${id}${suffix}`), now);
|
|
55
|
+
return Boolean(marker?.fresh && marker.ownerAlive);
|
|
56
|
+
});
|
|
45
57
|
}
|
|
46
58
|
|
|
47
|
-
export function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (!hasHeartbeatSnapshot || _heartbeatMtime(id) <= snapshotMtime) {
|
|
51
|
-
deleteHeartbeat(id);
|
|
52
|
-
}
|
|
59
|
+
export function _runtimeLivenessVeto(id, options = {}) {
|
|
60
|
+
if (typeof options.isSessionLive === 'function' && options.isSessionLive(id)) return true;
|
|
61
|
+
return options.legacyOwnerVeto === true && _legacyOwnerLivenessVeto(id);
|
|
53
62
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
readCanonicalSessionRecord,
|
|
9
9
|
acceptStrictSessionRecords,
|
|
10
10
|
} from './canonical-reader.mjs';
|
|
11
|
-
import { sessionPath } from './paths
|
|
11
|
+
import { sessionPath } from './session-paths.mjs';
|
|
12
12
|
import { noteMemoryRelease } from '../../../../shared/idle-gc.mjs';
|
|
13
13
|
|
|
14
14
|
// Recent full-session reads are much hotter than writes while a user hops
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* snapshot, or the evidence-backed failed-save snapshot. Nothing here writes;
|
|
5
5
|
* the precedence rules are the whole responsibility.
|
|
6
6
|
*/
|
|
7
|
-
import { sessionPath } from './paths
|
|
7
|
+
import { sessionPath } from './session-paths.mjs';
|
|
8
8
|
import { _savePending } from './pending-saves.mjs';
|
|
9
9
|
import { _liveSessions, _droppedSaveIds, getFailedSaveSnapshot } from './live-state.mjs';
|
|
10
10
|
import { _readStoredSessionCached } from './load-cache.mjs';
|
|
@@ -9,7 +9,7 @@ import { isAgentOwner } from '../../agent-owner.mjs';
|
|
|
9
9
|
import { listStoredAgentWorkerLinks } from '../store-agent-worker-rows.mjs';
|
|
10
10
|
import { listStoredSessionSummaries } from './listing.mjs';
|
|
11
11
|
import { STORED_SESSION_UNREADABLE, _storedSessionFromFile } from './serialize.mjs';
|
|
12
|
-
import { getStoreDir, sessionPath
|
|
12
|
+
import { getStoreDir, sessionPath } from './session-paths.mjs';
|
|
13
13
|
import {
|
|
14
14
|
readCanonicalSessionRecord as _readCanonicalRecord,
|
|
15
15
|
CANONICAL_RECORD_UNREADABLE as LIFECYCLE_AMBIGUOUS,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
import { purgeSessionSaveBookkeeping as _purgeSessionSaveBookkeeping } from './save-worker.mjs';
|
|
33
33
|
import { _uncacheSessionSummary, _queueSessionSummaryRemoval, _cachedSummaryRows } from './summary-cache.mjs';
|
|
34
34
|
import { _savePending, _clearDebounce, _releasePendingSlot } from './pending-saves.mjs';
|
|
35
|
-
import { _runtimeLivenessVeto
|
|
35
|
+
import { _runtimeLivenessVeto } from './liveness-veto.mjs';
|
|
36
36
|
import { _runSessionPurgeHooks } from './session-observers.mjs';
|
|
37
37
|
import { deleteCompactionArchive } from '../compaction-archive.mjs';
|
|
38
38
|
|
|
@@ -40,8 +40,8 @@ import { deleteCompactionArchive } from '../compaction-archive.mjs';
|
|
|
40
40
|
* metadata only (the summary rows and the agent-worker links — no folder
|
|
41
41
|
* scan); each candidate's own file is then read strictly and must still be an
|
|
42
42
|
* agent-owned record linked to this parent, so a stale/foreign metadata row
|
|
43
|
-
* can never name a deletion target.
|
|
44
|
-
*
|
|
43
|
+
* can never name a deletion target. Parent deletion no longer removes these
|
|
44
|
+
* children; they outlive the parent as independent sessions. */
|
|
45
45
|
export function listOwnedAgentSessionIds(ownerSessionId) {
|
|
46
46
|
const ownerId = String(ownerSessionId || '').trim();
|
|
47
47
|
if (!/^[A-Za-z0-9_-]+$/.test(ownerId)) return [];
|
|
@@ -78,14 +78,11 @@ function knownSessionCwds(id) {
|
|
|
78
78
|
export function deleteSession(id, options = {}) {
|
|
79
79
|
// Keep caller probes and all vetoes ahead of the non-reentrant lock and
|
|
80
80
|
// ahead of pending-save disruption, matching markSessionClosed().
|
|
81
|
-
if (_runtimeLivenessVeto(id, options)
|
|
81
|
+
if (_runtimeLivenessVeto(id, options)) return false;
|
|
82
82
|
const deleteGuard = _guardedSaveOptions(id);
|
|
83
83
|
const commitControl = _acquireWriteCommit(deleteGuard);
|
|
84
84
|
if (commitControl === false) return false;
|
|
85
85
|
try {
|
|
86
|
-
// Cross-process revival after full-TTL silence remains best-effort; the
|
|
87
|
-
// tombstone resurrection guard is authoritative. Only re-stat .hb here.
|
|
88
|
-
if (_heartbeatLivenessVeto(id, options)) return false;
|
|
89
86
|
// ── 1. unlink FIRST, still holding the commit lock ─────────────────────
|
|
90
87
|
// A failed unlink is NOT a delete: the canonical bytes are still there, so
|
|
91
88
|
// nothing may be purged, cancelled or closed — every pending write, parked
|
|
@@ -141,9 +138,6 @@ export function deleteSession(id, options = {}) {
|
|
|
141
138
|
_savePending.delete(id);
|
|
142
139
|
_purgeSessionSaveBookkeeping(id);
|
|
143
140
|
_runSessionPurgeHooks(id, { cwds: knownSessionCwds(id) });
|
|
144
|
-
// Preserve a sidecar published strictly after the sweep's scan snapshot.
|
|
145
|
-
_deleteHeartbeatUnlessNewer(id, options);
|
|
146
|
-
deleteSessionPresence(id);
|
|
147
141
|
// The display-only compaction archive has no meaning without its session.
|
|
148
142
|
deleteCompactionArchive(getStoreDir(), id);
|
|
149
143
|
_clearLiveSession(id);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { getPluginData } from '../../config.mjs';
|
|
4
|
+
|
|
5
|
+
// Session file paths are rebuilt on every load/save/sidecar probe. Memoize the
|
|
6
|
+
// joined strings per data dir: a changed data dir (MIXDOG_DATA_DIR switch)
|
|
7
|
+
// drops the whole memo, and the per-extension maps are bounded.
|
|
8
|
+
const SESSION_PATH_MEMO_LIMIT = 4096;
|
|
9
|
+
let _memoDataDir = null;
|
|
10
|
+
let _memoStoreDir = null;
|
|
11
|
+
const _memoFilePaths = new Map(); // extension → Map<id, path>
|
|
12
|
+
|
|
13
|
+
function _storeDirPath() {
|
|
14
|
+
const dataDir = getPluginData();
|
|
15
|
+
if (dataDir !== _memoDataDir) {
|
|
16
|
+
_memoDataDir = dataDir;
|
|
17
|
+
_memoStoreDir = join(dataDir, 'sessions');
|
|
18
|
+
_memoFilePaths.clear();
|
|
19
|
+
}
|
|
20
|
+
return _memoStoreDir;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function _memoFilePath(dir, id, extension) {
|
|
24
|
+
let byId = _memoFilePaths.get(extension);
|
|
25
|
+
if (!byId) {
|
|
26
|
+
byId = new Map();
|
|
27
|
+
_memoFilePaths.set(extension, byId);
|
|
28
|
+
}
|
|
29
|
+
let path = byId.get(id);
|
|
30
|
+
if (path === undefined) {
|
|
31
|
+
path = join(dir, _sessionFileName(id, extension));
|
|
32
|
+
if (byId.size >= SESSION_PATH_MEMO_LIMIT) byId.clear();
|
|
33
|
+
byId.set(id, path);
|
|
34
|
+
}
|
|
35
|
+
return path;
|
|
36
|
+
}
|
|
37
|
+
export function getStoreDir() {
|
|
38
|
+
const dir = _storeDirPath();
|
|
39
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
40
|
+
return dir;
|
|
41
|
+
}
|
|
42
|
+
function _sessionFileName(id, extension) {
|
|
43
|
+
return `${id}${extension}`;
|
|
44
|
+
}
|
|
45
|
+
// Enforce minted session-id shape before using it in a path to prevent
|
|
46
|
+
// `../` traversal. session IDs are generated by createSession as
|
|
47
|
+
// `sess_<timestamp>_<hex>` — reject anything that doesn't match.
|
|
48
|
+
function _assertSessionId(id) {
|
|
49
|
+
if (!id || typeof id !== 'string' || !/^[A-Za-z0-9_-]+$/.test(id)) {
|
|
50
|
+
throw new Error(`[session-store] invalid session id: ${JSON.stringify(id)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function _sessionFilePath(id, extension) {
|
|
54
|
+
_assertSessionId(id);
|
|
55
|
+
return _memoFilePath(getStoreDir(), id, extension);
|
|
56
|
+
}
|
|
57
|
+
export function sessionPath(id) {
|
|
58
|
+
return _sessionFilePath(id, '.json');
|
|
59
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readdirSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { getPluginData } from '../../config.mjs';
|
|
4
|
-
import { getStoreDir } from './paths
|
|
4
|
+
import { getStoreDir } from './session-paths.mjs';
|
|
5
5
|
import { probePath, PROBE_PRESENT, PROBE_ABSENT } from './fs-probe.mjs';
|
|
6
6
|
import { STORED_SESSION_UNREADABLE, _storedSessionFromFile } from './serialize.mjs';
|
|
7
7
|
import {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// sidecars. The generator yields between records so cooperative hosts never
|
|
5
5
|
// hold the event loop for a whole directory scan; the synchronous wrapper
|
|
6
6
|
// drains it in one go.
|
|
7
|
-
import { getStoreDir } from '../paths
|
|
7
|
+
import { getStoreDir } from '../session-paths.mjs';
|
|
8
8
|
import { probePath, PROBE_PRESENT } from '../fs-probe.mjs';
|
|
9
9
|
import { persistSweepRecordCache, pruneSweepRecordCache } from './sweep-record.mjs';
|
|
10
10
|
import { collectSweepRows, createSweepTally, resolveSweepPlan } from './sweep-plan.mjs';
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
// sweep/sweep-finish.mjs
|
|
2
2
|
// What runs after every row has its verdict: the resumable-open retention
|
|
3
|
-
// cap, the orphan sidecar reap, and the one batched summary-index prune.
|
|
3
|
+
// cap, the legacy/orphan sidecar reap, and the one batched summary-index prune.
|
|
4
4
|
import { readdirSync, unlinkSync } from 'node:fs';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { probePath, PROBE_PRESENT, PROBE_ABSENT } from '../fs-probe.mjs';
|
|
7
7
|
import { _queueSummaryIndexPrune } from '../summary-cache.mjs';
|
|
8
8
|
import { deleteSession } from '../session-delete.mjs';
|
|
9
9
|
import { COMPACTION_ARCHIVE_SUFFIX } from '../../compaction-archive.mjs';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
// A live presence owner rewrites `.own` every ~20s; one untouched for the
|
|
13
|
-
// attach guard's whole freshness window holds nothing open.
|
|
14
|
-
const PRESENCE_ORPHAN_AGE_MS = 2 * 60 * 1000;
|
|
10
|
+
import { LEGACY_MARKER_SUFFIXES, readLegacyMarker } from '../liveness-veto.mjs';
|
|
15
11
|
|
|
16
12
|
/** Retention cap: prune resumable open (non-tombstone) sessions newest-first
|
|
17
13
|
* — keep the most recent openMaxCount, prune anything older than openMaxAgeMs
|
|
@@ -37,8 +33,7 @@ export function pruneOpenCandidates({ plan, now, tally }) {
|
|
|
37
33
|
deleteSession(c.id, {
|
|
38
34
|
deferSummaryUpdate: true,
|
|
39
35
|
isSessionLive: plan.isSessionLive,
|
|
40
|
-
|
|
41
|
-
heartbeatFreshMs: c.heartbeatFreshMs,
|
|
36
|
+
legacyOwnerVeto: true,
|
|
42
37
|
})
|
|
43
38
|
) {
|
|
44
39
|
tally.openPruned++;
|
|
@@ -53,40 +48,40 @@ export function pruneOpenCandidates({ plan, now, tally }) {
|
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
50
|
|
|
56
|
-
/**
|
|
51
|
+
/** Legacy `.hb` heartbeat and `.own` presence sidecars are written by no
|
|
52
|
+
* current build, but an older Mixdog process still running mid-upgrade keeps
|
|
53
|
+
* publishing them. One is reaped only once it holds nothing: its recorded
|
|
54
|
+
* owner pid is dead or it went stale; a fresh marker of a live (or
|
|
55
|
+
* unrecorded) owner is kept. Orphan compaction-archive reap: an archive whose .json no longer
|
|
57
56
|
* exists is dead weight once it is also stale (older than maxAge) — the
|
|
58
|
-
* session JSON was swept/closed but the
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* like the row loop. */
|
|
57
|
+
* session JSON was swept/closed but the archive lingered. The staleness gate
|
|
58
|
+
* avoids nuking the archive of a session mid-create whose .json write has not
|
|
59
|
+
* landed yet. Yields between sidecars like the row loop. */
|
|
62
60
|
export function* reapOrphanSidecars({ plan, dir, now, tally }) {
|
|
63
|
-
const recordOf = (sidecar) =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
const recordOf = (sidecar) => `${sidecar.slice(0, -COMPACTION_ARCHIVE_SUFFIX.length)}.json`;
|
|
62
|
+
const unlinkSidecar = (h) => {
|
|
63
|
+
try {
|
|
64
|
+
unlinkSync(join(dir, h));
|
|
65
|
+
tally.cleaned++;
|
|
66
|
+
} catch {
|
|
67
|
+
/* ignore */
|
|
68
|
+
}
|
|
69
|
+
};
|
|
67
70
|
try {
|
|
68
71
|
for (const h of readdirSync(dir).filter(
|
|
69
72
|
(f) => f.endsWith('.hb') || f.endsWith('.own') || f.endsWith(COMPACTION_ARCHIVE_SUFFIX)
|
|
70
73
|
)) {
|
|
71
74
|
yield undefined;
|
|
72
|
-
|
|
75
|
+
if (LEGACY_MARKER_SUFFIXES.some((suffix) => h.endsWith(suffix))) {
|
|
76
|
+
const marker = readLegacyMarker(join(dir, h), now);
|
|
77
|
+
if (marker && (marker.ownerDead || !marker.fresh)) unlinkSidecar(h);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// Only a PROVEN-absent session file makes its archive an orphan.
|
|
73
81
|
if (probePath(join(dir, recordOf(h))).state !== PROBE_ABSENT) continue;
|
|
74
82
|
const sidecarProbe = probePath(join(dir, h));
|
|
75
83
|
if (sidecarProbe.state !== PROBE_PRESENT) continue;
|
|
76
|
-
|
|
77
|
-
// so one without a record whose recorded owner is dead (or which no
|
|
78
|
-
// live owner refreshed within the presence window) is a leftover of a
|
|
79
|
-
// deleted session, not a session mid-create.
|
|
80
|
-
const orphanPresence =
|
|
81
|
-
h.endsWith('.own') && (now - sidecarProbe.mtimeMs > PRESENCE_ORPHAN_AGE_MS || isSidecarOwnerDead(join(dir, h)));
|
|
82
|
-
if (orphanPresence || now - sidecarProbe.mtimeMs > plan.maxAge) {
|
|
83
|
-
try {
|
|
84
|
-
unlinkSync(join(dir, h));
|
|
85
|
-
tally.cleaned++;
|
|
86
|
-
} catch {
|
|
87
|
-
/* ignore */
|
|
88
|
-
}
|
|
89
|
-
}
|
|
84
|
+
if (now - sidecarProbe.mtimeMs > plan.maxAge) unlinkSidecar(h);
|
|
90
85
|
}
|
|
91
86
|
} catch {
|
|
92
87
|
/* dir scan failure — non-fatal */
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// One sweep's resolved options (what to sweep and with which bounds), the
|
|
3
3
|
// candidate rows it visits, and the tally it fills in.
|
|
4
4
|
import { readdirSync } from 'node:fs';
|
|
5
|
-
import { loadConfig } from '../../../config.mjs';
|
|
6
5
|
import { listStoredSessionSummaries } from '../listing.mjs';
|
|
7
6
|
import { DEFAULT_SESSION_TTL_MS, RESUMABLE_OPEN_MAX_AGE_MS, RESUMABLE_OPEN_MAX_COUNT } from './sweep-record.mjs';
|
|
8
7
|
|
|
@@ -11,12 +10,6 @@ export function resolveSweepPlan(ttlMs, options = {}) {
|
|
|
11
10
|
options = ttlMs;
|
|
12
11
|
ttlMs = options.ttlMs;
|
|
13
12
|
}
|
|
14
|
-
let terminalReapConfig = null;
|
|
15
|
-
try {
|
|
16
|
-
terminalReapConfig = loadConfig({ secrets: false });
|
|
17
|
-
} catch {
|
|
18
|
-
/* built-ins remain available */
|
|
19
|
-
}
|
|
20
13
|
const sweepIdle = options.sweepIdle !== false;
|
|
21
14
|
const tombstoneMaxAgeMs = Number(options.tombstoneMaxAgeMs);
|
|
22
15
|
const optAge = Number(options.openMaxAgeMs);
|
|
@@ -24,7 +17,6 @@ export function resolveSweepPlan(ttlMs, options = {}) {
|
|
|
24
17
|
return {
|
|
25
18
|
maxAge: ttlMs || DEFAULT_SESSION_TTL_MS,
|
|
26
19
|
sweepIdle,
|
|
27
|
-
terminalReapConfig,
|
|
28
20
|
tombstoneMaxAgeMs,
|
|
29
21
|
sweepTombstones: Number.isFinite(tombstoneMaxAgeMs) && tombstoneMaxAgeMs > 0,
|
|
30
22
|
// Retention cap for resumable open sessions runs only on the idle sweep
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
// sweep/sweep-record.mjs
|
|
2
2
|
// What the stale-session sweep reads per record and the bounds it decides
|
|
3
|
-
// with: the fingerprint-cached lifecycle record
|
|
4
|
-
//
|
|
3
|
+
// with: the fingerprint-cached lifecycle record and the
|
|
4
|
+
// idle / retention / blank-scratch thresholds.
|
|
5
5
|
import { readFileSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { writeJsonAtomicSync } from '../../../../../shared/atomic-file.mjs';
|
|
8
8
|
import { getPluginData } from '../../../config.mjs';
|
|
9
|
-
import { isAgentOwner } from '../../../agent-owner.mjs';
|
|
10
9
|
import { readTopLevelLifecycleRecord, isLifecycleUnreadable } from '../../lifecycle-scan.mjs';
|
|
11
|
-
import { sessionPath } from '../paths-heartbeat.mjs';
|
|
12
|
-
import { probePath, PROBE_ABSENT } from '../fs-probe.mjs';
|
|
13
10
|
|
|
14
11
|
export const DEFAULT_SESSION_TTL_MS = 5 * 60 * 1000; // 5 minutes idle — aligned with Anthropic 5m messages tier and OpenAI in-memory cache window
|
|
15
|
-
export const AGENT_TERMINAL_STATUSES = new Set(['idle', 'done', 'error']);
|
|
16
12
|
// Hard wall-clock ceiling for sessions stuck in status='running'. The
|
|
17
13
|
// stream-watchdog should abort stalled streams within ~120s, but if it misses
|
|
18
14
|
// one (process crash, watchdog not started, provider never returned), this
|
|
@@ -52,7 +48,7 @@ export const BLANK_SCRATCH_MAX_AGE_MS = 60 * 60 * 1000; // 1h
|
|
|
52
48
|
// running is still parsed again.
|
|
53
49
|
const sweepRecordCache = new Map();
|
|
54
50
|
const SWEEP_RECORD_CACHE_FILE = 'session-sweep-records.json';
|
|
55
|
-
const SWEEP_RECORD_CACHE_VERSION =
|
|
51
|
+
const SWEEP_RECORD_CACHE_VERSION = 2;
|
|
56
52
|
let sweepRecordCacheDataDir = null;
|
|
57
53
|
let sweepRecordCacheDirty = false;
|
|
58
54
|
let sweepRecordParses = 0;
|
|
@@ -86,11 +82,13 @@ function syncSweepRecordCache() {
|
|
|
86
82
|
}
|
|
87
83
|
|
|
88
84
|
// The only document fields sweep-row reads (effectiveFields, the closed
|
|
89
|
-
// check
|
|
85
|
+
// check). Caching the whole top-level document kept
|
|
90
86
|
// every session's tool catalogs, schemas and provider state alive — one
|
|
91
87
|
// entry per session file, measured at ~290MB of a 470MB daemon heap.
|
|
92
88
|
const SWEEP_DOC_FIELDS = [
|
|
93
89
|
'id',
|
|
90
|
+
'closed',
|
|
91
|
+
'closedReason',
|
|
94
92
|
'owner',
|
|
95
93
|
'status',
|
|
96
94
|
'provider',
|
|
@@ -172,13 +170,3 @@ export function sweepRecordCacheStats() {
|
|
|
172
170
|
syncSweepRecordCache();
|
|
173
171
|
return { entries: sweepRecordCache.size, parses: sweepRecordParses };
|
|
174
172
|
}
|
|
175
|
-
|
|
176
|
-
/** Child-agent transcripts share their visible parent's retention boundary.
|
|
177
|
-
* Presence (including a tombstone or unreadable file) preserves the child;
|
|
178
|
-
* only proven parent absence releases it to ordinary cleanup. */
|
|
179
|
-
export function retainedLinkedAgent(session) {
|
|
180
|
-
if (!session || !isAgentOwner(session)) return false;
|
|
181
|
-
const parentId = String(session.ownerSessionId || session.parentSessionId || '').trim();
|
|
182
|
-
if (!/^[A-Za-z0-9_-]+$/.test(parentId) || parentId === session.id) return false;
|
|
183
|
-
return probePath(sessionPath(parentId)).state !== PROBE_ABSENT;
|
|
184
|
-
}
|