@openrig/cli 0.6.9 → 0.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/daemon/assets/onboarding/02-self-and-competent-action.md +4 -3
- package/daemon/assets/plugins/openrig-core/.claude-plugin/plugin.json +1 -1
- package/daemon/assets/plugins/openrig-core/.codex-plugin/plugin.json +1 -1
- package/daemon/assets/plugins/openrig-core/hooks/scripts/activity-relay.cjs +42 -2
- package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +1 -1
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +7 -1
- package/daemon/assets/plugins/openrig-core/skills/refocusing/scripts/trace-to-root.py +6 -1
- package/daemon/assets/skills/rigs/SKILL.md +7 -5
- package/daemon/context-packs/help/manifest.yaml +1 -1
- package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
- package/daemon/context-packs/onboarding-width/public-what-you-can-do.md +64 -14
- package/daemon/context-packs/reference/getting-started.md +10 -6
- package/daemon/context-packs/reference/manifest.yaml +1 -1
- package/daemon/context-packs/reference/rig-spec.md +2 -2
- package/daemon/context-packs/reference/whats-new.md +151 -74
- package/daemon/context-packs/skills/agent-operated-software/manifest.yaml +1 -1
- package/daemon/context-packs/skills/agent-operated-workflows/manifest.yaml +1 -1
- package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +1 -1
- package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-skills/SKILL.md +1 -1
- package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +3 -3
- package/daemon/context-packs/skills/core/openrig-software-factory/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/SKILL.md +2 -2
- package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
- package/daemon/context-packs/skills/delegating-work/manifest.yaml +1 -1
- package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +1 -1
- package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +1 -1
- package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +1 -1
- package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +1 -1
- package/daemon/context-packs/skills/openrig-user/SKILL.md +7 -1
- package/daemon/context-packs/skills/openrig-user/manifest.yaml +1 -1
- package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
- package/daemon/context-packs/skills/queue-handoff/manifest.yaml +1 -1
- package/daemon/context-packs/skills/refocusing/manifest.yaml +1 -1
- package/daemon/context-packs/skills/refocusing/scripts/trace-to-root.py +6 -1
- package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +1 -1
- package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +1 -1
- package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +1 -1
- package/daemon/context-packs/skills/software-for-agents/manifest.yaml +1 -1
- package/daemon/context-packs/world-example/manifest.yaml +1 -1
- package/daemon/context-packs/world-public/manifest.yaml +1 -1
- package/daemon/dist/adapters/claude-code-adapter.d.ts +0 -14
- package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-code-adapter.js +43 -80
- package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
- package/daemon/dist/adapters/claude-resume-launch.d.ts +4 -0
- package/daemon/dist/adapters/claude-resume-launch.d.ts.map +1 -0
- package/daemon/dist/adapters/claude-resume-launch.js +13 -0
- package/daemon/dist/adapters/claude-resume-launch.js.map +1 -0
- package/daemon/dist/adapters/claude-resume.d.ts +2 -1
- package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-resume.js +9 -4
- package/daemon/dist/adapters/claude-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts +35 -0
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +94 -44
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/pi-runner.d.ts.map +1 -1
- package/daemon/dist/adapters/pi-runner.js +6 -3
- package/daemon/dist/adapters/pi-runner.js.map +1 -1
- package/daemon/dist/adapters/pi-runtime-adapter.js +1 -1
- package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/tmux-server.d.ts +15 -0
- package/daemon/dist/adapters/tmux-server.d.ts.map +1 -0
- package/daemon/dist/adapters/tmux-server.js +58 -0
- package/daemon/dist/adapters/tmux-server.js.map +1 -0
- package/daemon/dist/adapters/tmux.d.ts +26 -1
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +130 -7
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/build-info.js +3 -3
- package/daemon/dist/db/all-migrations.d.ts.map +1 -1
- package/daemon/dist/db/all-migrations.js +6 -0
- package/daemon/dist/db/all-migrations.js.map +1 -1
- package/daemon/dist/db/migrations/099_queue_items_recovery_tags.d.ts +3 -0
- package/daemon/dist/db/migrations/099_queue_items_recovery_tags.d.ts.map +1 -0
- package/daemon/dist/db/migrations/099_queue_items_recovery_tags.js +19 -0
- package/daemon/dist/db/migrations/099_queue_items_recovery_tags.js.map +1 -0
- package/daemon/dist/db/migrations/101_claude_resume_rotation.d.ts +3 -0
- package/daemon/dist/db/migrations/101_claude_resume_rotation.d.ts.map +1 -0
- package/daemon/dist/db/migrations/101_claude_resume_rotation.js +19 -0
- package/daemon/dist/db/migrations/101_claude_resume_rotation.js.map +1 -0
- package/daemon/dist/db/migrations/103_session_stop_intent.d.ts +4 -0
- package/daemon/dist/db/migrations/103_session_stop_intent.d.ts.map +1 -0
- package/daemon/dist/db/migrations/103_session_stop_intent.js +9 -0
- package/daemon/dist/db/migrations/103_session_stop_intent.js.map +1 -0
- package/daemon/dist/domain/active-occupant.d.ts +14 -0
- package/daemon/dist/domain/active-occupant.d.ts.map +1 -1
- package/daemon/dist/domain/active-occupant.js +17 -0
- package/daemon/dist/domain/active-occupant.js.map +1 -1
- package/daemon/dist/domain/agent-activity-store.js +3 -0
- package/daemon/dist/domain/agent-activity-store.js.map +1 -1
- package/daemon/dist/domain/bootstrap-repository.js +1 -1
- package/daemon/dist/domain/bootstrap-repository.js.map +1 -1
- package/daemon/dist/domain/chat-repository.d.ts +3 -0
- package/daemon/dist/domain/chat-repository.d.ts.map +1 -1
- package/daemon/dist/domain/chat-repository.js +15 -4
- package/daemon/dist/domain/chat-repository.js.map +1 -1
- package/daemon/dist/domain/claude-managed-launch.d.ts +1 -1
- package/daemon/dist/domain/claude-managed-launch.d.ts.map +1 -1
- package/daemon/dist/domain/claude-managed-launch.js +3 -2
- package/daemon/dist/domain/claude-managed-launch.js.map +1 -1
- package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -1
- package/daemon/dist/domain/cmux-layout-service.js +2 -1
- package/daemon/dist/domain/cmux-layout-service.js.map +1 -1
- package/daemon/dist/domain/codex-git-add-dirs.js +1 -1
- package/daemon/dist/domain/codex-git-add-dirs.js.map +1 -1
- package/daemon/dist/domain/codex-network-default.d.ts +3 -0
- package/daemon/dist/domain/codex-network-default.d.ts.map +1 -1
- package/daemon/dist/domain/codex-network-default.js +1 -1
- package/daemon/dist/domain/codex-network-default.js.map +1 -1
- package/daemon/dist/domain/codex-pane-patterns.d.ts +2 -0
- package/daemon/dist/domain/codex-pane-patterns.d.ts.map +1 -0
- package/daemon/dist/domain/codex-pane-patterns.js +5 -0
- package/daemon/dist/domain/codex-pane-patterns.js.map +1 -0
- package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
- package/daemon/dist/domain/context-monitor.js +46 -22
- package/daemon/dist/domain/context-monitor.js.map +1 -1
- package/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
- package/daemon/dist/domain/context-usage-store.js +6 -1
- package/daemon/dist/domain/context-usage-store.js.map +1 -1
- package/daemon/dist/domain/crash-cart-conductor.d.ts.map +1 -1
- package/daemon/dist/domain/crash-cart-conductor.js +3 -1
- package/daemon/dist/domain/crash-cart-conductor.js.map +1 -1
- package/daemon/dist/domain/cwd-resolution.d.ts +8 -0
- package/daemon/dist/domain/cwd-resolution.d.ts.map +1 -1
- package/daemon/dist/domain/cwd-resolution.js +24 -3
- package/daemon/dist/domain/cwd-resolution.js.map +1 -1
- package/daemon/dist/domain/files/file-read.d.ts.map +1 -1
- package/daemon/dist/domain/files/file-read.js +11 -3
- package/daemon/dist/domain/files/file-read.js.map +1 -1
- package/daemon/dist/domain/gateway/connections-projection.d.ts +1 -1
- package/daemon/dist/domain/gateway/slack/channel-recovery.d.ts.map +1 -1
- package/daemon/dist/domain/gateway/slack/channel-recovery.js +4 -3
- package/daemon/dist/domain/gateway/slack/channel-recovery.js.map +1 -1
- package/daemon/dist/domain/gateway/slack/inbound.d.ts +21 -2
- package/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -1
- package/daemon/dist/domain/gateway/slack/inbound.js +70 -11
- package/daemon/dist/domain/gateway/slack/inbound.js.map +1 -1
- package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts +4 -0
- package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts.map +1 -1
- package/daemon/dist/domain/gateway/slack/slack-delivery.js +1 -1
- package/daemon/dist/domain/gateway/slack/slack-delivery.js.map +1 -1
- package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts.map +1 -1
- package/daemon/dist/domain/gateway/slack/slack-subsystem.js +7 -4
- package/daemon/dist/domain/gateway/slack/slack-subsystem.js.map +1 -1
- package/daemon/dist/domain/history-query.d.ts.map +1 -1
- package/daemon/dist/domain/history-query.js +8 -6
- package/daemon/dist/domain/history-query.js.map +1 -1
- package/daemon/dist/domain/human-questions.d.ts +4 -1
- package/daemon/dist/domain/human-questions.d.ts.map +1 -1
- package/daemon/dist/domain/human-questions.js.map +1 -1
- package/daemon/dist/domain/install-engine.js +2 -2
- package/daemon/dist/domain/install-engine.js.map +1 -1
- package/daemon/dist/domain/native-process-lineage.d.ts +57 -4
- package/daemon/dist/domain/native-process-lineage.d.ts.map +1 -1
- package/daemon/dist/domain/native-process-lineage.js +277 -42
- package/daemon/dist/domain/native-process-lineage.js.map +1 -1
- package/daemon/dist/domain/node-cmux-service.d.ts.map +1 -1
- package/daemon/dist/domain/node-cmux-service.js +2 -1
- package/daemon/dist/domain/node-cmux-service.js.map +1 -1
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +71 -18
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/node-launcher.js +2 -1
- package/daemon/dist/domain/node-launcher.js.map +1 -1
- package/daemon/dist/domain/pane-cutover.d.ts +27 -0
- package/daemon/dist/domain/pane-cutover.d.ts.map +1 -0
- package/daemon/dist/domain/pane-cutover.js +37 -0
- package/daemon/dist/domain/pane-cutover.js.map +1 -0
- package/daemon/dist/domain/parent-session-env.d.ts +8 -0
- package/daemon/dist/domain/parent-session-env.d.ts.map +1 -0
- package/daemon/dist/domain/parent-session-env.js +37 -0
- package/daemon/dist/domain/parent-session-env.js.map +1 -0
- package/daemon/dist/domain/policies/parked-owner-consumer.d.ts +11 -0
- package/daemon/dist/domain/policies/parked-owner-consumer.d.ts.map +1 -1
- package/daemon/dist/domain/policies/parked-owner-consumer.js +81 -11
- package/daemon/dist/domain/policies/parked-owner-consumer.js.map +1 -1
- package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
- package/daemon/dist/domain/profile-resolver.js +2 -3
- package/daemon/dist/domain/profile-resolver.js.map +1 -1
- package/daemon/dist/domain/progress/progress-indexer.d.ts.map +1 -1
- package/daemon/dist/domain/progress/progress-indexer.js +19 -0
- package/daemon/dist/domain/progress/progress-indexer.js.map +1 -1
- package/daemon/dist/domain/proof/judgments.d.ts +10 -5
- package/daemon/dist/domain/proof/judgments.d.ts.map +1 -1
- package/daemon/dist/domain/proof/judgments.js +27 -19
- package/daemon/dist/domain/proof/judgments.js.map +1 -1
- package/daemon/dist/domain/provider/codex-limit-banner.d.ts +40 -0
- package/daemon/dist/domain/provider/codex-limit-banner.d.ts.map +1 -0
- package/daemon/dist/domain/provider/codex-limit-banner.js +168 -0
- package/daemon/dist/domain/provider/codex-limit-banner.js.map +1 -0
- package/daemon/dist/domain/provider/codex-usage-reader.d.ts +31 -0
- package/daemon/dist/domain/provider/codex-usage-reader.d.ts.map +1 -0
- package/daemon/dist/domain/provider/codex-usage-reader.js +115 -0
- package/daemon/dist/domain/provider/codex-usage-reader.js.map +1 -0
- package/daemon/dist/domain/provider/codex-usage-windows.d.ts +78 -0
- package/daemon/dist/domain/provider/codex-usage-windows.d.ts.map +1 -0
- package/daemon/dist/domain/provider/codex-usage-windows.js +259 -0
- package/daemon/dist/domain/provider/codex-usage-windows.js.map +1 -0
- package/daemon/dist/domain/provider/provider-service-impl.d.ts +10 -0
- package/daemon/dist/domain/provider/provider-service-impl.d.ts.map +1 -1
- package/daemon/dist/domain/provider/provider-service-impl.js +27 -1
- package/daemon/dist/domain/provider/provider-service-impl.js.map +1 -1
- package/daemon/dist/domain/provider/provider-service.d.ts +5 -0
- package/daemon/dist/domain/provider/provider-service.d.ts.map +1 -1
- package/daemon/dist/domain/provider/provider-types.d.ts +65 -0
- package/daemon/dist/domain/provider/provider-types.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.d.ts +5 -2
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +29 -26
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-recovery.d.ts.map +1 -1
- package/daemon/dist/domain/queue-recovery.js +10 -3
- package/daemon/dist/domain/queue-recovery.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +68 -13
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
- package/daemon/dist/domain/queue-repository.js +72 -43
- package/daemon/dist/domain/queue-repository.js.map +1 -1
- package/daemon/dist/domain/queue-stuck-sweep.d.ts.map +1 -1
- package/daemon/dist/domain/queue-stuck-sweep.js +26 -9
- package/daemon/dist/domain/queue-stuck-sweep.js.map +1 -1
- package/daemon/dist/domain/queue-wake-ladder.d.ts +17 -0
- package/daemon/dist/domain/queue-wake-ladder.d.ts.map +1 -1
- package/daemon/dist/domain/queue-wake-ladder.js +49 -3
- package/daemon/dist/domain/queue-wake-ladder.js.map +1 -1
- package/daemon/dist/domain/restore-check-service.d.ts +8 -0
- package/daemon/dist/domain/restore-check-service.d.ts.map +1 -1
- package/daemon/dist/domain/restore-check-service.js +12 -3
- package/daemon/dist/domain/restore-check-service.js.map +1 -1
- package/daemon/dist/domain/restore-guidance.d.ts +39 -0
- package/daemon/dist/domain/restore-guidance.d.ts.map +1 -0
- package/daemon/dist/domain/restore-guidance.js +163 -0
- package/daemon/dist/domain/restore-guidance.js.map +1 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts +10 -1
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +192 -9
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/restore-plan-preview.d.ts +4 -0
- package/daemon/dist/domain/restore-plan-preview.d.ts.map +1 -1
- package/daemon/dist/domain/restore-plan-preview.js +14 -3
- package/daemon/dist/domain/restore-plan-preview.js.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.js +7 -6
- package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
- package/daemon/dist/domain/runtime-adapter.d.ts +3 -0
- package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/domain/runtime-adapter.js.map +1 -1
- package/daemon/dist/domain/scope/scope-view-projection.d.ts +4 -2
- package/daemon/dist/domain/scope/scope-view-projection.d.ts.map +1 -1
- package/daemon/dist/domain/scope/scope-view-projection.js +11 -11
- package/daemon/dist/domain/scope/scope-view-projection.js.map +1 -1
- package/daemon/dist/domain/seat-attention-reconciler.d.ts +5 -2
- package/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
- package/daemon/dist/domain/seat-attention-reconciler.js +18 -4
- package/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
- package/daemon/dist/domain/seat-identity-reconciler.d.ts.map +1 -1
- package/daemon/dist/domain/seat-identity-reconciler.js +7 -2
- package/daemon/dist/domain/seat-identity-reconciler.js.map +1 -1
- package/daemon/dist/domain/seat-lifecycle-service.d.ts +117 -2
- package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-lifecycle-service.js +335 -74
- package/daemon/dist/domain/seat-lifecycle-service.js.map +1 -1
- package/daemon/dist/domain/seat-restart-in-place.d.ts +292 -0
- package/daemon/dist/domain/seat-restart-in-place.d.ts.map +1 -0
- package/daemon/dist/domain/seat-restart-in-place.js +895 -0
- package/daemon/dist/domain/seat-restart-in-place.js.map +1 -0
- package/daemon/dist/domain/seat-status-service.d.ts +2 -1
- package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-status-service.js +1 -0
- package/daemon/dist/domain/seat-status-service.js.map +1 -1
- package/daemon/dist/domain/seat-structural-activity-service.d.ts +9 -1
- package/daemon/dist/domain/seat-structural-activity-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-structural-activity-service.js +27 -4
- package/daemon/dist/domain/seat-structural-activity-service.js.map +1 -1
- package/daemon/dist/domain/seat-switch-client-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-switch-client-service.js +2 -1
- package/daemon/dist/domain/seat-switch-client-service.js.map +1 -1
- package/daemon/dist/domain/session-fingerprinter.d.ts.map +1 -1
- package/daemon/dist/domain/session-fingerprinter.js +9 -5
- package/daemon/dist/domain/session-fingerprinter.js.map +1 -1
- package/daemon/dist/domain/session-registry.d.ts +49 -0
- package/daemon/dist/domain/session-registry.d.ts.map +1 -1
- package/daemon/dist/domain/session-registry.js +92 -5
- package/daemon/dist/domain/session-registry.js.map +1 -1
- package/daemon/dist/domain/session-transport.d.ts +46 -4
- package/daemon/dist/domain/session-transport.d.ts.map +1 -1
- package/daemon/dist/domain/session-transport.js +492 -26
- package/daemon/dist/domain/session-transport.js.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.d.ts +10 -0
- package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.js +41 -4
- package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.d.ts +3 -7
- package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.js +6 -32
- package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
- package/daemon/dist/domain/terminal/terminal-service.d.ts +5 -1
- package/daemon/dist/domain/terminal/terminal-service.d.ts.map +1 -1
- package/daemon/dist/domain/terminal/terminal-service.js +30 -4
- package/daemon/dist/domain/terminal/terminal-service.js.map +1 -1
- package/daemon/dist/domain/terminal/view-composer.d.ts +6 -0
- package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -1
- package/daemon/dist/domain/terminal/view-composer.js +2 -1
- package/daemon/dist/domain/terminal/view-composer.js.map +1 -1
- package/daemon/dist/domain/transcript-store.js +1 -1
- package/daemon/dist/domain/transcript-store.js.map +1 -1
- package/daemon/dist/domain/types.d.ts +38 -0
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.js +5 -0
- package/daemon/dist/domain/types.js.map +1 -1
- package/daemon/dist/domain/usage-series.d.ts.map +1 -1
- package/daemon/dist/domain/usage-series.js +9 -4
- package/daemon/dist/domain/usage-series.js.map +1 -1
- package/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
- package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
- package/daemon/dist/domain/user-settings/settings-store.js +44 -0
- package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
- package/daemon/dist/domain/view-projector.d.ts +4 -0
- package/daemon/dist/domain/view-projector.d.ts.map +1 -1
- package/daemon/dist/domain/view-projector.js +19 -4
- package/daemon/dist/domain/view-projector.js.map +1 -1
- package/daemon/dist/domain/wake-resolver.js +2 -2
- package/daemon/dist/domain/wake-resolver.js.map +1 -1
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts.map +1 -1
- package/daemon/dist/domain/watchdog-jobs-repository.js +19 -3
- package/daemon/dist/domain/watchdog-jobs-repository.js.map +1 -1
- package/daemon/dist/domain/whoami-service.d.ts +4 -1
- package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
- package/daemon/dist/domain/whoami-service.js +25 -19
- package/daemon/dist/domain/whoami-service.js.map +1 -1
- package/daemon/dist/domain/workflow-runtime.d.ts +1 -1
- package/daemon/dist/domain/workspace/project-read.d.ts +2 -0
- package/daemon/dist/domain/workspace/project-read.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/project-read.js +19 -8
- package/daemon/dist/domain/workspace/project-read.js.map +1 -1
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +6 -0
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/activity.d.ts.map +1 -1
- package/daemon/dist/routes/activity.js +33 -1
- package/daemon/dist/routes/activity.js.map +1 -1
- package/daemon/dist/routes/chat.d.ts.map +1 -1
- package/daemon/dist/routes/chat.js +29 -4
- package/daemon/dist/routes/chat.js.map +1 -1
- package/daemon/dist/routes/projects.d.ts.map +1 -1
- package/daemon/dist/routes/projects.js +5 -1
- package/daemon/dist/routes/projects.js.map +1 -1
- package/daemon/dist/routes/proof.d.ts.map +1 -1
- package/daemon/dist/routes/proof.js +99 -10
- package/daemon/dist/routes/proof.js.map +1 -1
- package/daemon/dist/routes/provider.d.ts.map +1 -1
- package/daemon/dist/routes/provider.js +31 -0
- package/daemon/dist/routes/provider.js.map +1 -1
- package/daemon/dist/routes/query-limit.d.ts +19 -0
- package/daemon/dist/routes/query-limit.d.ts.map +1 -0
- package/daemon/dist/routes/query-limit.js +24 -0
- package/daemon/dist/routes/query-limit.js.map +1 -0
- package/daemon/dist/routes/queue.d.ts.map +1 -1
- package/daemon/dist/routes/queue.js +35 -12
- package/daemon/dist/routes/queue.js.map +1 -1
- package/daemon/dist/routes/rig-cmux.js +8 -10
- package/daemon/dist/routes/rig-cmux.js.map +1 -1
- package/daemon/dist/routes/rigs.d.ts.map +1 -1
- package/daemon/dist/routes/rigs.js +11 -7
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/scopes.d.ts.map +1 -1
- package/daemon/dist/routes/scopes.js +5 -3
- package/daemon/dist/routes/scopes.js.map +1 -1
- package/daemon/dist/routes/seat.d.ts.map +1 -1
- package/daemon/dist/routes/seat.js +32 -0
- package/daemon/dist/routes/seat.js.map +1 -1
- package/daemon/dist/routes/stream.d.ts.map +1 -1
- package/daemon/dist/routes/stream.js +5 -1
- package/daemon/dist/routes/stream.js.map +1 -1
- package/daemon/dist/routes/up.d.ts.map +1 -1
- package/daemon/dist/routes/up.js +2 -1
- package/daemon/dist/routes/up.js.map +1 -1
- package/daemon/dist/routes/views.d.ts.map +1 -1
- package/daemon/dist/routes/views.js +7 -1
- package/daemon/dist/routes/views.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +30 -1
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-startup-guide.md +19 -0
- package/daemon/docs/reference/getting-started.md +10 -6
- package/daemon/docs/reference/keeping-a-watch.md +156 -0
- package/daemon/docs/reference/rig-spec.md +2 -2
- package/daemon/docs/reference/sdlc-conventions.md +11 -1
- package/daemon/docs/reference/slack-app-setup.md +12 -4
- package/daemon/docs/reference/whats-new.md +151 -74
- package/daemon/specs/agents/development/qa/guidance/role.md +9 -0
- package/daemon/specs/agents/shared/skills/core/openrig-skills/SKILL.md +1 -1
- package/daemon/specs/agents/shared/skills/core/topology-mutation-and-seat-management/SKILL.md +2 -2
- package/daemon/specs/rigs/launch/factory/CULTURE.md +13 -0
- package/daemon/specs/rigs/launch/factory/guidance/lead-first-move.md +18 -5
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +20 -1
- package/daemon/specs/rigs/launch/starter/CULTURE.md +13 -0
- package/daemon/specs/rigs/launch/starter/guidance/lead-first-move.md +18 -5
- package/dist/build-info.js +3 -3
- package/dist/cli-error.d.ts.map +1 -1
- package/dist/cli-error.js +2 -0
- package/dist/cli-error.js.map +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +55 -4
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/capture.d.ts +9 -0
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +93 -41
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +6 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +44 -3
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +1 -50
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +6 -0
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/heartbeat.js +2 -2
- package/dist/commands/heartbeat.js.map +1 -1
- package/dist/commands/proof.d.ts.map +1 -1
- package/dist/commands/proof.js +11 -5
- package/dist/commands/proof.js.map +1 -1
- package/dist/commands/provider.d.ts.map +1 -1
- package/dist/commands/provider.js +72 -0
- package/dist/commands/provider.js.map +1 -1
- package/dist/commands/ps.d.ts +7 -0
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +20 -6
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +48 -5
- package/dist/commands/queue.d.ts.map +1 -1
- package/dist/commands/queue.js +215 -45
- package/dist/commands/queue.js.map +1 -1
- package/dist/commands/scope.d.ts.map +1 -1
- package/dist/commands/scope.js +57 -36
- package/dist/commands/scope.js.map +1 -1
- package/dist/commands/seat.d.ts.map +1 -1
- package/dist/commands/seat.js +167 -10
- package/dist/commands/seat.js.map +1 -1
- package/dist/commands/setup.d.ts +6 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +100 -44
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +9 -4
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +10 -0
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/usage.d.ts.map +1 -1
- package/dist/commands/usage.js +10 -5
- package/dist/commands/usage.js.map +1 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +8 -8
- package/dist/commands/workflow.js.map +1 -1
- package/dist/config-store.d.ts +8 -1
- package/dist/config-store.d.ts.map +1 -1
- package/dist/config-store.js +57 -0
- package/dist/config-store.js.map +1 -1
- package/dist/daemon-lifecycle.d.ts +4 -0
- package/dist/daemon-lifecycle.d.ts.map +1 -1
- package/dist/daemon-lifecycle.js +16 -4
- package/dist/daemon-lifecycle.js.map +1 -1
- package/dist/lib/scope/capability-delta.d.ts.map +1 -1
- package/dist/lib/scope/capability-delta.js +8 -0
- package/dist/lib/scope/capability-delta.js.map +1 -1
- package/dist/lib/scope/mission-composition.d.ts +5 -1
- package/dist/lib/scope/mission-composition.d.ts.map +1 -1
- package/dist/lib/scope/mission-composition.js +61 -1
- package/dist/lib/scope/mission-composition.js.map +1 -1
- package/dist/lib/scope/progress-edit.js +1 -1
- package/dist/lib/scope/progress-edit.js.map +1 -1
- package/dist/lib/scope/scope-fs.d.ts +2 -1
- package/dist/lib/scope/scope-fs.d.ts.map +1 -1
- package/dist/lib/scope/scope-fs.js +7 -7
- package/dist/lib/scope/scope-fs.js.map +1 -1
- package/dist/lib/scope/slice-claims.d.ts +8 -0
- package/dist/lib/scope/slice-claims.d.ts.map +1 -0
- package/dist/lib/scope/slice-claims.js +88 -0
- package/dist/lib/scope/slice-claims.js.map +1 -0
- package/dist/queue-receipt.d.ts +41 -0
- package/dist/queue-receipt.d.ts.map +1 -0
- package/dist/queue-receipt.js +272 -0
- package/dist/queue-receipt.js.map +1 -0
- package/dist/rig-handle.d.ts +45 -0
- package/dist/rig-handle.d.ts.map +1 -0
- package/dist/rig-handle.js +51 -0
- package/dist/rig-handle.js.map +1 -0
- package/dist/system-preflight.d.ts +5 -0
- package/dist/system-preflight.d.ts.map +1 -1
- package/dist/system-preflight.js +8 -0
- package/dist/system-preflight.js.map +1 -1
- package/dist/terminal-window.d.ts.map +1 -1
- package/dist/terminal-window.js +3 -1
- package/dist/terminal-window.js.map +1 -1
- package/package.json +1 -1
- package/tui/dist/config/config-model.d.ts.map +1 -1
- package/tui/dist/config/config-model.js +3 -0
- package/tui/dist/config/config-model.js.map +1 -1
- package/tui/dist/daemon-client.d.ts +3 -0
- package/tui/dist/daemon-client.d.ts.map +1 -1
- package/tui/dist/daemon-client.js +4 -1
- package/tui/dist/daemon-client.js.map +1 -1
- package/tui/dist/detail.d.ts.map +1 -1
- package/tui/dist/detail.js +6 -1
- package/tui/dist/detail.js.map +1 -1
- package/tui/dist/hydrate.d.ts.map +1 -1
- package/tui/dist/hydrate.js +30 -21
- package/tui/dist/hydrate.js.map +1 -1
- package/tui/dist/input.d.ts.map +1 -1
- package/tui/dist/input.js +15 -4
- package/tui/dist/input.js.map +1 -1
- package/tui/dist/local-reading.js +2 -2
- package/tui/dist/local-reading.js.map +1 -1
- package/tui/dist/pulse/pulse-model.d.ts +1 -0
- package/tui/dist/pulse/pulse-model.d.ts.map +1 -1
- package/tui/dist/pulse/pulse-model.js +7 -3
- package/tui/dist/pulse/pulse-model.js.map +1 -1
- package/tui/dist/pulse/render-pulse.d.ts.map +1 -1
- package/tui/dist/pulse/render-pulse.js +3 -1
- package/tui/dist/pulse/render-pulse.js.map +1 -1
- package/tui/dist/reading.d.ts.map +1 -1
- package/tui/dist/reading.js +14 -3
- package/tui/dist/reading.js.map +1 -1
- package/tui/dist/render.d.ts.map +1 -1
- package/tui/dist/render.js +26 -11
- package/tui/dist/render.js.map +1 -1
- package/tui/dist/types.d.ts +3 -0
- package/tui/dist/types.d.ts.map +1 -1
- package/ui/dist/assets/{index-D5n8EwkG.js → index-DhmxKuZf.js} +159 -159
- package/ui/dist/index.html +1 -1
|
@@ -7,6 +7,7 @@ import { observeSolePane } from "./pane-binding-observation.js";
|
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { NativePermissionStore } from "./native-permission-store.js";
|
|
9
9
|
import { validateNativePermissionSelection, unresolvedClaudePermissionModes } from "./native-permission-selection.js";
|
|
10
|
+
import { CodexInPlaceRestart, } from "./seat-restart-in-place.js";
|
|
10
11
|
/**
|
|
11
12
|
* S5 (OPR.0.5.4.7) — the seat-lifecycle verb surface: set-model, single-seat stop,
|
|
12
13
|
* dead-session clean. One coherent design (KI-5.3-9):
|
|
@@ -36,6 +37,9 @@ export class SeatLifecycleService {
|
|
|
36
37
|
runtimeAdapters;
|
|
37
38
|
occupantInvalidator;
|
|
38
39
|
activityOracle;
|
|
40
|
+
inPlaceRestartIo;
|
|
41
|
+
inPlaceRestartTiming;
|
|
42
|
+
inPlaceRestartDaemonStartedAt;
|
|
39
43
|
constructor(deps) {
|
|
40
44
|
if (deps.db !== deps.rigRepo.db)
|
|
41
45
|
throw new Error("SeatLifecycleService: rigRepo must share the same db handle");
|
|
@@ -54,6 +58,9 @@ export class SeatLifecycleService {
|
|
|
54
58
|
this.runtimeAdapters = deps.runtimeAdapters ?? {};
|
|
55
59
|
this.occupantInvalidator = deps.occupantInvalidator ?? null;
|
|
56
60
|
this.activityOracle = deps.activityOracle ?? null;
|
|
61
|
+
this.inPlaceRestartIo = deps.inPlaceRestartIo;
|
|
62
|
+
this.inPlaceRestartTiming = deps.inPlaceRestartTiming;
|
|
63
|
+
this.inPlaceRestartDaemonStartedAt = deps.inPlaceRestartDaemonStartedAt;
|
|
57
64
|
}
|
|
58
65
|
async setModel(input) {
|
|
59
66
|
const required = this.requireReason(input.reason);
|
|
@@ -174,7 +181,7 @@ export class SeatLifecycleService {
|
|
|
174
181
|
guidance: "A dead seat with stale records is returned to launchable with: rig seat clean",
|
|
175
182
|
};
|
|
176
183
|
}
|
|
177
|
-
return this.stopManagedTmuxSeat(resolved, session, input.reason, input.operator);
|
|
184
|
+
return this.stopManagedTmuxSeat(resolved, session, input.reason, input.operator, true);
|
|
178
185
|
}
|
|
179
186
|
async cleanSeat(input) {
|
|
180
187
|
const required = this.requireReason(input.reason);
|
|
@@ -309,30 +316,18 @@ export class SeatLifecycleService {
|
|
|
309
316
|
});
|
|
310
317
|
return { ...result, message: result.ok ? "Configured context delivered to the existing fresh conversation." : result.errors.join("; ") };
|
|
311
318
|
}
|
|
312
|
-
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
ok: false,
|
|
320
|
-
code: "fresh_required",
|
|
321
|
-
message: "Explicit fresh launch requires fresh=true (--fresh); no continuity mode is inferred.",
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
const resolved = this.resolveSeat(input.seatRef);
|
|
325
|
-
if ("code" in resolved)
|
|
326
|
-
return resolved;
|
|
327
|
-
const guard = this.tmuxAdapter.deliveryGuard;
|
|
328
|
-
if (guard && !guard.ownsLifecycle(resolved.nodeId)) {
|
|
329
|
-
return guard.lifecycle([resolved.nodeId], () => this.launchFresh(input));
|
|
330
|
-
}
|
|
319
|
+
/**
|
|
320
|
+
* Resolve a seat snapshot into current launch settings and persisted startup context.
|
|
321
|
+
* Return a refusal for stale seats, unavailable services, or runtime/context mismatch.
|
|
322
|
+
* Reads only: callers receive no reservation or launch guarantee. Execution repeats
|
|
323
|
+
* this resolution under its lifecycle lock rather than trusting an earlier plan.
|
|
324
|
+
*/
|
|
325
|
+
resolveFreshLaunch(resolved, seatRef) {
|
|
331
326
|
const seat = this.describe(resolved);
|
|
332
327
|
const rig = this.rigRepo.getRig(seat.rigId);
|
|
333
328
|
const node = rig?.nodes.find((candidate) => candidate.id === seat.nodeId);
|
|
334
329
|
if (!rig || !node) {
|
|
335
|
-
return { ok: false, code: "seat_not_found", message: `Seat "${
|
|
330
|
+
return { ok: false, code: "seat_not_found", message: `Seat "${seatRef}" no longer exists.`, guidance: SEAT_LOOKUP_GUIDANCE };
|
|
336
331
|
}
|
|
337
332
|
if (!this.nodeLauncher || !this.startupOrchestrator) {
|
|
338
333
|
return { ok: false, code: "launch_unavailable", message: "Fresh-launch services are unavailable in this daemon." };
|
|
@@ -357,15 +352,197 @@ export class SeatLifecycleService {
|
|
|
357
352
|
}
|
|
358
353
|
const canonicalSessionName = deriveCanonicalFromEntry(resolved.entry)
|
|
359
354
|
?? deriveSessionName(seat.rigName, seat.logicalId);
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
return { ok: true, resolved, seat, rig, node, adapter, startup: startup.context, canonicalSessionName, nodeLauncher: this.nodeLauncher, startupOrchestrator: this.startupOrchestrator };
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Validate an observed canonical collision against current managed rows and binding.
|
|
359
|
+
* `stop` authorizes only this matching occupant; it cannot authorize adopted or
|
|
360
|
+
* mismatched sessions. Return its session row or a refusal, including unknown pane
|
|
361
|
+
* observations, without stopping, repairing, or starting a tmux server.
|
|
362
|
+
*/
|
|
363
|
+
async validateFreshCollision(resolved, canonicalSessionName, stop) {
|
|
364
|
+
const currentSession = this.latestSession(resolved.nodeId);
|
|
365
|
+
const currentBinding = this.sessionRegistry.getBindingForNode(resolved.nodeId);
|
|
366
|
+
const currentManaged = currentSession !== null
|
|
367
|
+
&& !TERMINAL_SESSION_STATUSES.has(currentSession.status)
|
|
368
|
+
&& currentSession.origin !== "claimed"
|
|
369
|
+
&& currentSession.session_name === canonicalSessionName
|
|
370
|
+
&& currentBinding?.tmuxSession === canonicalSessionName;
|
|
371
|
+
if (!currentManaged) {
|
|
362
372
|
return {
|
|
363
373
|
ok: false,
|
|
364
|
-
code: "
|
|
365
|
-
message: `
|
|
374
|
+
code: "unmanaged_session_collision",
|
|
375
|
+
message: `Canonical tmux session "${canonicalSessionName}" exists but is not owned by this seat's current managed rows; refusing to overwrite it.`,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
if (!stop) {
|
|
379
|
+
return {
|
|
380
|
+
ok: false,
|
|
381
|
+
code: "session_live",
|
|
382
|
+
message: `Seat "${canonicalSessionName}" is live; fresh launch refuses without --stop.`,
|
|
383
|
+
guidance: "Re-run with --stop to end exactly this managed occupant, or use rig handover to carry context.",
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
const observedPane = await observeSolePane(this.tmuxAdapter, canonicalSessionName);
|
|
387
|
+
if (!observedPane.ok && observedPane.code === "tmux_unavailable") {
|
|
388
|
+
return {
|
|
389
|
+
ok: false,
|
|
390
|
+
code: "tmux_probe_failed",
|
|
391
|
+
message: `${observedPane.detail}; fresh launch refuses rather than kill without live occupant identity.`,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
if (!observedPane.ok || observedPane.pane !== currentBinding?.tmuxPane) {
|
|
395
|
+
return {
|
|
396
|
+
ok: false,
|
|
397
|
+
code: "unmanaged_session_collision",
|
|
398
|
+
message: `Canonical tmux session "${canonicalSessionName}" is live, but its pane does not match this seat's current managed binding; refusing to stop it.`,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
return currentSession;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Check historical rows/bindings that clean would touch, excluding the canonical name.
|
|
405
|
+
* Read-only tmux probes reject adopted, live, or unreadable historical occupants
|
|
406
|
+
* before any stop. Null means no historical blocker was observed; the caller must
|
|
407
|
+
* still validate the canonical occupant and recheck absence before launching.
|
|
408
|
+
*/
|
|
409
|
+
async validateFreshHistory(nodeId, canonicalSessionName, seatRef) {
|
|
410
|
+
const rows = this.nonTerminalSessions(nodeId);
|
|
411
|
+
if (rows.some(row => row.origin === "claimed")) {
|
|
412
|
+
return {
|
|
413
|
+
ok: false, code: "claimed_session",
|
|
414
|
+
message: `Seat "${seatRef}" has an adopted/operator-owned occupant; fresh launch refuses even with --stop.`,
|
|
366
415
|
guidance: "Stop the adopted process yourself, then run rig seat clean before launching fresh.",
|
|
367
416
|
};
|
|
368
417
|
}
|
|
418
|
+
const binding = this.sessionRegistry.getBindingForNode(nodeId);
|
|
419
|
+
const names = new Set([...rows.map(row => row.session_name), ...(binding?.tmuxSession ? [binding.tmuxSession] : [])]);
|
|
420
|
+
for (const name of names) {
|
|
421
|
+
if (name === canonicalSessionName)
|
|
422
|
+
continue;
|
|
423
|
+
const probe = await this.probeLiveness(name, "fresh launch refuses while historical occupant state is unknown");
|
|
424
|
+
if ("code" in probe)
|
|
425
|
+
return probe;
|
|
426
|
+
if (probe.state === "present")
|
|
427
|
+
return {
|
|
428
|
+
ok: false, code: "session_live",
|
|
429
|
+
message: `Historical session "${name}" is still live; fresh launch refuses to change this seat.`,
|
|
430
|
+
guidance: "rig seat stop targets the seat's latest session, not a selected historical session; it may stop the current occupant instead.",
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Snapshot one seat's proposed fresh launch; `fresh` is mandatory and `stop` is intent.
|
|
437
|
+
* No lifecycle lock, repair, material projection, native launch or persistent write
|
|
438
|
+
* is entered. Siblings are listed as unchanged; no seat is reserved by the result.
|
|
439
|
+
* Known blockers set launchable=false; otherwise incomplete observations yield null.
|
|
440
|
+
* Unreadable tmux remains incomplete, never readiness. No launch command is built.
|
|
441
|
+
* Errors are reduced to safe codes;
|
|
442
|
+
* startup text, credentials and process output are not included in the response.
|
|
443
|
+
*/
|
|
444
|
+
async planFresh(input) {
|
|
445
|
+
const refusal = (error) => ({
|
|
446
|
+
...error, planOnly: true, complete: error.code !== "tmux_probe_failed", launchable: false,
|
|
447
|
+
// Parser/probe errors can embed persisted startup content or process output.
|
|
448
|
+
message: `Fresh launch preview refused: ${error.code}.`,
|
|
449
|
+
});
|
|
450
|
+
if (!input.fresh)
|
|
451
|
+
return refusal({ ok: false, code: "fresh_required", message: "--plan requires --fresh." });
|
|
452
|
+
const resolved = this.resolveSeat(input.seatRef);
|
|
453
|
+
if ("code" in resolved)
|
|
454
|
+
return refusal(resolved);
|
|
455
|
+
const prepared = this.resolveFreshLaunch(resolved, input.seatRef);
|
|
456
|
+
if ("code" in prepared)
|
|
457
|
+
return refusal(prepared);
|
|
458
|
+
const { seat, rig, node, startup, canonicalSessionName } = prepared;
|
|
459
|
+
const blockers = [];
|
|
460
|
+
const warnings = ["Snapshot only; execution resolves and validates again. Native readiness is not checked."];
|
|
461
|
+
let complete = true;
|
|
462
|
+
let tmuxUnknown = false;
|
|
463
|
+
const guard = this.tmuxAdapter.deliveryGuard?.preference(node.id);
|
|
464
|
+
if (guard?.effective || guard?.desired)
|
|
465
|
+
blockers.push({ code: "typing_guard_enabled", message: "Typing protection blocks lifecycle operations for this seat." });
|
|
466
|
+
const record = (error) => {
|
|
467
|
+
if (error.code === "tmux_probe_failed") {
|
|
468
|
+
complete = false;
|
|
469
|
+
tmuxUnknown = true;
|
|
470
|
+
warnings.push("tmux state is unknown; no server was started and no occupant was changed.");
|
|
471
|
+
}
|
|
472
|
+
else if (error.code === "claimed_session" || error.code === "session_live") {
|
|
473
|
+
blockers.push({ code: error.code, message: error.message, guidance: error.guidance });
|
|
474
|
+
}
|
|
475
|
+
else
|
|
476
|
+
blockers.push({ code: error.code, message: `Fresh launch would be refused: ${error.code}.` });
|
|
477
|
+
};
|
|
478
|
+
const history = await this.validateFreshHistory(node.id, canonicalSessionName, input.seatRef);
|
|
479
|
+
if (history)
|
|
480
|
+
record(history);
|
|
481
|
+
const probe = await this.probeLiveness(canonicalSessionName, "preview does not repair tmux");
|
|
482
|
+
const currentOccupant = "code" in probe ? "unknown" : probe.state;
|
|
483
|
+
let stopRequired = currentOccupant === "absent" ? false : null;
|
|
484
|
+
let owned = false;
|
|
485
|
+
if ("code" in probe)
|
|
486
|
+
record(probe);
|
|
487
|
+
else if (probe.state === "present") {
|
|
488
|
+
// Check ownership even without --stop; presence alone is not permission to stop.
|
|
489
|
+
const collision = await this.validateFreshCollision(resolved, canonicalSessionName, true);
|
|
490
|
+
if ("code" in collision)
|
|
491
|
+
record(collision);
|
|
492
|
+
else {
|
|
493
|
+
owned = true;
|
|
494
|
+
stopRequired = true;
|
|
495
|
+
if (!input.stop)
|
|
496
|
+
blockers.push({ code: "session_live", message: "A live managed occupant requires --stop." });
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
const launchable = blockers.length > 0 ? false : complete ? true : null;
|
|
500
|
+
const siblings = rig.nodes.filter(n => n.id !== node.id).map(n => ({
|
|
501
|
+
logicalId: n.logicalId, sessionName: n.binding?.tmuxSession ?? null, effect: "unchanged",
|
|
502
|
+
}));
|
|
503
|
+
return {
|
|
504
|
+
ok: true, planOnly: true, complete, launchable, seat,
|
|
505
|
+
sessionName: canonicalSessionName, currentOccupant,
|
|
506
|
+
stopRequired, wouldStop: blockers.length > 0 ? false : tmuxUnknown ? null : owned && input.stop === true,
|
|
507
|
+
blockers, warnings, siblings,
|
|
508
|
+
startup: { projectionCount: startup.plan.entries.length,
|
|
509
|
+
fileCount: startup.resolvedStartupFiles.filter(f => f.appliesOn.includes("fresh_start")).length,
|
|
510
|
+
actionCount: startup.startupActions.filter(a => a.appliesOn.includes("fresh_start")).length },
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Execute a fresh replacement of exactly one seat, requiring fresh intent and reason.
|
|
515
|
+
* Resolve configuration again under the lifecycle lock, reject unsafe historical or
|
|
516
|
+
* canonical occupants, and require positive absence before creating a new occupant.
|
|
517
|
+
* Unlike planFresh this mutates lifecycle/startup state; an earlier preview grants
|
|
518
|
+
* no authority to skip validation. Sibling seats are never included in the operation.
|
|
519
|
+
*/
|
|
520
|
+
async launchFresh(input) {
|
|
521
|
+
const required = this.requireReason(input.reason);
|
|
522
|
+
if (required)
|
|
523
|
+
return required;
|
|
524
|
+
if (input.fresh !== true) {
|
|
525
|
+
return {
|
|
526
|
+
ok: false,
|
|
527
|
+
code: "fresh_required",
|
|
528
|
+
message: "Explicit fresh launch requires fresh=true (--fresh); no continuity mode is inferred.",
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
const resolved = this.resolveSeat(input.seatRef);
|
|
532
|
+
if ("code" in resolved)
|
|
533
|
+
return resolved;
|
|
534
|
+
const guard = this.tmuxAdapter.deliveryGuard;
|
|
535
|
+
if (guard && !guard.ownsLifecycle(resolved.nodeId)) {
|
|
536
|
+
return guard.lifecycle([resolved.nodeId], () => this.launchFresh(input));
|
|
537
|
+
}
|
|
538
|
+
const prepared = this.resolveFreshLaunch(resolved, input.seatRef);
|
|
539
|
+
if ("code" in prepared)
|
|
540
|
+
return prepared;
|
|
541
|
+
const { seat, node, adapter, startup, canonicalSessionName, nodeLauncher, startupOrchestrator } = prepared;
|
|
542
|
+
const historyRefusal = await this.validateFreshHistory(resolved.nodeId, canonicalSessionName, input.seatRef);
|
|
543
|
+
if (historyRefusal)
|
|
544
|
+
return historyRefusal;
|
|
545
|
+
const retiringRows = this.nonTerminalSessions(node.id);
|
|
369
546
|
// Detached is terminal for process cleanup, but remains a reboot candidate.
|
|
370
547
|
// A deliberate fresh launch must retire that prior history as well.
|
|
371
548
|
const supersededSessionIds = this.db.prepare("SELECT id FROM sessions WHERE node_id = ? AND status NOT IN ('superseded', 'exited')").all(node.id).map((row) => row.id);
|
|
@@ -403,44 +580,10 @@ export class SeatLifecycleService {
|
|
|
403
580
|
if ("code" in canonicalProbe)
|
|
404
581
|
return canonicalProbe;
|
|
405
582
|
if (canonicalProbe.state === "present") {
|
|
406
|
-
const currentSession = this.
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
&& currentSession.origin !== "claimed"
|
|
411
|
-
&& currentSession.session_name === canonicalSessionName
|
|
412
|
-
&& currentBinding?.tmuxSession === canonicalSessionName;
|
|
413
|
-
if (!currentManaged) {
|
|
414
|
-
return {
|
|
415
|
-
ok: false,
|
|
416
|
-
code: "unmanaged_session_collision",
|
|
417
|
-
message: `Canonical tmux session "${canonicalSessionName}" exists but is not owned by this seat's current managed rows; refusing to overwrite it.`,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
if (!input.stop) {
|
|
421
|
-
return {
|
|
422
|
-
ok: false,
|
|
423
|
-
code: "session_live",
|
|
424
|
-
message: `Seat "${input.seatRef}" is live; fresh launch refuses without --stop.`,
|
|
425
|
-
guidance: "Re-run with --stop to end exactly this managed occupant, or use rig handover to carry context.",
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
const observedPane = await observeSolePane(this.tmuxAdapter, canonicalSessionName);
|
|
429
|
-
if (!observedPane.ok && observedPane.code === "tmux_unavailable") {
|
|
430
|
-
return {
|
|
431
|
-
ok: false,
|
|
432
|
-
code: "tmux_probe_failed",
|
|
433
|
-
message: `${observedPane.detail}; fresh launch refuses rather than kill without live occupant identity.`,
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
if (!observedPane.ok || observedPane.pane !== currentBinding?.tmuxPane) {
|
|
437
|
-
return {
|
|
438
|
-
ok: false,
|
|
439
|
-
code: "unmanaged_session_collision",
|
|
440
|
-
message: `Canonical tmux session "${canonicalSessionName}" is live, but its pane does not match this seat's current managed binding; refusing to stop it.`,
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
const stopped = await this.stopManagedTmuxSeat(resolved, currentSession, input.reason, input.operator);
|
|
583
|
+
const currentSession = await this.validateFreshCollision(resolved, canonicalSessionName, input.stop === true);
|
|
584
|
+
if ("code" in currentSession)
|
|
585
|
+
return currentSession;
|
|
586
|
+
const stopped = await this.stopManagedTmuxSeat(resolved, currentSession, input.reason, input.operator, false);
|
|
444
587
|
if (!stopped.ok)
|
|
445
588
|
return stopped;
|
|
446
589
|
// Stopping the server's last session ends tmux's server, and every probe
|
|
@@ -481,7 +624,7 @@ export class SeatLifecycleService {
|
|
|
481
624
|
successorSessionName: canonicalSessionName,
|
|
482
625
|
...(retiringGeneration ? { retiringGeneration } : {}),
|
|
483
626
|
});
|
|
484
|
-
const launch = await
|
|
627
|
+
const launch = await nodeLauncher.launchNode(seat.rigId, seat.logicalId, {
|
|
485
628
|
sessionName: canonicalSessionName,
|
|
486
629
|
cwd: node.cwd ?? undefined,
|
|
487
630
|
occupantKind: "fresh",
|
|
@@ -500,7 +643,7 @@ export class SeatLifecycleService {
|
|
|
500
643
|
supersededSessionIds,
|
|
501
644
|
retiringGeneration,
|
|
502
645
|
newGeneration: null,
|
|
503
|
-
startupPolicyHash: startup.
|
|
646
|
+
startupPolicyHash: startup.hash,
|
|
504
647
|
model: node.model,
|
|
505
648
|
effort: node.effort ?? null,
|
|
506
649
|
reason: input.reason,
|
|
@@ -515,7 +658,7 @@ export class SeatLifecycleService {
|
|
|
515
658
|
const launchPosture = this.rigRepo.getNodePolicyProvenance(node.id)?.launchPosture
|
|
516
659
|
?? this.rigRepo.getRigPolicyProvenance(seat.rigId)?.launchPosture
|
|
517
660
|
?? "floor";
|
|
518
|
-
const startupResult = await
|
|
661
|
+
const startupResult = await startupOrchestrator.startNode({
|
|
519
662
|
rigId: seat.rigId,
|
|
520
663
|
nodeId: node.id,
|
|
521
664
|
sessionId: launch.session.id,
|
|
@@ -528,9 +671,9 @@ export class SeatLifecycleService {
|
|
|
528
671
|
launchPosture,
|
|
529
672
|
},
|
|
530
673
|
adapter,
|
|
531
|
-
plan: startup.
|
|
532
|
-
resolvedStartupFiles: startup.
|
|
533
|
-
startupActions: startup.
|
|
674
|
+
plan: startup.plan,
|
|
675
|
+
resolvedStartupFiles: startup.resolvedStartupFiles,
|
|
676
|
+
startupActions: startup.startupActions,
|
|
534
677
|
isRestore: false,
|
|
535
678
|
includeDurableObligations: true,
|
|
536
679
|
sessionName: canonicalSessionName,
|
|
@@ -543,7 +686,7 @@ export class SeatLifecycleService {
|
|
|
543
686
|
supersededSessionIds,
|
|
544
687
|
retiringGeneration,
|
|
545
688
|
newGeneration: generation,
|
|
546
|
-
startupPolicyHash: startup.
|
|
689
|
+
startupPolicyHash: startup.hash,
|
|
547
690
|
model: node.model,
|
|
548
691
|
effort: node.effort ?? null,
|
|
549
692
|
reason: input.reason,
|
|
@@ -608,7 +751,7 @@ export class SeatLifecycleService {
|
|
|
608
751
|
...(nativeSessionId ? {} : { nativeSessionIdReason: "scrape_miss" }),
|
|
609
752
|
model: node.model,
|
|
610
753
|
effort: node.effort ?? null,
|
|
611
|
-
startupPolicyHash: startup.
|
|
754
|
+
startupPolicyHash: startup.hash,
|
|
612
755
|
reason: input.reason.trim(),
|
|
613
756
|
operator: input.operator ?? null,
|
|
614
757
|
status: attentionRequired ? "attention_required" : "ready",
|
|
@@ -640,13 +783,125 @@ export class SeatLifecycleService {
|
|
|
640
783
|
generation,
|
|
641
784
|
model: node.model,
|
|
642
785
|
effort: node.effort ?? undefined,
|
|
643
|
-
startupPolicyHash: startup.
|
|
786
|
+
startupPolicyHash: startup.hash,
|
|
644
787
|
supersededSessionIds,
|
|
645
788
|
warnings: startupResult.warnings,
|
|
646
789
|
};
|
|
647
790
|
}
|
|
791
|
+
/**
|
|
792
|
+
* OPR.0.7.0.5 — restart one Codex seat in place so it reads its home's current account: same conversation,
|
|
793
|
+
* same pane, the settings it is running with now. `plan` runs every gate read-only. Activity (mid-turn,
|
|
794
|
+
* needs input) and child processes are reported for the operator to judge, not refused. Identity, typing
|
|
795
|
+
* guard, adopted sessions, unreadable tmux and settings drift are named refusals before any signal.
|
|
796
|
+
*/
|
|
797
|
+
async restartInPlace(input) {
|
|
798
|
+
if (!input.plan) {
|
|
799
|
+
const required = this.requireReason(input.reason ?? "");
|
|
800
|
+
if (required)
|
|
801
|
+
return required;
|
|
802
|
+
}
|
|
803
|
+
const resolved = this.resolveSeat(input.seatRef);
|
|
804
|
+
if ("code" in resolved)
|
|
805
|
+
return resolved;
|
|
806
|
+
const prepared = this.inPlaceRestarter();
|
|
807
|
+
if ("code" in prepared)
|
|
808
|
+
return prepared;
|
|
809
|
+
if (input.plan) {
|
|
810
|
+
const target = await this.inPlaceTarget(resolved, input.seatRef);
|
|
811
|
+
return "code" in target ? target : prepared.plan(target);
|
|
812
|
+
}
|
|
813
|
+
// Recorded before waiting for the lease: a restart that ran meanwhile refuses this one (no repeat
|
|
814
|
+
// on a slow reply).
|
|
815
|
+
const seenStartedSeq = prepared.latestStartedSeq(resolved.nodeId);
|
|
816
|
+
const run = async () => {
|
|
817
|
+
const target = await this.inPlaceTarget(resolved, input.seatRef);
|
|
818
|
+
if ("code" in target)
|
|
819
|
+
return target;
|
|
820
|
+
return prepared.execute(target, { reason: input.reason ?? "", operator: input.operator ?? null, seenStartedSeq });
|
|
821
|
+
};
|
|
822
|
+
const guard = this.tmuxAdapter.deliveryGuard;
|
|
823
|
+
return guard && !guard.ownsLifecycle(resolved.nodeId) ? guard.lifecycle([resolved.nodeId], run) : run();
|
|
824
|
+
}
|
|
825
|
+
/** `--verify`: report `moved` only with a completed tool turn since the restart and account-specific evidence. */
|
|
826
|
+
async verifyRestartInPlace(input) {
|
|
827
|
+
const resolved = this.resolveSeat(input.seatRef);
|
|
828
|
+
if ("code" in resolved)
|
|
829
|
+
return resolved;
|
|
830
|
+
const prepared = this.inPlaceRestarter();
|
|
831
|
+
if ("code" in prepared)
|
|
832
|
+
return prepared;
|
|
833
|
+
const target = await this.inPlaceTarget(resolved, input.seatRef);
|
|
834
|
+
return "code" in target ? target : prepared.verify(target, { expectAccount: input.expectAccount ?? null });
|
|
835
|
+
}
|
|
836
|
+
inPlaceRestarter() {
|
|
837
|
+
const adapter = this.runtimeAdapters["codex"];
|
|
838
|
+
if (!adapter?.buildResumeCommand || !adapter.verifyResumeInPane || !adapter.sendResumeCommand) {
|
|
839
|
+
return { ok: false, code: "runtime_adapter_missing", message: "The Codex runtime adapter with in-place resume is unavailable in this daemon." };
|
|
840
|
+
}
|
|
841
|
+
const activity = this.activityOracle?.getSeatState ? this.activityOracle : null;
|
|
842
|
+
return new CodexInPlaceRestart({
|
|
843
|
+
db: this.db, sessionRegistry: this.sessionRegistry, eventBus: this.eventBus, tmux: this.tmuxAdapter,
|
|
844
|
+
codex: adapter, activity, listProcesses: this.listProcesses,
|
|
845
|
+
io: this.inPlaceRestartIo, timing: this.inPlaceRestartTiming, daemonStartedAt: this.inPlaceRestartDaemonStartedAt,
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
/** The shared seat refusals, then the binding the relaunch is built from (the handover's posture rules). */
|
|
849
|
+
async inPlaceTarget(resolved, seatRef) {
|
|
850
|
+
const seat = this.describe(resolved);
|
|
851
|
+
const node = this.rigRepo.getRig(seat.rigId)?.nodes.find((candidate) => candidate.id === seat.nodeId);
|
|
852
|
+
if (!node)
|
|
853
|
+
return { ok: false, code: "seat_not_found", message: `Seat "${seatRef}" no longer exists.`, guidance: SEAT_LOOKUP_GUIDANCE };
|
|
854
|
+
if (node.runtime !== "codex") {
|
|
855
|
+
return { ok: false, code: "not_codex", message: `Seat "${seatRef}" runs ${node.runtime ?? "an unknown runtime"}; in-place restart supports Codex seats only.` };
|
|
856
|
+
}
|
|
857
|
+
const preference = this.tmuxAdapter.deliveryGuard?.preference(node.id);
|
|
858
|
+
if (preference?.effective || preference?.desired) {
|
|
859
|
+
return { ok: false, code: "typing_guard_enabled", message: "Typing protection blocks lifecycle operations for this seat; nothing was restarted." };
|
|
860
|
+
}
|
|
861
|
+
const session = this.latestSession(node.id);
|
|
862
|
+
if (!session || TERMINAL_SESSION_STATUSES.has(session.status)) {
|
|
863
|
+
return { ok: false, code: "no_session", message: `Seat "${seatRef}" has no live managed session to restart (checked: latest sessions row).` };
|
|
864
|
+
}
|
|
865
|
+
if (session.origin === "claimed") {
|
|
866
|
+
return { ok: false, code: "claimed_session", message: `Session "${session.session_name}" was adopted (origin=claimed), not launched by OpenRig; in-place restart refuses it.`,
|
|
867
|
+
guidance: "Release an adopted session with: rig unclaim" };
|
|
868
|
+
}
|
|
869
|
+
const probed = await this.probeLiveness(session.session_name, "in-place restart refuses rather than act on an unknown session");
|
|
870
|
+
if ("code" in probed)
|
|
871
|
+
return probed;
|
|
872
|
+
if (probed.state === "absent") {
|
|
873
|
+
return { ok: false, code: "session_not_live", message: `Session "${session.session_name}" is absent in tmux; there is nothing to restart in place.` };
|
|
874
|
+
}
|
|
875
|
+
const binding = this.sessionRegistry.getBindingForNode(node.id);
|
|
876
|
+
if (!binding?.tmuxSession || binding.tmuxSession !== session.session_name || !binding.tmuxPane) {
|
|
877
|
+
return { ok: false, code: "session_not_live", message: `Seat "${seatRef}" has no bound tmux pane for session "${session.session_name}".` };
|
|
878
|
+
}
|
|
879
|
+
let permissionOverride;
|
|
880
|
+
try {
|
|
881
|
+
permissionOverride = new NativePermissionStore(this.db).launchOverride(node.id, "codex");
|
|
882
|
+
}
|
|
883
|
+
catch (error) {
|
|
884
|
+
return { ok: false, code: "permission_selection_refused", message: `Permission selection: ${error.message}` };
|
|
885
|
+
}
|
|
886
|
+
const launchPosture = permissionOverride.launchPosture
|
|
887
|
+
?? this.rigRepo.getNodePolicyProvenance(node.id)?.launchPosture
|
|
888
|
+
?? this.rigRepo.getRigPolicyProvenance(seat.rigId)?.launchPosture
|
|
889
|
+
?? "floor";
|
|
890
|
+
return {
|
|
891
|
+
seat, sessionId: session.id, sessionName: session.session_name,
|
|
892
|
+
saved: { model: node.model ?? null, effort: node.effort ?? null, codexConfigProfile: node.codexConfigProfile ?? null },
|
|
893
|
+
binding: {
|
|
894
|
+
...binding, cwd: node.cwd ?? ".",
|
|
895
|
+
...(node.model ? { model: node.model } : {}),
|
|
896
|
+
...(node.effort ? { effort: node.effort } : {}),
|
|
897
|
+
...(node.codexConfigProfile ? { codexConfigProfile: node.codexConfigProfile } : {}),
|
|
898
|
+
launchPosture, kernelAuthority: permissionOverride.kernelAuthority, teamPermissionDefault: permissionOverride.teamPermissionDefault,
|
|
899
|
+
nonInterruptive: this.rigRepo.getRigNonInterruptive(seat.rigId),
|
|
900
|
+
},
|
|
901
|
+
};
|
|
902
|
+
}
|
|
648
903
|
// -- shared internals --
|
|
649
|
-
async stopManagedTmuxSeat(resolved, session, reason, operator) {
|
|
904
|
+
async stopManagedTmuxSeat(resolved, session, reason, operator, recordStopIntent) {
|
|
650
905
|
const seat = this.describe(resolved);
|
|
651
906
|
const kill = await this.tmuxAdapter.killSession(session.session_name);
|
|
652
907
|
if (kill && !kill.ok && kill.code !== "session_not_found") {
|
|
@@ -658,7 +913,13 @@ export class SeatLifecycleService {
|
|
|
658
913
|
}
|
|
659
914
|
let persisted = null;
|
|
660
915
|
const tx = this.db.transaction(() => {
|
|
661
|
-
|
|
916
|
+
if (recordStopIntent && kill?.ok) {
|
|
917
|
+
this.sessionRegistry.markIntentionallyStopped(session.id);
|
|
918
|
+
}
|
|
919
|
+
else {
|
|
920
|
+
// An internal replacement stop or an unconfirmed kill must still affect health.
|
|
921
|
+
this.sessionRegistry.updateStatus(session.id, "exited");
|
|
922
|
+
}
|
|
662
923
|
this.sessionRegistry.clearBinding(resolved.nodeId);
|
|
663
924
|
persisted = this.eventBus.persistWithinTransaction({
|
|
664
925
|
type: "session.stopped",
|