mixdog 1.4.1 → 1.4.3
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 +4 -3
- package/scripts/build-shipped-history.mjs +125 -33
- package/scripts/gate-local.mjs +220 -63
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +139 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +71 -34
- package/scripts/lib/scoped-temp.mjs +1 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +9 -4
- package/scripts/lib/test-spawn-ledger.mjs +43 -3
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/pptx-kit-index.mjs +5 -6
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/scripts/suite-health.mjs +110 -28
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +38 -2
- package/src/defaults/skills/browser-use/SKILL.md +4 -1
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +12 -2
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +28 -9
- package/src/defaults/skills/setup/references/surfaces.md +5 -2
- package/src/defaults/skills/setup-guide/SKILL.md +11 -3
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +40 -50
- package/src/orchestration/balanced.md +23 -0
- package/src/orchestration/focused.md +22 -0
- package/src/orchestration/none.md +5 -0
- package/src/orchestration/swarm.md +24 -0
- package/src/rules/agent-mode/AGENT_MODE.md +3 -1
- package/src/rules/agent-mode/MIXY.md +2 -2
- package/src/rules/lead/LEAD.md +3 -3
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +4 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
- package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
- package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
- package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
- package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
- package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/attachment-reference.mjs +1 -1
- package/src/runtime/attachments/pdf-extract.mjs +1 -1
- package/src/runtime/attachments/store.d.mts +1 -0
- package/src/runtime/attachments/store.mjs +2 -2
- package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
- package/src/runtime/channels/lib/scheduler.mjs +33 -0
- package/src/runtime/channels/lib/schedules-db.mjs +11 -4
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
- package/src/runtime/channels/lib/whisper-port.mjs +19 -10
- package/src/runtime/channels/lib/whisper-server.mjs +22 -13
- package/src/runtime/channels/lib/worker-main.mjs +9 -31
- package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
- package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
- package/src/runtime/connectors/gmail-app-password.mjs +4 -4
- package/src/runtime/connectors/google-mcp.mjs +1 -1
- package/src/runtime/effort-judge/judge-client.mjs +2 -2
- package/src/runtime/effort-judge/judge-input.mjs +4 -4
- package/src/runtime/explore/explorer.mjs +88 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/hardware.mjs +1 -1
- package/src/runtime/media/adapters/codex-image.mjs +3 -3
- package/src/runtime/media/adapters/gemini-video.mjs +1 -1
- package/src/runtime/media/media-usage.mjs +1 -1
- package/src/runtime/media/store.mjs +1 -1
- package/src/runtime/memory/index.mjs +15 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
- package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
- package/src/runtime/memory/lib/memory-embed.mjs +83 -14
- package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
- package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
- package/src/runtime/memory/lib/memory.mjs +17 -0
- package/src/runtime/memory/lib/pg/process.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
- package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/capabilities.mjs +1 -1
- package/src/runtime/office/core/office-core.mjs +1 -1
- package/src/runtime/office/design/content-model.mjs +3 -3
- package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
- package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
- package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
- package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
- package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +8 -6
- package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
- package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +37 -10
- package/src/runtime/shared/background-wait.mjs +66 -0
- package/src/runtime/shared/child-guardian.mjs +17 -7
- package/src/runtime/shared/config.mjs +313 -16
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +14 -8
- package/src/runtime/shared/connector-catalog.mjs +70 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +21 -18
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/cost.mjs +6 -1
- package/src/runtime/shared/llm/http-agent.mjs +316 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +453 -0
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
- package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
- package/src/runtime/shared/maintenance-schedule.mjs +109 -0
- package/src/runtime/shared/process-runner.mjs +8 -4
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/routine-trigger.d.mts +13 -0
- package/src/runtime/shared/routine-trigger.mjs +34 -0
- package/src/runtime/shared/run-child.d.mts +2 -1
- package/src/runtime/shared/run-child.mjs +70 -18
- package/src/runtime/shared/session-scratch.mjs +14 -2
- package/src/runtime/shared/shipped-definitions.mjs +7 -1
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-surface.mjs +110 -36
- package/src/runtime/shared/tool-work-units.mjs +35 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
- package/src/runtime/shared/worker-requests.mjs +17 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
- package/src/runtime/shared/worktrees/contract.mjs +16 -6
- package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
- package/src/runtime/shared/worktrees/disk.mjs +79 -2
- package/src/runtime/shared/worktrees/git.mjs +97 -7
- package/src/runtime/shared/worktrees/include.mjs +6 -4
- package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
- package/src/runtime/shared/worktrees/manager.mjs +962 -197
- package/src/runtime/shared/worktrees/settings.mjs +33 -7
- package/src/runtime/shared/worktrees/test-support.mjs +5 -1
- package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +9 -5
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +4 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +4 -23
- package/src/runtime/web-search/lib/web-tools.mjs +2 -2
- package/src/runtime/web-search/tool-defs.mjs +17 -26
- package/src/session-runtime/agent-profile-changes.mjs +55 -4
- package/src/session-runtime/agent-task-sessions.mjs +410 -353
- package/src/session-runtime/boot/apis.mjs +27 -4
- package/src/session-runtime/boot/begin.mjs +2 -0
- package/src/session-runtime/boot/config.mjs +10 -1
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/providers.mjs +70 -3
- package/src/session-runtime/boot/session.mjs +2 -0
- package/src/session-runtime/boot/tools.mjs +71 -25
- package/src/session-runtime/bot-status.mjs +103 -103
- package/src/session-runtime/channel-config-api.mjs +1 -0
- package/src/session-runtime/config-change-effects.mjs +179 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
- package/src/session-runtime/config-lifecycle.mjs +160 -24
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/discovery.mjs +245 -47
- package/src/session-runtime/conversation-import/service.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- package/src/session-runtime/handoff-attachments.mjs +1 -1
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
- package/src/session-runtime/internal-tool-executor.mjs +12 -19
- package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
- package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
- package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +40 -7
- package/src/session-runtime/native-web-search/routes.mjs +3 -3
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-auth/refresh.mjs +6 -3
- package/src/session-runtime/provider-auth/setup.mjs +1 -1
- package/src/session-runtime/provider-readiness.mjs +53 -4
- package/src/session-runtime/resource-api.mjs +1 -1
- package/src/session-runtime/resource-extension-sync.mjs +4 -8
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
- package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-plugins-api.mjs +4 -0
- package/src/session-runtime/routine-executor.mjs +152 -0
- package/src/session-runtime/routine-home-turn.mjs +46 -5
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-feature-gates.mjs +2 -11
- package/src/session-runtime/schedule-session-run.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +14 -6
- package/src/session-runtime/services/provider-admin.mjs +281 -10
- package/src/session-runtime/services/seeds.mjs +7 -0
- package/src/session-runtime/services/usage-stats-model.mjs +32 -11
- package/src/session-runtime/session-create/materialize.mjs +4 -2
- package/src/session-runtime/session-create/session-options.mjs +2 -0
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +14 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
- package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
- package/src/session-runtime/tool-policy-refresh.mjs +182 -5
- package/src/session-runtime/tool-surface.mjs +38 -1
- package/src/session-runtime/turn/agent-ops.mjs +33 -2
- package/src/session-runtime/turn/session-ops.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
- package/src/session-runtime/turn/turn-run.mjs +1 -1
- package/src/session-runtime/webhook-session-run.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
- package/src/session-runtime/workflow-agents-api.mjs +2 -0
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/project-branches.mjs +1 -1
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +128 -1070
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +8 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon-session-control.mjs +151 -136
- package/src/standalone/daemon.mjs +61 -2
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +21 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +15 -0
- package/src/standalone/session-service/agent-route-follow.mjs +23 -20
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/quota-resume.mjs +9 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
- package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/tui/App.jsx +162 -164
- package/src/tui/app/app-view/floating-panel.jsx +3 -0
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +22 -11
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/doctor.mjs +2 -2
- package/src/tui/app/panel-signature.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
- package/src/tui/app/provider-setup-picker.mjs +20 -13
- package/src/tui/app/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
- package/src/tui/app/slash-commands.mjs +2 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +5 -4
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +48 -33
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
- package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
- package/src/tui/components/question-panel-model.mjs +4 -4
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/components/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +2205 -1371
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
- package/src/tui/session/agent-job-feed.mjs +2 -0
- package/src/tui/session/context-state.mjs +3 -0
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/quota-resume.mjs +1 -1
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-api/worktree.mjs +13 -1
- package/src/tui/session/session-flow/drain.mjs +11 -14
- package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/tui/session/turn-quiet.mjs +1 -1
- package/src/tui/session/turn.mjs +3 -0
- package/src/tui/session/worktree-setup-notice.mjs +1 -1
- package/src/tui/spinner-meta.mjs +3 -3
- package/src/tui/spinner-verbs.mjs +2 -2
- package/src/defaults/skills/goal-management/SKILL.md +0 -169
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
- package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// Process lock for the standalone memory MCP entry.
|
|
2
2
|
// A direct entry (including the isolated daemon child) owns this lock.
|
|
3
3
|
import fs from 'node:fs';
|
|
4
|
-
import {
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { killProcessTreesSync } from '../../agent/orchestrator/mcp/child-tree.mjs';
|
|
6
|
+
|
|
7
|
+
// Windows: the tree kill's whole pass (a table read under load included).
|
|
8
|
+
const PREVIOUS_SERVER_KILL_TIMEOUT_MS = 10_000;
|
|
5
9
|
|
|
6
10
|
export function parsePositivePid(value) {
|
|
7
11
|
const pid = Number(value);
|
|
@@ -18,42 +22,158 @@ export function isPidAliveLocal(pid) {
|
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
const POSIX_ENV = () => ({ ...process.env, LC_ALL: 'C', LANG: 'C' });
|
|
26
|
+
|
|
27
|
+
// When a process was created, as epoch-ms bounds { low, high } around the true
|
|
28
|
+
// time, or null when it cannot be read. Linux: /proc/<pid>/stat starttime
|
|
29
|
+
// (clock ticks since boot) against /proc/uptime, both read at `now`; the
|
|
30
|
+
// margin covers one tick, uptime's centiseconds and the read skew.
|
|
31
|
+
export function linuxCreatedBounds(statText, uptimeText, clockTicks, now) {
|
|
32
|
+
const ticks = linuxStartTicks(statText);
|
|
33
|
+
const startTicks = Number(ticks);
|
|
34
|
+
const uptime = Number(String(uptimeText || '').split(' ')[0]);
|
|
35
|
+
if (ticks === null || !Number.isFinite(uptime) || !(clockTicks > 0)) return null;
|
|
36
|
+
const created = now - (uptime - startTicks / clockTicks) * 1000;
|
|
37
|
+
const margin = 1000 / clockTicks + 20;
|
|
38
|
+
return { low: created - margin, high: created + margin };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Elsewhere: `ps -o lstart=` under the C locale, whole seconds.
|
|
42
|
+
export function lstartCreatedBounds(text) {
|
|
43
|
+
const started = Date.parse(String(text || '').trim());
|
|
44
|
+
return Number.isFinite(started) ? { low: started, high: started + 1000 } : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// /proc/<pid>/stat's starttime field (clock ticks since boot), as its digits.
|
|
48
|
+
function linuxStartTicks(statText) {
|
|
49
|
+
const stat = String(statText || '');
|
|
50
|
+
if (!stat.includes(')')) return null;
|
|
51
|
+
const ticks = stat.slice(stat.lastIndexOf(')') + 2).split(' ')[19];
|
|
52
|
+
return /^\d+$/.test(ticks || '') ? ticks : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** A process's start token, as recorded in the lock and compared on
|
|
56
|
+
* recovery, or null when it cannot be read: Linux `/proc/<pid>/stat`
|
|
57
|
+
* starttime, elsewhere `ps -o lstart=` under the C locale. The two sources
|
|
58
|
+
* never mix (each is prefixed), and both are read from the same host. */
|
|
59
|
+
export function linuxStartToken(statText) {
|
|
60
|
+
const ticks = linuxStartTicks(statText);
|
|
61
|
+
return ticks ? `proc:${ticks}` : null;
|
|
62
|
+
}
|
|
63
|
+
export function lstartStartToken(text) {
|
|
64
|
+
const started = String(text || '').trim();
|
|
65
|
+
return Number.isFinite(Date.parse(started)) ? `lstart:${started}` : null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function posixStartToken(pid) {
|
|
69
|
+
try {
|
|
70
|
+
if (process.platform === 'linux') return linuxStartToken(fs.readFileSync(`/proc/${pid}/stat`, 'utf8'));
|
|
71
|
+
const r = spawnSync('ps', ['-o', 'lstart=', '-p', String(pid)], {
|
|
72
|
+
encoding: 'utf8',
|
|
73
|
+
env: POSIX_ENV(),
|
|
74
|
+
timeout: 5000,
|
|
75
|
+
});
|
|
76
|
+
return lstartStartToken(r.stdout);
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function posixCreatedBounds(pid) {
|
|
83
|
+
const env = POSIX_ENV();
|
|
84
|
+
try {
|
|
85
|
+
if (process.platform === 'linux') {
|
|
86
|
+
const ticks = Number(spawnSync('getconf', ['CLK_TCK'], { encoding: 'utf8', env, timeout: 5000 }).stdout);
|
|
87
|
+
const now = Date.now();
|
|
88
|
+
return linuxCreatedBounds(
|
|
89
|
+
fs.readFileSync(`/proc/${pid}/stat`, 'utf8'),
|
|
90
|
+
fs.readFileSync('/proc/uptime', 'utf8'),
|
|
91
|
+
ticks,
|
|
92
|
+
now
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
const r = spawnSync('ps', ['-o', 'lstart=', '-p', String(pid)], { encoding: 'utf8', env, timeout: 5000 });
|
|
96
|
+
return lstartCreatedBounds(r.stdout);
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Who holds a lock's pid, from the start token the writer recorded and the
|
|
103
|
+
* pid's current one: 'writer' (the same token: the server that wrote the
|
|
104
|
+
* lock), 'other' (a different one: the writer is gone and its pid reused) or
|
|
105
|
+
* 'unproven' (the current token cannot be read). */
|
|
106
|
+
export function lockHolderTokenVerdict(recordedToken, currentToken) {
|
|
107
|
+
if (!currentToken) return 'unproven';
|
|
108
|
+
return currentToken === recordedToken ? 'writer' : 'other';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** The legacy verdict, for a lock written without a start token: from the
|
|
112
|
+
* holder's creation bounds, 'writer' (created before the lock was written),
|
|
113
|
+
* 'other' (created after) or 'unproven' (unreadable, or too close to the
|
|
114
|
+
* write to tell). Only 'writer' may be signalled, and only 'other' or a dead
|
|
115
|
+
* pid lets the lock be recovered. */
|
|
116
|
+
export function lockHolderVerdict(bounds, lockWrittenAt) {
|
|
117
|
+
if (!bounds) return 'unproven';
|
|
118
|
+
if (bounds.high <= lockWrittenAt) return 'writer';
|
|
119
|
+
if (bounds.low > lockWrittenAt) return 'other';
|
|
120
|
+
return 'unproven';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The lock's text: the writer's pid, then (POSIX) its start token on the
|
|
124
|
+
* next line. */
|
|
125
|
+
export function formatLock(pid, token) {
|
|
126
|
+
return token ? `${pid}\n${token}` : String(pid);
|
|
127
|
+
}
|
|
128
|
+
export function parseLock(text) {
|
|
129
|
+
const [pidLine = '', token = ''] = String(text || '').split(/\r?\n/);
|
|
130
|
+
return { pid: Number(pidLine.trim()), token: token.trim() || null };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The lock names its writer only while that writer lives. A POSIX writer
|
|
134
|
+
// recorded its start token; the pid's holder is the writer exactly when its
|
|
135
|
+
// token is still the same. Accepted: lstart has whole seconds, so a writer
|
|
136
|
+
// that died within its first second, its pid reused in that same second,
|
|
137
|
+
// would pass as the writer; sequential pid allocation makes that impractical,
|
|
138
|
+
// and treating same-second tokens as unproven would block every restart.
|
|
139
|
+
// Windows compares the holder's creation time against
|
|
140
|
+
// the lock's write time inside the shared tree kill: its creation times are
|
|
141
|
+
// sub-millisecond, and a pid is only reused after the writer died, after the
|
|
142
|
+
// write. A lock without a token (an older writer) keeps the creation-bounds
|
|
143
|
+
// verdict. A pid taken over since is never signalled; one whose identity
|
|
144
|
+
// cannot be proven is neither signalled nor evicted (fail closed).
|
|
145
|
+
function killPreviousServer(pid, recordedToken, lockWrittenAt, log = () => {}) {
|
|
22
146
|
if (pid <= 0 || pid === process.pid) return false;
|
|
23
147
|
if (process.platform === 'win32') {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
148
|
+
const status = killProcessTreesSync([pid], {
|
|
149
|
+
aliveAt: lockWrittenAt,
|
|
150
|
+
timeoutMs: PREVIOUS_SERVER_KILL_TIMEOUT_MS,
|
|
151
|
+
});
|
|
152
|
+
if (status === 0) {
|
|
30
153
|
log(`[memory-service] Killed previous server PID ${pid}\n`);
|
|
31
154
|
return true;
|
|
32
|
-
} catch (e) {
|
|
33
|
-
// Exit code 128 = process not found; treat stale lock as already-dead = success.
|
|
34
|
-
// Status 128 reliably means "process not found" regardless of locale; no text match needed.
|
|
35
|
-
// Status 1 with English text match handles edge cases on some Windows versions.
|
|
36
|
-
const notFoundText =
|
|
37
|
-
/not found|no running instance/i.test(e.stdout || '') ||
|
|
38
|
-
/not found|no running instance/i.test(e.stderr || '') ||
|
|
39
|
-
/not found|no running instance/i.test(e.message || '');
|
|
40
|
-
const alreadyDead = e.status === 128 || (e.status === 1 && notFoundText);
|
|
41
|
-
if (alreadyDead) {
|
|
42
|
-
log(`[memory-service] PID ${pid} already dead (stale lock), proceeding\n`);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
log(`[memory-service] taskkill failed for PID ${pid}: ${e.message}\n`);
|
|
46
|
-
return false;
|
|
47
155
|
}
|
|
156
|
+
if (status === 128) {
|
|
157
|
+
log(`[memory-service] PID ${pid} is not the lock's writer any more (stale lock), proceeding\n`);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
log(`[memory-service] Killing previous server PID ${pid} failed (status ${status})\n`);
|
|
161
|
+
return false;
|
|
48
162
|
} else {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
163
|
+
const verdict = !isPidAliveLocal(pid)
|
|
164
|
+
? 'gone'
|
|
165
|
+
: recordedToken
|
|
166
|
+
? lockHolderTokenVerdict(recordedToken, posixStartToken(pid))
|
|
167
|
+
: lockHolderVerdict(posixCreatedBounds(pid), lockWrittenAt);
|
|
168
|
+
if (verdict === 'gone' || verdict === 'other' || (verdict === 'unproven' && !isPidAliveLocal(pid))) {
|
|
169
|
+
log(`[memory-service] PID ${pid} is not the lock's writer any more (stale lock), proceeding\n`);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
if (verdict === 'unproven') {
|
|
173
|
+
log(
|
|
174
|
+
`[memory-service] PID ${pid} may still be the lock's writer and cannot be proven otherwise; leaving it running\n`
|
|
175
|
+
);
|
|
176
|
+
return false;
|
|
57
177
|
}
|
|
58
178
|
try {
|
|
59
179
|
process.kill(pid, 'SIGTERM');
|
|
@@ -86,9 +206,10 @@ export function acquireLock(lockFile, log = () => {}) {
|
|
|
86
206
|
if (process.env.MIXDOG_MULTI_INSTANCE === '1') return;
|
|
87
207
|
try {
|
|
88
208
|
if (fs.existsSync(lockFile)) {
|
|
89
|
-
const
|
|
209
|
+
const lockWrittenAt = fs.statSync(lockFile).mtimeMs;
|
|
210
|
+
const { pid: lockedPid, token } = parseLock(fs.readFileSync(lockFile, 'utf8'));
|
|
90
211
|
if (lockedPid > 0 && lockedPid !== process.pid) {
|
|
91
|
-
const killed = killPreviousServer(lockedPid, log);
|
|
212
|
+
const killed = killPreviousServer(lockedPid, token, lockWrittenAt, log);
|
|
92
213
|
if (!killed) {
|
|
93
214
|
log(`[memory-service] Could not kill previous server PID ${lockedPid}, aborting\n`);
|
|
94
215
|
process.exit(1);
|
|
@@ -98,9 +219,12 @@ export function acquireLock(lockFile, log = () => {}) {
|
|
|
98
219
|
} catch {}
|
|
99
220
|
}
|
|
100
221
|
}
|
|
222
|
+
// Read before the lock exists: an unreadable token leaves a pid-only lock,
|
|
223
|
+
// which a successor judges by the legacy verdict.
|
|
224
|
+
const token = process.platform === 'win32' ? null : posixStartToken(process.pid);
|
|
101
225
|
const fd = fs.openSync(lockFile, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL, 0o600);
|
|
102
226
|
try {
|
|
103
|
-
fs.writeSync(fd,
|
|
227
|
+
fs.writeSync(fd, formatLock(process.pid, token));
|
|
104
228
|
} finally {
|
|
105
229
|
fs.closeSync(fd);
|
|
106
230
|
}
|
|
@@ -116,7 +240,6 @@ export function acquireLock(lockFile, log = () => {}) {
|
|
|
116
240
|
|
|
117
241
|
export function releaseLock(lockFile) {
|
|
118
242
|
try {
|
|
119
|
-
|
|
120
|
-
if (Number(content) === process.pid) fs.unlinkSync(lockFile);
|
|
243
|
+
if (parseLock(fs.readFileSync(lockFile, 'utf8')).pid === process.pid) fs.unlinkSync(lockFile);
|
|
121
244
|
} catch {}
|
|
122
245
|
}
|
|
@@ -130,7 +130,12 @@ export function mergeRecallConceptTokens(text, conceptTokens, limit = 24) {
|
|
|
130
130
|
const entityConcepts = concepts.filter(isEntityConcept);
|
|
131
131
|
const rankingEntityConcepts = entityConcepts.filter((token) => !isStructuralTimeToken(token));
|
|
132
132
|
const useEntityConcepts = rankingEntityConcepts.some(isIdentifierToken) || rankingEntityConcepts.length > 2;
|
|
133
|
-
|
|
133
|
+
// Entity-heavy queries rank their entities first, but the Korean content
|
|
134
|
+
// words stay: dropping them left a mixed query ("웹 검색 원인 Claude Codex
|
|
135
|
+
// Hermes 비교") matching only on product names that half the history shares.
|
|
136
|
+
const rankingConcepts = useEntityConcepts
|
|
137
|
+
? [...entityConcepts, ...concepts.filter((token) => !isEntityConcept(token))]
|
|
138
|
+
: concepts;
|
|
134
139
|
const source =
|
|
135
140
|
concepts.length > 0
|
|
136
141
|
? [...raw.filter((token) => isIdentifierToken(token) || isConceptCompound(token, concepts)), ...rankingConcepts]
|
|
@@ -309,6 +309,22 @@ async function removeReviewAndPromotionCycleState(db) {
|
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
+
// Root vectors now cover the chunk's first message as well as its summary
|
|
313
|
+
// (memory-embed.mjs rootEmbedText). Vectors written under the older text stay
|
|
314
|
+
// in place and are replaced by a paced background sweep (sweepRootEmbedText)
|
|
315
|
+
// that walks roots below this starting cursor, newest first. One statement, so
|
|
316
|
+
// the start is atomic; ON CONFLICT keeps an existing sweep's progress.
|
|
317
|
+
export const ROOT_EMBED_SWEEP_META_KEY = 'embedding.root_text_v2';
|
|
318
|
+
export async function startRootEmbedSweep(db) {
|
|
319
|
+
await db.query(
|
|
320
|
+
`INSERT INTO meta(key, value)
|
|
321
|
+
SELECT $1, jsonb_build_object('cursor', COALESCE(MAX(id), 0) + 1, 'done', false)
|
|
322
|
+
FROM entries WHERE is_root = 1
|
|
323
|
+
ON CONFLICT (key) DO NOTHING`,
|
|
324
|
+
[ROOT_EMBED_SWEEP_META_KEY]
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
312
328
|
export async function ensureCurrentSchemaExtensions(db, dims, embeddingIdentity = null) {
|
|
313
329
|
await removeAttachmentPlaceholderRows(db);
|
|
314
330
|
await removeRuntimeNotificationRowsOnce(db);
|
|
@@ -413,6 +429,7 @@ export async function openDatabase(dataDir, dims, embeddingIdentity = null) {
|
|
|
413
429
|
}
|
|
414
430
|
await ensureCurrentSchemaExtensions(db, Number(dims), embeddingIdentity);
|
|
415
431
|
await validateEmbeddingDims(db, Number(dims));
|
|
432
|
+
await withSchemaBootstrapLock(pool, () => startRootEmbedSweep(db));
|
|
416
433
|
|
|
417
434
|
dbs.set(key, db);
|
|
418
435
|
return db;
|
|
@@ -400,7 +400,7 @@ async function startAndWaitReady({ pgctl, startArgs, env, pgdataDir, port }) {
|
|
|
400
400
|
// so the postmaster is already reparented OUT of the Node process tree —
|
|
401
401
|
// detached only isolated the short-lived pg_ctl. Shutdown/reuse target
|
|
402
402
|
// pgdata/postmaster.pid (pg_ctl stop -D, tryReusePgInstance), not a
|
|
403
|
-
// Node-tree
|
|
403
|
+
// Node-tree kill, so `windowsHide` alone is correct on all platforms.
|
|
404
404
|
const child = spawn(pgctl, startArgs, { env, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
|
|
405
405
|
child.unref?.();
|
|
406
406
|
const run = { stdout: '', stderr: '', closed: false, exitCode: null };
|
|
@@ -20,7 +20,7 @@ import { __mixdogMemoryLog } from '../memory-log.mjs';
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { createServer } from 'node:net';
|
|
23
|
-
import { existsSync, unlinkSync, readFileSync,
|
|
23
|
+
import { existsSync, unlinkSync, readFileSync, renameSync, statSync, mkdirSync } from 'node:fs';
|
|
24
24
|
import { join, resolve } from 'node:path';
|
|
25
25
|
import {
|
|
26
26
|
discoveryPath as _pgDiscoveryPath,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
writeServiceAdvert as _writePgServiceAdvert,
|
|
29
29
|
} from '../../../shared/service-discovery.mjs';
|
|
30
30
|
import { withFileLockSync } from '../../../shared/atomic-file.mjs';
|
|
31
|
+
import { withFileLock } from '../../../shared/file-lock.mjs';
|
|
31
32
|
import { isPidAlive } from '../../../shared/pid-liveness.mjs';
|
|
32
33
|
import { envFlag } from '../../../shared/env.mjs';
|
|
33
34
|
import { createSharedAbortable } from '../../../shared/abort-race.mjs';
|
|
@@ -64,92 +65,11 @@ let _ownedExitStopInstalled = false;
|
|
|
64
65
|
const PG_PORT_MIN = 55432;
|
|
65
66
|
const PG_PORT_MAX = 55632;
|
|
66
67
|
const PG_LOG_MAX_BYTES = 10 * 1024 * 1024; // 10 MB
|
|
67
|
-
const SPAWN_LOCK_NAME = 'pg-spawn.lock';
|
|
68
|
-
const LOCK_WAIT_MS = 30_000;
|
|
69
|
-
const LOCK_POLL_MS = 100;
|
|
70
|
-
const LOCK_WARN_MS = 5_000;
|
|
71
|
-
const LOCK_WAIT_CODES = new Set(['EEXIST', 'EPERM', 'EACCES', 'EBUSY']);
|
|
72
68
|
|
|
73
69
|
function attachOnlyMode() {
|
|
74
70
|
return envFlag('MIXDOG_PG_ATTACH_ONLY') || envFlag('MIXDOG_MEMORY_SECONDARY');
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
// ── File lock (O_EXCL pattern from dispatch-persist.mjs / run-mcp.mjs) ───────
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Acquire `${dataDir}/pg-spawn.lock`.
|
|
81
|
-
* Returns the lock-file path on success, or null on timeout (caller proceeds
|
|
82
|
-
* best-effort — worst case: two supervisors race initdb on the same pgdata,
|
|
83
|
-
* but the second will fail pg_ctl start gracefully and healthcheck will
|
|
84
|
-
* converge on the first's port).
|
|
85
|
-
*/
|
|
86
|
-
async function acquireSpawnLock(dataDir, blockedProbe = null) {
|
|
87
|
-
const lp = join(dataDir, SPAWN_LOCK_NAME);
|
|
88
|
-
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
89
|
-
const body = JSON.stringify({ pid: process.pid, startedAt: Date.now() });
|
|
90
|
-
let warned = false;
|
|
91
|
-
for (;;) {
|
|
92
|
-
try {
|
|
93
|
-
// 'wx' = O_CREAT | O_EXCL — atomic, fails with EEXIST if held.
|
|
94
|
-
writeFileSync(lp, body, { flag: 'wx' });
|
|
95
|
-
return { lockPath: lp, reuse: null };
|
|
96
|
-
} catch (err) {
|
|
97
|
-
if (!LOCK_WAIT_CODES.has(err?.code)) {
|
|
98
|
-
__mixdogMemoryLog(`[supervisor-pg] spawn lock error: ${err?.code || err?.message}\n`);
|
|
99
|
-
return { lockPath: null, reuse: null };
|
|
100
|
-
}
|
|
101
|
-
if (blockedProbe) {
|
|
102
|
-
try {
|
|
103
|
-
const reuse = await blockedProbe();
|
|
104
|
-
if (reuse) return { lockPath: null, reuse };
|
|
105
|
-
} catch {}
|
|
106
|
-
}
|
|
107
|
-
// Dead-holder detection: same as run-mcp.mjs acquireLock().
|
|
108
|
-
try {
|
|
109
|
-
const holder = JSON.parse(readFileSync(lp, 'utf8'));
|
|
110
|
-
if (holder?.pid) {
|
|
111
|
-
try {
|
|
112
|
-
process.kill(holder.pid, 0);
|
|
113
|
-
} catch (ke) {
|
|
114
|
-
if (ke.code === 'ESRCH') {
|
|
115
|
-
try {
|
|
116
|
-
unlinkSync(lp);
|
|
117
|
-
} catch {}
|
|
118
|
-
continue; // retry immediately after removing stale lock
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const ageMs = Date.now() - Number(holder?.startedAt || 0);
|
|
123
|
-
if (!warned && ageMs >= LOCK_WARN_MS) {
|
|
124
|
-
warned = true;
|
|
125
|
-
__mixdogMemoryLog(
|
|
126
|
-
`[supervisor-pg] waiting for spawn lock holder pid=${holder?.pid || 'unknown'} ageMs=${ageMs}\n`
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
} catch {
|
|
130
|
-
/* unreadable — fall through and wait */
|
|
131
|
-
}
|
|
132
|
-
if (Date.now() >= deadline) {
|
|
133
|
-
if (blockedProbe) {
|
|
134
|
-
try {
|
|
135
|
-
const reuse = await blockedProbe();
|
|
136
|
-
if (reuse) return { lockPath: null, reuse };
|
|
137
|
-
} catch {}
|
|
138
|
-
}
|
|
139
|
-
throw new Error(`[supervisor-pg] spawn-lock acquire timeout (concurrent supervisor risk)`);
|
|
140
|
-
}
|
|
141
|
-
await new Promise((r) => setTimeout(r, LOCK_POLL_MS));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function releaseSpawnLock(lp) {
|
|
147
|
-
if (!lp) return;
|
|
148
|
-
try {
|
|
149
|
-
unlinkSync(lp);
|
|
150
|
-
} catch {}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
73
|
// ── Port allocation ──────────────────────────────────────────────────────────
|
|
154
74
|
|
|
155
75
|
function _probePort(port) {
|
|
@@ -602,18 +522,10 @@ async function _doEnsure(dataDir, signal) {
|
|
|
602
522
|
throw new Error('secondary memory runtime requires an existing PG instance');
|
|
603
523
|
}
|
|
604
524
|
|
|
605
|
-
// ──
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
runtimeDir,
|
|
610
|
-
healthcheckPg,
|
|
611
|
-
source: 'lock-wait',
|
|
612
|
-
})
|
|
613
|
-
);
|
|
614
|
-
if (acquired?.reuse) return acquired.reuse;
|
|
615
|
-
const lp = acquired?.lockPath ?? null;
|
|
616
|
-
try {
|
|
525
|
+
// ── Spawn lock serializes initdb races (see withFileLock below) ──────────
|
|
526
|
+
let lockEntered = false;
|
|
527
|
+
const spawnUnderLock = async () => {
|
|
528
|
+
lockEntered = true;
|
|
617
529
|
// ── Reuse path: another supervisor already started PG ─────────────────
|
|
618
530
|
const lockedReuse = await tryReusePgInstance({
|
|
619
531
|
pgdata,
|
|
@@ -701,8 +613,16 @@ async function _doEnsure(dataDir, signal) {
|
|
|
701
613
|
// ── Allocate a fresh port and spawn ───────────────────────────────────
|
|
702
614
|
const port = await allocatePort();
|
|
703
615
|
return await _startFresh(dataDir, pgdata, port, runtimeDir);
|
|
704
|
-
}
|
|
705
|
-
|
|
616
|
+
};
|
|
617
|
+
try {
|
|
618
|
+
return await withFileLock(join(dataDir, 'pg-spawn.lock'), spawnUnderLock, { timeoutMs: 30_000 });
|
|
619
|
+
} catch (err) {
|
|
620
|
+
// Only an acquisition timeout (spawnUnderLock never ran) falls back to
|
|
621
|
+
// reuse; failures from inside the locked region propagate untouched.
|
|
622
|
+
if (lockEntered || err?.code !== 'ELOCKTIMEOUT') throw err;
|
|
623
|
+
const reuse = await tryReusePgInstance({ pgdata, runtimeDir, healthcheckPg, source: 'lock-wait' });
|
|
624
|
+
if (reuse) return reuse;
|
|
625
|
+
throw new Error('[supervisor-pg] spawn-lock acquire timeout (concurrent supervisor risk)', { cause: err });
|
|
706
626
|
}
|
|
707
627
|
}
|
|
708
628
|
|
|
@@ -119,6 +119,11 @@ exact AS (
|
|
|
119
119
|
WHERE false
|
|
120
120
|
),`;
|
|
121
121
|
}
|
|
122
|
+
// Each row is lowercased once (OFFSET 0 keeps the subquery from being
|
|
123
|
+
// inlined into the per-term condition) and every term is a literal strpos
|
|
124
|
+
// on that text. Per-term ILIKE re-lowercased the whole content for every
|
|
125
|
+
// term, so a natural-language query's 10+ terms multiplied the scan cost.
|
|
126
|
+
// Terms arrive lowercased from buildExactTerms.
|
|
122
127
|
return `
|
|
123
128
|
exact_matches AS (
|
|
124
129
|
SELECT ee.id,
|
|
@@ -126,10 +131,14 @@ exact_matches AS (
|
|
|
126
131
|
q.term,
|
|
127
132
|
COUNT(*) OVER (PARTITION BY q.term)::float8 AS term_df
|
|
128
133
|
FROM entries ee
|
|
134
|
+
CROSS JOIN LATERAL (
|
|
135
|
+
SELECT lower(ee.content) AS content, lower(ee.element) AS element, lower(ee.summary) AS summary
|
|
136
|
+
OFFSET 0
|
|
137
|
+
) lc
|
|
129
138
|
JOIN LATERAL unnest($${exactTermsParam}::text[]) AS q(term) ON (
|
|
130
|
-
|
|
131
|
-
OR
|
|
132
|
-
OR
|
|
139
|
+
strpos(lc.content, q.term) > 0
|
|
140
|
+
OR strpos(lc.element, q.term) > 0
|
|
141
|
+
OR strpos(lc.summary, q.term) > 0
|
|
133
142
|
)
|
|
134
143
|
WHERE true
|
|
135
144
|
${filters.exactFilterClause}
|
|
@@ -17,7 +17,7 @@ import { renderPdfPages } from '../pdf/pdf-render.mjs';
|
|
|
17
17
|
const PX_TO_PT = 0.75;
|
|
18
18
|
|
|
19
19
|
/** Artifacts kept beside the document: its HTML and the browser's print of it. */
|
|
20
|
-
|
|
20
|
+
function docxHtmlArtifacts(target) {
|
|
21
21
|
return {
|
|
22
22
|
source: `${target}.mixdog-source.html`,
|
|
23
23
|
print: `${target}.mixdog-html.pdf`,
|
|
@@ -34,7 +34,7 @@ const PPTX_AUTHOR_NEEDS_SOURCE =
|
|
|
34
34
|
'author requires script: HTML slides or a pptxgenjs script (without one it re-authors from <deck>.pptx.mixdog-source.html, and none is there). Load the `pptx` Skill first (Skill name:"pptx"): it carries the authoring workflow, the HTML contract, the composition grammar, and the device kit, then call author again with path and script.';
|
|
35
35
|
|
|
36
36
|
// HTML opens with markup (a doctype, a comment, an element); a pptxgenjs script never does.
|
|
37
|
-
|
|
37
|
+
function isHtmlSource(source) {
|
|
38
38
|
return /^\s*</.test(String(source || ''));
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -140,7 +140,7 @@ function resolveRange(text, cells, notes) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
/** The operations that write one measured workbook; formulas and charts come after every sheet's values. */
|
|
143
|
-
|
|
143
|
+
function xlsxOperationsFromSheets(sheets, { captures = new Map(), notes = [] } = {}) {
|
|
144
144
|
const first = [];
|
|
145
145
|
const later = [];
|
|
146
146
|
const chartData = [];
|
|
@@ -49,7 +49,7 @@ function fillRangeCharts() {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/** Artifacts kept beside the workbook: its HTML and the browser's picture of each sheet. */
|
|
52
|
-
|
|
52
|
+
function xlsxHtmlArtifacts(target) {
|
|
53
53
|
return {
|
|
54
54
|
source: `${target}.mixdog-source.html`,
|
|
55
55
|
shot: (sheet) => `${target}.mixdog-html-sheet-${sheet}.png`,
|
|
@@ -430,7 +430,7 @@ function docxStyleDefinitionFault(format, name, operation, index) {
|
|
|
430
430
|
|
|
431
431
|
// A Word table has two alignments that read alike: `alignment` places the
|
|
432
432
|
// table on the page and `columnAlignments` sets the text of each column.
|
|
433
|
-
// A list written into the first
|
|
433
|
+
// A list written into the first would be serialized verbatim into the
|
|
434
434
|
// table's justification and refused by Word's schema at finalize.
|
|
435
435
|
function docxTableAlignmentFaults(format, name, operation, index) {
|
|
436
436
|
const properties = operation.properties;
|
|
@@ -118,7 +118,7 @@ export async function ensureOfficeSessionDesign(
|
|
|
118
118
|
session.designRequest = mergeOfficeDesignRequest(session.designRequest, args.design);
|
|
119
119
|
// A native document stays native: the `design` a later call carries is the
|
|
120
120
|
// page review (reviewed, reviewToken, critique) or content, not a request
|
|
121
|
-
// for a preset. Resolving it as one
|
|
121
|
+
// for a preset. Resolving it as one would hand a Word or Excel file the
|
|
122
122
|
// default profile's palette and art direction it never asked for, and put
|
|
123
123
|
// the preset review's gates in front of finalize.
|
|
124
124
|
session.design =
|
|
@@ -108,9 +108,9 @@ export function normalizeOfficeContentModel(value) {
|
|
|
108
108
|
const id = safeId(claim.id, 'claim id', `claim ${index + 1}${claim?.text ? `: ${claim.text}` : ''}`);
|
|
109
109
|
if (claimIds.has(id)) throw new Error(`Office content model has duplicate claim id ${id}`);
|
|
110
110
|
claimIds.add(id);
|
|
111
|
-
// The references are the point of a claim
|
|
112
|
-
//
|
|
113
|
-
//
|
|
111
|
+
// The references are the point of a claim, so `facts` is accepted as an
|
|
112
|
+
// alias of `factIds`: a claim written with either name stays bound to its
|
|
113
|
+
// sources instead of reporting the figure it carried as unsourced.
|
|
114
114
|
let references = [];
|
|
115
115
|
if (Array.isArray(claim.factIds)) references = claim.factIds;
|
|
116
116
|
else if (Array.isArray(claim.facts)) references = claim.facts;
|
|
@@ -39,10 +39,10 @@ function writeSectionHeading(w, section) {
|
|
|
39
39
|
function writeSectionList(w, section, sectionKind, blockFollows = false) {
|
|
40
40
|
const { append, colors, type, bodySize, spacing } = w;
|
|
41
41
|
const sectionBullets = strings(section.bullets);
|
|
42
|
-
// A section that names steps draws them.
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
42
|
+
// A section that names steps draws them. Reaching the page only with
|
|
43
|
+
// kind:'roadmap' would land a plan section as a heading with nothing under
|
|
44
|
+
// it - and the audit would report the orphan heading the composer had just
|
|
45
|
+
// written.
|
|
46
46
|
const sectionSteps = Array.isArray(section.steps) ? section.steps : [];
|
|
47
47
|
const stepSource = sectionSteps.length ? sectionSteps : sectionBullets;
|
|
48
48
|
const drewSteps =
|
|
@@ -76,8 +76,8 @@ function writeSectionList(w, section, sectionKind, blockFollows = false) {
|
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
// What a section can carry. A field outside this list
|
|
80
|
-
// page as a heading with nothing under it, and the composer
|
|
79
|
+
// What a section can carry. A field outside this list would vanish: a plan written as `roadmap:[…]` would reach the
|
|
80
|
+
// page as a heading with nothing under it, and the composer would report success.
|
|
81
81
|
const SECTION_FIELDS = new Set([
|
|
82
82
|
'heading',
|
|
83
83
|
'title',
|
|
@@ -197,7 +197,7 @@ export function addXlsxDecisionPanel(
|
|
|
197
197
|
cursor += 1;
|
|
198
198
|
});
|
|
199
199
|
}
|
|
200
|
-
// The actions follow the gates rather than stand in for them: given both, the actions
|
|
200
|
+
// The actions follow the gates rather than stand in for them: given both, the actions would be dropped.
|
|
201
201
|
if (gateRows.length && strings(actions).length) cursor += 1;
|
|
202
202
|
for (const action of strings(actions).slice(0, 4)) {
|
|
203
203
|
mergedBlock(output, {
|
|
@@ -417,7 +417,7 @@ function metricLabelStyle({ colors, type, dashboard }) {
|
|
|
417
417
|
// metric is the one the strip paints as the headline, so the wider card reads
|
|
418
418
|
// as emphasis rather than as a card that ran out of room.
|
|
419
419
|
// More cards than columns wrap onto a second strip rather than pulling the
|
|
420
|
-
// canvas past the table: a three-metric strip over a two-column table
|
|
420
|
+
// canvas past the table: a three-metric strip over a two-column table would
|
|
421
421
|
// make every band half again as wide as the table under it.
|
|
422
422
|
// The text a card's value shows under its number format ("47.0%" for 0.47 under 0.0%, "12명" for 12 under 0"명").
|
|
423
423
|
function metricDisplayText(metric) {
|
|
@@ -9,7 +9,7 @@ import { workerExecArgv } from '../../shared/worker-exec-argv.mjs';
|
|
|
9
9
|
const ENGINE_URL = new URL('./ocr-engine-worker.mjs', import.meta.url);
|
|
10
10
|
|
|
11
11
|
/** The start includes the first-use download; without network it fails or hangs. */
|
|
12
|
-
|
|
12
|
+
const OCR_ENGINE_START_TIMEOUT_MS = 90_000;
|
|
13
13
|
|
|
14
14
|
const engines = new Map();
|
|
15
15
|
|
|
@@ -13,10 +13,10 @@ const HEADING_SIZES = Object.freeze({ 1: 16, 2: 13, 3: 12 });
|
|
|
13
13
|
|
|
14
14
|
const FLOW_FIELDS = ['before', 'after', 'x', 'width', 'color', 'align'];
|
|
15
15
|
|
|
16
|
-
// What each block actually takes. A block the writer cannot read
|
|
17
|
-
// as an empty paragraph: a table or a list written under the wrong key
|
|
18
|
-
// mark on the page and no word in the result, so the report
|
|
19
|
-
// the evidence it was asked for.
|
|
16
|
+
// What each block actually takes. A block the writer cannot read would flow
|
|
17
|
+
// as an empty paragraph: a table or a list written under the wrong key would
|
|
18
|
+
// leave no mark on the page and no word in the result, so the report would ship
|
|
19
|
+
// without the evidence it was asked for.
|
|
20
20
|
const BLOCK_FIELDS = Object.freeze({
|
|
21
21
|
paragraph: Object.freeze({ required: ['text'], optional: [...FLOW_FIELDS, 'size', 'lineHeight'] }),
|
|
22
22
|
heading: Object.freeze({ required: ['text'], optional: [...FLOW_FIELDS, 'size', 'lineHeight', 'level'] }),
|
|
@@ -825,8 +825,8 @@ function styledDocxCell(cell, op) {
|
|
|
825
825
|
}
|
|
826
826
|
|
|
827
827
|
// A merged cell keeps what it carried (its shading, its borders, the bottom alignment a header row sits on, as Word
|
|
828
|
-
// keeps them) and takes the spans; its width becomes the widths it joins.
|
|
829
|
-
// two-level header's merged labels
|
|
828
|
+
// keeps them) and takes the spans; its width becomes the widths it joins. Replacing the whole tcPr would make a
|
|
829
|
+
// two-level header's merged labels rise to the top of their cells on this backend only. Children stay in schema
|
|
830
830
|
// order: cnfStyle, tcW, gridSpan, vMerge, then the rest.
|
|
831
831
|
function mergedCellXml(joined, spans) {
|
|
832
832
|
const existing = /<w:tcPr(?:\s[^>]*)?>([\s\S]*?)<\/w:tcPr>/.exec(joined[0])?.[1] || '';
|