@openrig/cli 0.4.4 → 0.4.6
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/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +6 -8
- package/daemon/assets/plugins/openrig-core/skills/openrig-cmux/SKILL.md +86 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-herdr/SKILL.md +158 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +744 -96
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +12 -8
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/pi-resume.d.ts +32 -0
- package/daemon/dist/adapters/pi-resume.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-resume.js +125 -0
- package/daemon/dist/adapters/pi-resume.js.map +1 -0
- package/daemon/dist/adapters/pi-runner-protocol.d.ts +88 -0
- package/daemon/dist/adapters/pi-runner-protocol.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-runner-protocol.js +153 -0
- package/daemon/dist/adapters/pi-runner-protocol.js.map +1 -0
- package/daemon/dist/adapters/pi-runner.d.ts +99 -0
- package/daemon/dist/adapters/pi-runner.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-runner.js +519 -0
- package/daemon/dist/adapters/pi-runner.js.map +1 -0
- package/daemon/dist/adapters/pi-runtime-adapter.d.ts +61 -0
- package/daemon/dist/adapters/pi-runtime-adapter.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-runtime-adapter.js +356 -0
- package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -0
- package/daemon/dist/adapters/tmux.d.ts +22 -1
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +40 -1
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/build-info.js +3 -3
- package/daemon/dist/builtins/workflow-specs/branched-remediation.yaml +31 -0
- package/daemon/dist/builtins/workflow-specs/factory-rsi.yaml +152 -0
- package/daemon/dist/builtins/workflow-specs/gated-release.yaml +26 -0
- package/daemon/dist/builtins/workflow-specs/linear-build.yaml +21 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.d.ts +20 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.d.ts.map +1 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.js +24 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.js.map +1 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.d.ts +22 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.d.ts.map +1 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.js +26 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.js.map +1 -0
- package/daemon/dist/db/migrations/051_workflow_resume.d.ts +22 -0
- package/daemon/dist/db/migrations/051_workflow_resume.d.ts.map +1 -0
- package/daemon/dist/db/migrations/051_workflow_resume.js +27 -0
- package/daemon/dist/db/migrations/051_workflow_resume.js.map +1 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.d.ts +26 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.d.ts.map +1 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.js +30 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.js.map +1 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.d.ts +48 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.d.ts.map +1 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.js +53 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.js.map +1 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.d.ts +34 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.d.ts.map +1 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.js +49 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.js.map +1 -0
- package/daemon/dist/domain/claim-service.d.ts +11 -0
- package/daemon/dist/domain/claim-service.d.ts.map +1 -1
- package/daemon/dist/domain/claim-service.js +3 -1
- package/daemon/dist/domain/claim-service.js.map +1 -1
- package/daemon/dist/domain/discovery-types.d.ts +1 -1
- package/daemon/dist/domain/discovery-types.d.ts.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-reader.js +19 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts +11 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.js +54 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.js.map +1 -0
- package/daemon/dist/domain/hosts/read-through.d.ts +28 -0
- package/daemon/dist/domain/hosts/read-through.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/read-through.js +139 -0
- package/daemon/dist/domain/hosts/read-through.js.map +1 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts +21 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -1
- package/daemon/dist/domain/hosts/remote-daemon-http.js +49 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -1
- package/daemon/dist/domain/node-inventory.d.ts +18 -0
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +206 -95
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/node-launcher.d.ts +11 -0
- package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/node-launcher.js +10 -0
- package/daemon/dist/domain/node-launcher.js.map +1 -1
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts +7 -0
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -1
- package/daemon/dist/domain/policies/workflow-keepalive.js +93 -13
- package/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -1
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +37 -26
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +105 -0
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
- package/daemon/dist/domain/queue-repository.js +193 -4
- package/daemon/dist/domain/queue-repository.js.map +1 -1
- package/daemon/dist/domain/queue-retention.d.ts +130 -0
- package/daemon/dist/domain/queue-retention.d.ts.map +1 -0
- package/daemon/dist/domain/queue-retention.js +224 -0
- package/daemon/dist/domain/queue-retention.js.map +1 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts +5 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +29 -2
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/resume-token-capture.d.ts +13 -0
- package/daemon/dist/domain/resume-token-capture.d.ts.map +1 -1
- package/daemon/dist/domain/resume-token-capture.js +14 -1
- package/daemon/dist/domain/resume-token-capture.js.map +1 -1
- package/daemon/dist/domain/resume-token-validation.d.ts +1 -1
- package/daemon/dist/domain/resume-token-validation.d.ts.map +1 -1
- package/daemon/dist/domain/resume-token-validation.js +58 -10
- package/daemon/dist/domain/resume-token-validation.js.map +1 -1
- package/daemon/dist/domain/review/compose.d.ts +50 -1
- package/daemon/dist/domain/review/compose.d.ts.map +1 -1
- package/daemon/dist/domain/review/compose.js +92 -3
- package/daemon/dist/domain/review/compose.js.map +1 -1
- package/daemon/dist/domain/review/fleet-compose.d.ts +52 -0
- package/daemon/dist/domain/review/fleet-compose.d.ts.map +1 -0
- package/daemon/dist/domain/review/fleet-compose.js +294 -0
- package/daemon/dist/domain/review/fleet-compose.js.map +1 -0
- package/daemon/dist/domain/review/gather.d.ts +16 -1
- package/daemon/dist/domain/review/gather.d.ts.map +1 -1
- package/daemon/dist/domain/review/gather.js +177 -41
- package/daemon/dist/domain/review/gather.js.map +1 -1
- package/daemon/dist/domain/review/types.d.ts +104 -1
- package/daemon/dist/domain/review/types.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.js +3 -0
- package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
- package/daemon/dist/domain/rig-repository.d.ts +7 -6
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +33 -11
- package/daemon/dist/domain/rig-repository.js.map +1 -1
- package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-codec.js +3 -0
- package/daemon/dist/domain/rigspec-codec.js.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.js +4 -0
- package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.js +11 -0
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.d.ts +6 -0
- package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.js +26 -1
- package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
- package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-schema.js +20 -1
- package/daemon/dist/domain/rigspec-schema.js.map +1 -1
- package/daemon/dist/domain/runtime-verifier.d.ts +7 -1
- package/daemon/dist/domain/runtime-verifier.d.ts.map +1 -1
- package/daemon/dist/domain/runtime-verifier.js +39 -1
- package/daemon/dist/domain/runtime-verifier.js.map +1 -1
- package/daemon/dist/domain/seat-handover-service.d.ts +9 -0
- package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-handover-service.js +2 -0
- package/daemon/dist/domain/seat-handover-service.js.map +1 -1
- package/daemon/dist/domain/seat-identity-store.d.ts +7 -0
- package/daemon/dist/domain/seat-identity-store.d.ts.map +1 -1
- package/daemon/dist/domain/seat-identity-store.js +27 -0
- package/daemon/dist/domain/seat-identity-store.js.map +1 -1
- package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-status-service.js +6 -4
- package/daemon/dist/domain/seat-status-service.js.map +1 -1
- package/daemon/dist/domain/session-name.d.ts +22 -0
- package/daemon/dist/domain/session-name.d.ts.map +1 -1
- package/daemon/dist/domain/session-name.js +29 -0
- package/daemon/dist/domain/session-name.js.map +1 -1
- package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
- package/daemon/dist/domain/slices/slice-detail-projector.js +4 -5
- package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
- package/daemon/dist/domain/spec-library-workflow-scanner.d.ts +18 -2
- package/daemon/dist/domain/spec-library-workflow-scanner.d.ts.map +1 -1
- package/daemon/dist/domain/spec-library-workflow-scanner.js +23 -1
- package/daemon/dist/domain/spec-library-workflow-scanner.js.map +1 -1
- package/daemon/dist/domain/startup-proof.d.ts +10 -6
- package/daemon/dist/domain/startup-proof.d.ts.map +1 -1
- package/daemon/dist/domain/startup-proof.js +35 -7
- package/daemon/dist/domain/startup-proof.js.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.d.ts +16 -0
- package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.js +13 -0
- package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
- package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts +27 -0
- package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/cmux-provider-adapter.js +67 -0
- package/daemon/dist/domain/terminal/cmux-provider-adapter.js.map +1 -0
- package/daemon/dist/domain/terminal/herdr-adapter.d.ts +77 -0
- package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/herdr-adapter.js +266 -0
- package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -0
- package/daemon/dist/domain/terminal/herdr-transport.d.ts +50 -0
- package/daemon/dist/domain/terminal/herdr-transport.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/herdr-transport.js +145 -0
- package/daemon/dist/domain/terminal/herdr-transport.js.map +1 -0
- package/daemon/dist/domain/terminal/terminal-provider.d.ts +88 -0
- package/daemon/dist/domain/terminal/terminal-provider.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/terminal-provider.js +17 -0
- package/daemon/dist/domain/terminal/terminal-provider.js.map +1 -0
- package/daemon/dist/domain/terminal/terminal-service.d.ts +60 -0
- package/daemon/dist/domain/terminal/terminal-service.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/terminal-service.js +174 -0
- package/daemon/dist/domain/terminal/terminal-service.js.map +1 -0
- package/daemon/dist/domain/terminal/terminal-views-store.d.ts +77 -0
- package/daemon/dist/domain/terminal/terminal-views-store.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/terminal-views-store.js +146 -0
- package/daemon/dist/domain/terminal/terminal-views-store.js.map +1 -0
- package/daemon/dist/domain/terminal/view-composer.d.ts +42 -0
- package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/view-composer.js +137 -0
- package/daemon/dist/domain/terminal/view-composer.js.map +1 -0
- package/daemon/dist/domain/tmux-option-defaults.d.ts +89 -0
- package/daemon/dist/domain/tmux-option-defaults.d.ts.map +1 -0
- package/daemon/dist/domain/tmux-option-defaults.js +132 -0
- package/daemon/dist/domain/tmux-option-defaults.js.map +1 -0
- package/daemon/dist/domain/types.d.ts +34 -1
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.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 +92 -0
- package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
- package/daemon/dist/domain/workflow/slice-workflow-projection.d.ts.map +1 -1
- package/daemon/dist/domain/workflow/slice-workflow-projection.js +6 -2
- package/daemon/dist/domain/workflow/slice-workflow-projection.js.map +1 -1
- package/daemon/dist/domain/workflow-boot-sweep.d.ts +28 -0
- package/daemon/dist/domain/workflow-boot-sweep.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-boot-sweep.js +102 -0
- package/daemon/dist/domain/workflow-boot-sweep.js.map +1 -0
- package/daemon/dist/domain/workflow-deadline.d.ts +74 -0
- package/daemon/dist/domain/workflow-deadline.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-deadline.js +165 -0
- package/daemon/dist/domain/workflow-deadline.js.map +1 -0
- package/daemon/dist/domain/workflow-exception-escalation.d.ts +33 -0
- package/daemon/dist/domain/workflow-exception-escalation.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-exception-escalation.js +104 -0
- package/daemon/dist/domain/workflow-exception-escalation.js.map +1 -0
- package/daemon/dist/domain/workflow-exception-router.d.ts +33 -0
- package/daemon/dist/domain/workflow-exception-router.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-exception-router.js +96 -0
- package/daemon/dist/domain/workflow-exception-router.js.map +1 -0
- package/daemon/dist/domain/workflow-exception.d.ts +90 -0
- package/daemon/dist/domain/workflow-exception.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-exception.js +122 -0
- package/daemon/dist/domain/workflow-exception.js.map +1 -0
- package/daemon/dist/domain/workflow-frontier-guard.d.ts +24 -0
- package/daemon/dist/domain/workflow-frontier-guard.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-frontier-guard.js +30 -0
- package/daemon/dist/domain/workflow-frontier-guard.js.map +1 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts +28 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-instance-store.js +66 -10
- package/daemon/dist/domain/workflow-instance-store.js.map +1 -1
- package/daemon/dist/domain/workflow-keepalive-arming.d.ts +35 -0
- package/daemon/dist/domain/workflow-keepalive-arming.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-keepalive-arming.js +87 -0
- package/daemon/dist/domain/workflow-keepalive-arming.js.map +1 -0
- package/daemon/dist/domain/workflow-projector.d.ts +117 -2
- package/daemon/dist/domain/workflow-projector.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-projector.js +672 -41
- package/daemon/dist/domain/workflow-projector.js.map +1 -1
- package/daemon/dist/domain/workflow-role-context.d.ts +57 -0
- package/daemon/dist/domain/workflow-role-context.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-role-context.js +120 -0
- package/daemon/dist/domain/workflow-role-context.js.map +1 -0
- package/daemon/dist/domain/workflow-role-resolver.d.ts +65 -0
- package/daemon/dist/domain/workflow-role-resolver.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-role-resolver.js +108 -0
- package/daemon/dist/domain/workflow-role-resolver.js.map +1 -0
- package/daemon/dist/domain/workflow-runtime.d.ts +157 -1
- package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-runtime.js +718 -11
- package/daemon/dist/domain/workflow-runtime.js.map +1 -1
- package/daemon/dist/domain/workflow-spec-cache.d.ts +26 -1
- package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-spec-cache.js +327 -13
- package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
- package/daemon/dist/domain/workflow-types.d.ts +143 -8
- package/daemon/dist/domain/workflow-types.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-types.js +14 -1
- package/daemon/dist/domain/workflow-types.js.map +1 -1
- package/daemon/dist/domain/workflow-validator.d.ts +11 -1
- package/daemon/dist/domain/workflow-validator.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-validator.js +246 -1
- package/daemon/dist/domain/workflow-validator.js.map +1 -1
- package/daemon/dist/index.d.ts +17 -0
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +44 -0
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/activity.js +22 -0
- package/daemon/dist/routes/activity.js.map +1 -1
- package/daemon/dist/routes/hosts.d.ts +5 -0
- package/daemon/dist/routes/hosts.d.ts.map +1 -0
- package/daemon/dist/routes/hosts.js +346 -0
- package/daemon/dist/routes/hosts.js.map +1 -0
- package/daemon/dist/routes/queue.d.ts +2 -7
- package/daemon/dist/routes/queue.d.ts.map +1 -1
- package/daemon/dist/routes/queue.js +264 -9
- package/daemon/dist/routes/queue.js.map +1 -1
- package/daemon/dist/routes/review.d.ts.map +1 -1
- package/daemon/dist/routes/review.js +26 -0
- package/daemon/dist/routes/review.js.map +1 -1
- package/daemon/dist/routes/seat.js +13 -0
- package/daemon/dist/routes/seat.js.map +1 -1
- package/daemon/dist/routes/terminal.d.ts +11 -0
- package/daemon/dist/routes/terminal.d.ts.map +1 -0
- package/daemon/dist/routes/terminal.js +104 -0
- package/daemon/dist/routes/terminal.js.map +1 -0
- package/daemon/dist/routes/workflow.d.ts.map +1 -1
- package/daemon/dist/routes/workflow.js +102 -10
- package/daemon/dist/routes/workflow.js.map +1 -1
- package/daemon/dist/server.d.ts +5 -0
- package/daemon/dist/server.d.ts.map +1 -1
- package/daemon/dist/server.js +22 -0
- package/daemon/dist/server.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +221 -12
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +29 -0
- package/daemon/specs/agents/factory-rsi/dogfood/guidance/role.md +37 -0
- package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +29 -0
- package/daemon/specs/agents/factory-rsi/release-manager/guidance/role.md +40 -0
- package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +6 -8
- package/daemon/specs/agents/shared/skills/core/openrig-cmux/SKILL.md +86 -0
- package/daemon/specs/agents/shared/skills/core/openrig-herdr/SKILL.md +158 -0
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +6 -6
- package/daemon/specs/rigs/launch/factory-rsi/CULTURE.md +47 -0
- package/daemon/specs/rigs/launch/factory-rsi/rig.yaml +115 -0
- package/dist/build-info.js +3 -3
- package/dist/commands/broadcast.d.ts +6 -1
- package/dist/commands/broadcast.d.ts.map +1 -1
- package/dist/commands/broadcast.js +101 -15
- package/dist/commands/broadcast.js.map +1 -1
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +99 -8
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +4 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +5 -0
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/host.d.ts +14 -0
- package/dist/commands/host.d.ts.map +1 -1
- package/dist/commands/host.js +338 -14
- package/dist/commands/host.js.map +1 -1
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +5 -0
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +10 -4
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +36 -0
- package/dist/commands/queue.d.ts.map +1 -1
- package/dist/commands/queue.js +73 -7
- package/dist/commands/queue.js.map +1 -1
- package/dist/commands/restore-packet.d.ts.map +1 -1
- package/dist/commands/restore-packet.js +13 -2
- package/dist/commands/restore-packet.js.map +1 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +114 -9
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/terminal.d.ts +6 -0
- package/dist/commands/terminal.d.ts.map +1 -0
- package/dist/commands/terminal.js +116 -0
- package/dist/commands/terminal.js.map +1 -0
- package/dist/commands/transcript.d.ts +6 -1
- package/dist/commands/transcript.d.ts.map +1 -1
- package/dist/commands/transcript.js +113 -30
- package/dist/commands/transcript.js.map +1 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +9 -0
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +11 -0
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workflow-errors.d.ts +23 -0
- package/dist/commands/workflow-errors.d.ts.map +1 -0
- package/dist/commands/workflow-errors.js +100 -0
- package/dist/commands/workflow-errors.js.map +1 -0
- package/dist/commands/workflow-follow.d.ts +71 -0
- package/dist/commands/workflow-follow.d.ts.map +1 -0
- package/dist/commands/workflow-follow.js +259 -0
- package/dist/commands/workflow-follow.js.map +1 -0
- package/dist/commands/workflow-render.d.ts +114 -0
- package/dist/commands/workflow-render.d.ts.map +1 -0
- package/dist/commands/workflow-render.js +223 -0
- package/dist/commands/workflow-render.js.map +1 -0
- package/dist/commands/workflow.d.ts +1 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +278 -14
- package/dist/commands/workflow.js.map +1 -1
- package/dist/config-store.d.ts +15 -1
- package/dist/config-store.d.ts.map +1 -1
- package/dist/config-store.js +103 -0
- package/dist/config-store.js.map +1 -1
- package/dist/cross-host-cli-helpers.d.ts +13 -0
- package/dist/cross-host-cli-helpers.d.ts.map +1 -1
- package/dist/cross-host-cli-helpers.js +27 -0
- package/dist/cross-host-cli-helpers.js.map +1 -1
- package/dist/cross-host-target.d.ts +49 -0
- package/dist/cross-host-target.d.ts.map +1 -0
- package/dist/cross-host-target.js +35 -0
- package/dist/cross-host-target.js.map +1 -0
- package/dist/host-registry.d.ts +8 -0
- package/dist/host-registry.d.ts.map +1 -1
- package/dist/host-registry.js +32 -0
- package/dist/host-registry.js.map +1 -1
- package/dist/host-selection.d.ts +13 -0
- package/dist/host-selection.d.ts.map +1 -0
- package/dist/host-selection.js +54 -0
- package/dist/host-selection.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/remote-host-ops.d.ts +1 -0
- package/dist/remote-host-ops.d.ts.map +1 -1
- package/dist/remote-host-ops.js +11 -4
- package/dist/remote-host-ops.js.map +1 -1
- package/dist/session-name.d.ts +23 -0
- package/dist/session-name.d.ts.map +1 -0
- package/dist/session-name.js +61 -0
- package/dist/session-name.js.map +1 -0
- package/package.json +1 -1
- package/ui/dist/assets/index-CFqxa0zW.css +32 -0
- package/ui/dist/assets/index-zrFqS7gL.js +623 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-D69ZhNIr.js +0 -598
- package/ui/dist/assets/index-DJYun-8d.css +0 -32
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// OPR.0.4.6.02 C2 — the terminal-views store.
|
|
2
|
+
//
|
|
3
|
+
// SAVED views persist to `terminal-views.yaml` at the OPENRIG_HOME root
|
|
4
|
+
// (VM-isolatable via OPENRIG_HOME). They are write-once/read-at-launch: the
|
|
5
|
+
// daemon reads them at launch and the operator's saved layouts survive
|
|
6
|
+
// restarts. Each saved member carries a STRUCTURED `host` field (a host id,
|
|
7
|
+
// never a `member@rig@host` string — MH BR-1).
|
|
8
|
+
//
|
|
9
|
+
// DERIVED views (per-rig / per-mission / per-slice) are computed LIVE from the
|
|
10
|
+
// live seat inventory + the review agents band and are NEVER written to disk
|
|
11
|
+
// (A3). That invariant is structural, not conventional: this module exposes
|
|
12
|
+
// `deriveViewMembers` (a pure mapper) and a `save()` that only ever accepts a
|
|
13
|
+
// `SavedView` — there is no code path that persists a derived view.
|
|
14
|
+
//
|
|
15
|
+
// Writes are atomic (tmp + rename on the same filesystem) and byte-stable:
|
|
16
|
+
// serialization uses a fixed field order and OMITS absent optionals (never
|
|
17
|
+
// null), so a read→save round-trip of the same logical content is idempotent.
|
|
18
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
20
|
+
import { getDefaultOpenRigPath } from "../../openrig-compat.js";
|
|
21
|
+
const EMPTY_FILE = { version: 1, views: [] };
|
|
22
|
+
/** Build a member object in fixed key order, omitting absent optionals (never null). */
|
|
23
|
+
function normalizeMember(m) {
|
|
24
|
+
const out = { seat: m.seat };
|
|
25
|
+
if (m.label != null && m.label !== "")
|
|
26
|
+
out.label = m.label;
|
|
27
|
+
if (m.host != null && m.host !== "")
|
|
28
|
+
out.host = m.host;
|
|
29
|
+
if (m.tmuxSession != null && m.tmuxSession !== "")
|
|
30
|
+
out.tmuxSession = m.tmuxSession;
|
|
31
|
+
if (m.readOnly === true)
|
|
32
|
+
out.readOnly = true;
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function normalizeView(v) {
|
|
36
|
+
return { id: v.id, name: v.name, members: v.members.map(normalizeMember) };
|
|
37
|
+
}
|
|
38
|
+
/** Canonical byte-stable serialization of the whole file (fixed order, omit-when-absent). */
|
|
39
|
+
function serialize(file) {
|
|
40
|
+
const normalized = {
|
|
41
|
+
version: 1,
|
|
42
|
+
views: file.views.map(normalizeView),
|
|
43
|
+
};
|
|
44
|
+
return stringifyYaml(normalized);
|
|
45
|
+
}
|
|
46
|
+
export class TerminalViewsStore {
|
|
47
|
+
path;
|
|
48
|
+
constructor(path = getDefaultOpenRigPath("terminal-views.yaml")) {
|
|
49
|
+
this.path = path;
|
|
50
|
+
}
|
|
51
|
+
/** The resolved on-disk path (useful for tests / diagnostics). */
|
|
52
|
+
getPath() {
|
|
53
|
+
return this.path;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Read-at-launch. An absent file yields the empty set. A malformed file
|
|
57
|
+
* throws (honest — never a silent reset that would discard operator layouts).
|
|
58
|
+
*/
|
|
59
|
+
read() {
|
|
60
|
+
if (!existsSync(this.path))
|
|
61
|
+
return { version: 1, views: [] };
|
|
62
|
+
const raw = readFileSync(this.path, "utf-8");
|
|
63
|
+
const parsed = parseYaml(raw);
|
|
64
|
+
if (parsed == null)
|
|
65
|
+
return { version: 1, views: [] };
|
|
66
|
+
if (typeof parsed !== "object") {
|
|
67
|
+
throw new Error(`terminal views file at ${this.path} must be a YAML object with a 'views' array`);
|
|
68
|
+
}
|
|
69
|
+
const obj = parsed;
|
|
70
|
+
const views = obj["views"];
|
|
71
|
+
if (!Array.isArray(views)) {
|
|
72
|
+
throw new Error(`terminal views file at ${this.path}: 'views' must be an array`);
|
|
73
|
+
}
|
|
74
|
+
return { version: 1, views: views };
|
|
75
|
+
}
|
|
76
|
+
list() {
|
|
77
|
+
return this.read().views;
|
|
78
|
+
}
|
|
79
|
+
get(id) {
|
|
80
|
+
return this.read().views.find((v) => v.id === id) ?? null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Persist a SAVED view (upsert by id). Atomic (tmp + rename) and byte-stable.
|
|
84
|
+
* Returns the resulting file. Only accepts `SavedView` — a derived view can
|
|
85
|
+
* never reach disk through this path (A3).
|
|
86
|
+
*/
|
|
87
|
+
save(view) {
|
|
88
|
+
const current = this.read();
|
|
89
|
+
const idx = current.views.findIndex((v) => v.id === view.id);
|
|
90
|
+
const next = [...current.views];
|
|
91
|
+
if (idx >= 0)
|
|
92
|
+
next[idx] = view;
|
|
93
|
+
else
|
|
94
|
+
next.push(view);
|
|
95
|
+
const file = { version: 1, views: next };
|
|
96
|
+
this.writeAtomic(file);
|
|
97
|
+
return { version: 1, views: file.views.map(normalizeView) };
|
|
98
|
+
}
|
|
99
|
+
/** Remove a saved view by id (idempotent). Atomic. */
|
|
100
|
+
remove(id) {
|
|
101
|
+
const current = this.read();
|
|
102
|
+
const file = {
|
|
103
|
+
version: 1,
|
|
104
|
+
views: current.views.filter((v) => v.id !== id),
|
|
105
|
+
};
|
|
106
|
+
this.writeAtomic(file);
|
|
107
|
+
return { version: 1, views: file.views.map(normalizeView) };
|
|
108
|
+
}
|
|
109
|
+
writeAtomic(file) {
|
|
110
|
+
const tmp = `${this.path}.tmp`;
|
|
111
|
+
writeFileSync(tmp, serialize(file), "utf-8");
|
|
112
|
+
renameSync(tmp, this.path);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Map a live seat inventory into composer-ready members. PURE and IN-MEMORY —
|
|
117
|
+
* the result is handed straight to `composeView`; it is NEVER written to the
|
|
118
|
+
* saved-views file. Non-tmux / session-less rows are dropped from the derived
|
|
119
|
+
* set (a derived view only tiles attachable seats; saved views name absents).
|
|
120
|
+
*/
|
|
121
|
+
export function deriveViewMembers(rows, opts = {}) {
|
|
122
|
+
const members = [];
|
|
123
|
+
for (const row of rows) {
|
|
124
|
+
if (row.attachmentType !== "tmux")
|
|
125
|
+
continue;
|
|
126
|
+
const seat = row.canonicalSessionName;
|
|
127
|
+
if (!seat)
|
|
128
|
+
continue;
|
|
129
|
+
const tmuxSession = row.tmuxSession ?? row.canonicalSessionName;
|
|
130
|
+
const agent = row.logicalId ?? seat;
|
|
131
|
+
const label = opts.labelSuffix ? `${agent} · ${opts.labelSuffix}` : agent;
|
|
132
|
+
members.push({
|
|
133
|
+
seat,
|
|
134
|
+
label,
|
|
135
|
+
tmuxSession,
|
|
136
|
+
host: opts.host ?? null,
|
|
137
|
+
readOnly: opts.readOnly === true,
|
|
138
|
+
// Derived views are live: presence in the inventory IS the liveness
|
|
139
|
+
// signal for the derived set; a stricter has-session probe layers on at
|
|
140
|
+
// compose time for local members if the caller supplies one.
|
|
141
|
+
alive: true,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
return members;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=terminal-views-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-views-store.js","sourceRoot":"","sources":["../../../src/domain/terminal/terminal-views-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { HostEntry } from "../hosts/hosts-registry-reader.js";
|
|
2
|
+
import type { ComposedPane, ComposedView } from "./terminal-provider.js";
|
|
3
|
+
/**
|
|
4
|
+
* Panes per grid page (3×3). Overflow spills to the next provider tab/page.
|
|
5
|
+
* A module constant in v1 — a future per-rig `terminal.tiles_per_page` config
|
|
6
|
+
* key is a natural extension, but no config key ships in this slice (the plan
|
|
7
|
+
* keeps the C1 config surface to the single `terminal.status_bar` key).
|
|
8
|
+
*/
|
|
9
|
+
export declare const PANES_PER_PAGE = 9;
|
|
10
|
+
/**
|
|
11
|
+
* One resolved member of a view, ready to compose. `alive` and `readOnly` are
|
|
12
|
+
* decided upstream (liveness probe + cross-rig/saved-read-only policy); the
|
|
13
|
+
* composer only routes on them. `host` is a structured host id or null (local).
|
|
14
|
+
*/
|
|
15
|
+
export interface ViewMemberInput {
|
|
16
|
+
/** Canonical session name of the seat. */
|
|
17
|
+
seat: string;
|
|
18
|
+
/** Pane label — `<agent> · <slice>` (AC-7). */
|
|
19
|
+
label: string;
|
|
20
|
+
/** The tmux session to attach to (may be null if the seat has no tmux binding). */
|
|
21
|
+
tmuxSession: string | null;
|
|
22
|
+
/** Structured host id when remote; null for a local seat. */
|
|
23
|
+
host: string | null;
|
|
24
|
+
/** View-only / cross-rig membership → read-only (`-r`) attach. */
|
|
25
|
+
readOnly: boolean;
|
|
26
|
+
/** Local liveness (has-session). Ignored for remote members (reachability is an ssh concern). */
|
|
27
|
+
alive: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** The composer's only side-channel: read-only host resolution from the registry. */
|
|
30
|
+
export interface ComposeContext {
|
|
31
|
+
/** Resolve a host id to its registry entry, or null if the id is unknown. */
|
|
32
|
+
resolveHost(id: string): HostEntry | null;
|
|
33
|
+
}
|
|
34
|
+
/** Chunk panes into fixed-size grid pages (one provider tab per page). */
|
|
35
|
+
export declare function chunkPanes(panes: ComposedPane[], perPage?: number): ComposedPane[][];
|
|
36
|
+
/**
|
|
37
|
+
* Compose a resolved member list into a provider-neutral view. Pure: same
|
|
38
|
+
* inputs → byte-identical output. Member order is preserved into `opened`
|
|
39
|
+
* (and therefore into page assignment), so paging is deterministic.
|
|
40
|
+
*/
|
|
41
|
+
export declare function composeView(id: string, members: ViewMemberInput[], ctx: ComposeContext): ComposedView;
|
|
42
|
+
//# sourceMappingURL=view-composer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-composer.d.ts","sourceRoot":"","sources":["../../../src/domain/terminal/view-composer.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EAEb,MAAM,wBAAwB,CAAC;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CAC3C;AAYD,0EAA0E;AAC1E,wBAAgB,UAAU,CACxB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,GAAE,MAAuB,GAC/B,YAAY,EAAE,EAAE,CAOlB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,eAAe,EAAE,EAC1B,GAAG,EAAE,cAAc,GAClB,YAAY,CA2Fd"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// OPR.0.4.6.02 C2 — the PURE view composer.
|
|
2
|
+
//
|
|
3
|
+
// Turns a resolved list of view members into a provider-neutral `ComposedView`
|
|
4
|
+
// (`{ opened, absent, degraded, pages }`, BR-6 honest-partial). All of the
|
|
5
|
+
// partition rules live here, in one testable pure function, so no provider
|
|
6
|
+
// re-implements them:
|
|
7
|
+
//
|
|
8
|
+
// local live → `tmux attach -t <session>`
|
|
9
|
+
// view-only / cross-rig (read-only)
|
|
10
|
+
// → `tmux attach -r -t <session>`
|
|
11
|
+
// ssh host → `ssh <dest> tmux attach [-r] -t <session>`
|
|
12
|
+
// http host → NO pane; honest-degrade { seat, host, reason }
|
|
13
|
+
// dead / no session → absent[] (named, never silently dropped)
|
|
14
|
+
//
|
|
15
|
+
// The composer takes members that already carry a STRUCTURED `host` field (a
|
|
16
|
+
// host id, never a `member@rig@host` string — MH BR-1). Host classification
|
|
17
|
+
// (ssh vs http vs unknown) is resolved through the operator's read-only hosts
|
|
18
|
+
// registry via the injected `resolveHost`.
|
|
19
|
+
/**
|
|
20
|
+
* Panes per grid page (3×3). Overflow spills to the next provider tab/page.
|
|
21
|
+
* A module constant in v1 — a future per-rig `terminal.tiles_per_page` config
|
|
22
|
+
* key is a natural extension, but no config key ships in this slice (the plan
|
|
23
|
+
* keeps the C1 config surface to the single `terminal.status_bar` key).
|
|
24
|
+
*/
|
|
25
|
+
export const PANES_PER_PAGE = 9;
|
|
26
|
+
/** POSIX single-quote a string so session names / targets are shell-inert in the composed command. */
|
|
27
|
+
function shellQuote(s) {
|
|
28
|
+
return "'" + s.replace(/'/g, "'\"'\"'") + "'";
|
|
29
|
+
}
|
|
30
|
+
/** The remote ssh destination — `user@target` when a user is declared, else `target`. */
|
|
31
|
+
function sshDest(host) {
|
|
32
|
+
return host.user ? `${host.user}@${host.target}` : host.target;
|
|
33
|
+
}
|
|
34
|
+
/** Chunk panes into fixed-size grid pages (one provider tab per page). */
|
|
35
|
+
export function chunkPanes(panes, perPage = PANES_PER_PAGE) {
|
|
36
|
+
if (perPage < 1)
|
|
37
|
+
throw new Error(`chunkPanes: perPage must be >= 1 (got ${perPage})`);
|
|
38
|
+
const pages = [];
|
|
39
|
+
for (let i = 0; i < panes.length; i += perPage) {
|
|
40
|
+
pages.push(panes.slice(i, i + perPage));
|
|
41
|
+
}
|
|
42
|
+
return pages;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compose a resolved member list into a provider-neutral view. Pure: same
|
|
46
|
+
* inputs → byte-identical output. Member order is preserved into `opened`
|
|
47
|
+
* (and therefore into page assignment), so paging is deterministic.
|
|
48
|
+
*/
|
|
49
|
+
export function composeView(id, members, ctx) {
|
|
50
|
+
const opened = [];
|
|
51
|
+
const absent = [];
|
|
52
|
+
const degraded = [];
|
|
53
|
+
for (const m of members) {
|
|
54
|
+
const attachFlag = m.readOnly ? "-r " : "";
|
|
55
|
+
if (m.host !== null) {
|
|
56
|
+
// Remote member: classify by the registry entry's transport.
|
|
57
|
+
const host = ctx.resolveHost(m.host);
|
|
58
|
+
if (!host) {
|
|
59
|
+
// Unknown host id is a config gap, not a live seat — degrade named,
|
|
60
|
+
// never a silent omission.
|
|
61
|
+
degraded.push({
|
|
62
|
+
seat: m.seat,
|
|
63
|
+
host: m.host,
|
|
64
|
+
reason: `host ${m.host} is not in the hosts registry`,
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (host.transport === "http") {
|
|
69
|
+
// http hosts speak daemon REST, not interactive ssh panes — the tile
|
|
70
|
+
// surface needs ssh. Honest-degrade, R1(a).
|
|
71
|
+
degraded.push({
|
|
72
|
+
seat: m.seat,
|
|
73
|
+
host: m.host,
|
|
74
|
+
reason: `host ${m.host} is http-registered; tiles need ssh`,
|
|
75
|
+
});
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// ssh host: a seat with no recorded tmux session cannot be attached.
|
|
79
|
+
if (!m.tmuxSession) {
|
|
80
|
+
absent.push({
|
|
81
|
+
seat: m.seat,
|
|
82
|
+
host: m.host,
|
|
83
|
+
reason: "no tmux session recorded for this seat",
|
|
84
|
+
});
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// Guard G1: the host registry is STRUCTURED data, but the pane command is a
|
|
88
|
+
// shell string — so the ssh destination must be shell-inert AND not
|
|
89
|
+
// option-shaped. A registry `user`/`target` with whitespace or shell
|
|
90
|
+
// metacharacters would otherwise split into extra shell words; a leading
|
|
91
|
+
// `-` would be parsed BY ssh as an option (option injection). We shell-quote
|
|
92
|
+
// the destination so it stays exactly ONE argument, and honest-degrade (named,
|
|
93
|
+
// never run) a destination that begins with `-`.
|
|
94
|
+
const dest = sshDest(host);
|
|
95
|
+
if (dest.startsWith("-")) {
|
|
96
|
+
degraded.push({
|
|
97
|
+
seat: m.seat,
|
|
98
|
+
host: m.host,
|
|
99
|
+
reason: `host ${m.host} ssh destination '${dest}' is option-shaped (leading '-'); refusing to compose an ssh tile`,
|
|
100
|
+
});
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
opened.push({
|
|
104
|
+
seat: m.seat,
|
|
105
|
+
label: m.label,
|
|
106
|
+
paneCommand: `ssh ${shellQuote(dest)} tmux attach ${attachFlag}-t ${shellQuote(m.tmuxSession)}`,
|
|
107
|
+
readOnly: m.readOnly,
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Local member.
|
|
112
|
+
if (!m.tmuxSession) {
|
|
113
|
+
absent.push({
|
|
114
|
+
seat: m.seat,
|
|
115
|
+
host: null,
|
|
116
|
+
reason: "no tmux session recorded for this seat",
|
|
117
|
+
});
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (!m.alive) {
|
|
121
|
+
absent.push({
|
|
122
|
+
seat: m.seat,
|
|
123
|
+
host: null,
|
|
124
|
+
reason: `tmux session ${m.tmuxSession} is not alive`,
|
|
125
|
+
});
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
opened.push({
|
|
129
|
+
seat: m.seat,
|
|
130
|
+
label: m.label,
|
|
131
|
+
paneCommand: `tmux attach ${attachFlag}-t ${shellQuote(m.tmuxSession)}`,
|
|
132
|
+
readOnly: m.readOnly,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return { id, opened, absent, degraded, pages: chunkPanes(opened) };
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=view-composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-composer.js","sourceRoot":"","sources":["../../../src/domain/terminal/view-composer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { TmuxAdapter } from "../adapters/tmux.js";
|
|
2
|
+
export interface TmuxOptionDefaultsDeps {
|
|
3
|
+
tmuxAdapter: TmuxAdapter;
|
|
4
|
+
/**
|
|
5
|
+
* OPR.0.4.6.02 S1 — reads the daemon's tmux option defaults at APPLY time.
|
|
6
|
+
* Resolved fresh per call (from the SettingsStore in startup) so an
|
|
7
|
+
* operator's `terminal.status_bar` flip applies to FUTURE launches only.
|
|
8
|
+
* Defaults to `statusBar: false` (bar hidden) when omitted.
|
|
9
|
+
*/
|
|
10
|
+
readTmuxOptionDefaults?: () => {
|
|
11
|
+
statusBar: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* OPR.0.4.6.02 S1 — platform selector for the server-scope `copy-command`
|
|
15
|
+
* table. Defaults to `process.platform`; injectable for the scope tests.
|
|
16
|
+
*/
|
|
17
|
+
platform?: NodeJS.Platform;
|
|
18
|
+
/**
|
|
19
|
+
* OPR.0.4.6.02 S1 — cheap `command -v <bin>` probe for the linux
|
|
20
|
+
* copy-command fallback chain. Defaults to a real shell probe; injectable
|
|
21
|
+
* for deterministic tests.
|
|
22
|
+
*/
|
|
23
|
+
hasCommand?: (bin: string) => boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* OPR.0.4.6.02 S1 — applies the daemon's tmux option defaults to a
|
|
27
|
+
* FRESHLY-CREATED session. Shared by `NodeLauncher` (the launch path) and
|
|
28
|
+
* `SuccessorSessionLauncher` (the fresh seat-handover successor path) so
|
|
29
|
+
* every fresh operator/agent seat gets consistent mouse/status/clipboard
|
|
30
|
+
* defaults (orch C1 scope ruling: fold fresh successors in via ONE helper).
|
|
31
|
+
*
|
|
32
|
+
* Scope discipline (guard b2): SESSION-scope options (`mouse`, `status`) are
|
|
33
|
+
* applied ONLY to the just-created session name passed in — never a
|
|
34
|
+
* pre-existing/discovered session — so the never-retro-flip rail (BR-1)
|
|
35
|
+
* holds and a `terminal.status_bar` flip affects future launches only.
|
|
36
|
+
* SERVER-scope options (`set-clipboard`, `copy-command`) are asserted ONCE
|
|
37
|
+
* per daemon lifetime via the shared memo on this single instance; a daemon
|
|
38
|
+
* RESTART re-asserts (a fresh applier). Callers MUST only invoke this after
|
|
39
|
+
* a successful `createSession` on a freshly-created session.
|
|
40
|
+
*/
|
|
41
|
+
export declare class TmuxOptionDefaultsApplier {
|
|
42
|
+
private tmuxAdapter;
|
|
43
|
+
private readTmuxOptionDefaults;
|
|
44
|
+
private platform;
|
|
45
|
+
private hasCommand;
|
|
46
|
+
private serverDefaultsAsserted;
|
|
47
|
+
constructor(deps: TmuxOptionDefaultsDeps);
|
|
48
|
+
/**
|
|
49
|
+
* Apply the option defaults to a JUST-CREATED session. `mouse` is always
|
|
50
|
+
* on; the inner status bar follows the `terminal.status_bar` config key
|
|
51
|
+
* (default off), read at apply time so a flip applies to FUTURE launches
|
|
52
|
+
* only (this touches only `sessionName`). Then assert the server-scope
|
|
53
|
+
* defaults once per daemon lifetime.
|
|
54
|
+
*
|
|
55
|
+
* Returns the list of non-fatal warnings (empty when all sets succeed) so
|
|
56
|
+
* the caller can fold them into its own launch-warning channel. NEVER
|
|
57
|
+
* throws for an option-set failure — a seat without mouse-scroll is
|
|
58
|
+
* degraded, not dead (and a handover successor must not be handover-fatal
|
|
59
|
+
* over a cosmetic option).
|
|
60
|
+
*/
|
|
61
|
+
applyToFreshSession(sessionName: string): Promise<string[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Assert the SERVER-scope tmux defaults (`set-clipboard on` + the
|
|
64
|
+
* per-platform `copy-command`) on the daemon's OWN tmux server, ONCE per
|
|
65
|
+
* daemon lifetime. Written only through `setServerOption` (`set-option
|
|
66
|
+
* -s`) — never a `-t` session target (guard b2 scope contract).
|
|
67
|
+
*
|
|
68
|
+
* Per-process memoization means a daemon RESTART re-asserts these (a fresh
|
|
69
|
+
* applier instance): an operator's manual `copy-command` / `set-clipboard`
|
|
70
|
+
* override does NOT survive a daemon restart — the named off-switch
|
|
71
|
+
* follow-up is the customization path. Re-running is harmless (idempotent
|
|
72
|
+
* set of the same values); the memo is an optimization, not a correctness
|
|
73
|
+
* gate.
|
|
74
|
+
*/
|
|
75
|
+
private ensureServerDefaults;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* OPR.0.4.6.02 S1 — the per-platform tmux `copy-command` table (arch rail
|
|
79
|
+
* b). Ref: the tmux "Clipboard" wiki — `copy-command` is the shell command
|
|
80
|
+
* tmux pipes a copy-mode selection into to reach the system clipboard.
|
|
81
|
+
* - darwin → `pbcopy`
|
|
82
|
+
* - linux → `wl-copy` if present, else `xclip -selection clipboard -i`,
|
|
83
|
+
* else UNSET (null) — fall back to `set-clipboard on` OSC 52.
|
|
84
|
+
* - other → UNSET (null).
|
|
85
|
+
* Pure: platform + a `command -v` probe in, the command string (or null)
|
|
86
|
+
* out. One table, no side effects — the applier decides whether to write.
|
|
87
|
+
*/
|
|
88
|
+
export declare function resolveCopyCommand(platform: NodeJS.Platform, hasCommand: (bin: string) => boolean): string | null;
|
|
89
|
+
//# sourceMappingURL=tmux-option-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-option-defaults.d.ts","sourceRoot":"","sources":["../../src/domain/tmux-option-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,sBAAsB,CAA+B;IAC7D,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,sBAAsB,CAAS;gBAE3B,IAAI,EAAE,sBAAsB;IAOxC;;;;;;;;;;;;OAYG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAuBjE;;;;;;;;;;;;OAYG;YACW,oBAAoB;CAmBnC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GACnC,MAAM,GAAG,IAAI,CAQf"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* OPR.0.4.6.02 S1 — applies the daemon's tmux option defaults to a
|
|
4
|
+
* FRESHLY-CREATED session. Shared by `NodeLauncher` (the launch path) and
|
|
5
|
+
* `SuccessorSessionLauncher` (the fresh seat-handover successor path) so
|
|
6
|
+
* every fresh operator/agent seat gets consistent mouse/status/clipboard
|
|
7
|
+
* defaults (orch C1 scope ruling: fold fresh successors in via ONE helper).
|
|
8
|
+
*
|
|
9
|
+
* Scope discipline (guard b2): SESSION-scope options (`mouse`, `status`) are
|
|
10
|
+
* applied ONLY to the just-created session name passed in — never a
|
|
11
|
+
* pre-existing/discovered session — so the never-retro-flip rail (BR-1)
|
|
12
|
+
* holds and a `terminal.status_bar` flip affects future launches only.
|
|
13
|
+
* SERVER-scope options (`set-clipboard`, `copy-command`) are asserted ONCE
|
|
14
|
+
* per daemon lifetime via the shared memo on this single instance; a daemon
|
|
15
|
+
* RESTART re-asserts (a fresh applier). Callers MUST only invoke this after
|
|
16
|
+
* a successful `createSession` on a freshly-created session.
|
|
17
|
+
*/
|
|
18
|
+
export class TmuxOptionDefaultsApplier {
|
|
19
|
+
tmuxAdapter;
|
|
20
|
+
readTmuxOptionDefaults;
|
|
21
|
+
platform;
|
|
22
|
+
hasCommand;
|
|
23
|
+
serverDefaultsAsserted = false;
|
|
24
|
+
constructor(deps) {
|
|
25
|
+
this.tmuxAdapter = deps.tmuxAdapter;
|
|
26
|
+
this.readTmuxOptionDefaults = deps.readTmuxOptionDefaults ?? (() => ({ statusBar: false }));
|
|
27
|
+
this.platform = deps.platform ?? process.platform;
|
|
28
|
+
this.hasCommand = deps.hasCommand ?? defaultHasCommand;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Apply the option defaults to a JUST-CREATED session. `mouse` is always
|
|
32
|
+
* on; the inner status bar follows the `terminal.status_bar` config key
|
|
33
|
+
* (default off), read at apply time so a flip applies to FUTURE launches
|
|
34
|
+
* only (this touches only `sessionName`). Then assert the server-scope
|
|
35
|
+
* defaults once per daemon lifetime.
|
|
36
|
+
*
|
|
37
|
+
* Returns the list of non-fatal warnings (empty when all sets succeed) so
|
|
38
|
+
* the caller can fold them into its own launch-warning channel. NEVER
|
|
39
|
+
* throws for an option-set failure — a seat without mouse-scroll is
|
|
40
|
+
* degraded, not dead (and a handover successor must not be handover-fatal
|
|
41
|
+
* over a cosmetic option).
|
|
42
|
+
*/
|
|
43
|
+
async applyToFreshSession(sessionName) {
|
|
44
|
+
const warnings = [];
|
|
45
|
+
const mouse = await this.tmuxAdapter.setSessionOption(sessionName, "mouse", "on");
|
|
46
|
+
if (!mouse.ok) {
|
|
47
|
+
warnings.push(`tmux "mouse" option not set for ${sessionName}: ${mouse.message}`);
|
|
48
|
+
}
|
|
49
|
+
let statusBar = false;
|
|
50
|
+
try {
|
|
51
|
+
statusBar = this.readTmuxOptionDefaults().statusBar === true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
statusBar = false;
|
|
55
|
+
}
|
|
56
|
+
const status = await this.tmuxAdapter.setSessionOption(sessionName, "status", statusBar ? "on" : "off");
|
|
57
|
+
if (!status.ok) {
|
|
58
|
+
warnings.push(`tmux "status" option not set for ${sessionName}: ${status.message}`);
|
|
59
|
+
}
|
|
60
|
+
await this.ensureServerDefaults(warnings);
|
|
61
|
+
return warnings;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Assert the SERVER-scope tmux defaults (`set-clipboard on` + the
|
|
65
|
+
* per-platform `copy-command`) on the daemon's OWN tmux server, ONCE per
|
|
66
|
+
* daemon lifetime. Written only through `setServerOption` (`set-option
|
|
67
|
+
* -s`) — never a `-t` session target (guard b2 scope contract).
|
|
68
|
+
*
|
|
69
|
+
* Per-process memoization means a daemon RESTART re-asserts these (a fresh
|
|
70
|
+
* applier instance): an operator's manual `copy-command` / `set-clipboard`
|
|
71
|
+
* override does NOT survive a daemon restart — the named off-switch
|
|
72
|
+
* follow-up is the customization path. Re-running is harmless (idempotent
|
|
73
|
+
* set of the same values); the memo is an optimization, not a correctness
|
|
74
|
+
* gate.
|
|
75
|
+
*/
|
|
76
|
+
async ensureServerDefaults(warnings) {
|
|
77
|
+
if (this.serverDefaultsAsserted)
|
|
78
|
+
return;
|
|
79
|
+
// Set first so concurrent applies don't double-assert; either way the
|
|
80
|
+
// sets are idempotent.
|
|
81
|
+
this.serverDefaultsAsserted = true;
|
|
82
|
+
const clip = await this.tmuxAdapter.setServerOption("set-clipboard", "on");
|
|
83
|
+
if (!clip.ok) {
|
|
84
|
+
warnings.push(`tmux "set-clipboard" server option not set: ${clip.message}`);
|
|
85
|
+
}
|
|
86
|
+
const copyCommand = resolveCopyCommand(this.platform, this.hasCommand);
|
|
87
|
+
if (copyCommand !== null) {
|
|
88
|
+
const cc = await this.tmuxAdapter.setServerOption("copy-command", copyCommand);
|
|
89
|
+
if (!cc.ok) {
|
|
90
|
+
warnings.push(`tmux "copy-command" server option not set: ${cc.message}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* OPR.0.4.6.02 S1 — the per-platform tmux `copy-command` table (arch rail
|
|
97
|
+
* b). Ref: the tmux "Clipboard" wiki — `copy-command` is the shell command
|
|
98
|
+
* tmux pipes a copy-mode selection into to reach the system clipboard.
|
|
99
|
+
* - darwin → `pbcopy`
|
|
100
|
+
* - linux → `wl-copy` if present, else `xclip -selection clipboard -i`,
|
|
101
|
+
* else UNSET (null) — fall back to `set-clipboard on` OSC 52.
|
|
102
|
+
* - other → UNSET (null).
|
|
103
|
+
* Pure: platform + a `command -v` probe in, the command string (or null)
|
|
104
|
+
* out. One table, no side effects — the applier decides whether to write.
|
|
105
|
+
*/
|
|
106
|
+
export function resolveCopyCommand(platform, hasCommand) {
|
|
107
|
+
if (platform === "darwin")
|
|
108
|
+
return "pbcopy";
|
|
109
|
+
if (platform === "linux") {
|
|
110
|
+
if (hasCommand("wl-copy"))
|
|
111
|
+
return "wl-copy";
|
|
112
|
+
if (hasCommand("xclip"))
|
|
113
|
+
return "xclip -selection clipboard -i";
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* OPR.0.4.6.02 S1 — default `command -v <bin>` probe (POSIX shell builtin).
|
|
120
|
+
* Returns true when the binary resolves on PATH. Cheap + best-effort; any
|
|
121
|
+
* failure (spawn error, non-shell env) reads as absent.
|
|
122
|
+
*/
|
|
123
|
+
function defaultHasCommand(bin) {
|
|
124
|
+
try {
|
|
125
|
+
const r = spawnSync(`command -v ${bin}`, { shell: true, stdio: "ignore" });
|
|
126
|
+
return r.status === 0;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=tmux-option-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-option-defaults.js","sourceRoot":"","sources":["../../src/domain/tmux-option-defaults.ts"],"names":[],"mappings":"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"}
|
|
@@ -188,7 +188,7 @@ export type RigEvent = {
|
|
|
188
188
|
sessionName: string;
|
|
189
189
|
runtime: string;
|
|
190
190
|
sessionId: string;
|
|
191
|
-
provenance: "hook" | "scrape";
|
|
191
|
+
provenance: "hook" | "scrape" | "rpc";
|
|
192
192
|
} | {
|
|
193
193
|
type: "session.resume_token_set";
|
|
194
194
|
rigId: string;
|
|
@@ -571,10 +571,22 @@ export type RigEvent = {
|
|
|
571
571
|
instanceId: string;
|
|
572
572
|
workflowName: string;
|
|
573
573
|
reason: string;
|
|
574
|
+
} | {
|
|
575
|
+
type: "workflow.resumed";
|
|
576
|
+
instanceId: string;
|
|
577
|
+
workflowName: string;
|
|
578
|
+
stepId: string;
|
|
579
|
+
resumedBy: string;
|
|
580
|
+
decision: string | null;
|
|
581
|
+
resumeCount: number;
|
|
574
582
|
} | {
|
|
575
583
|
type: "workflow.routing_table_changed";
|
|
576
584
|
rigName: string;
|
|
577
585
|
cause: string;
|
|
586
|
+
instanceId?: string;
|
|
587
|
+
stepId?: string | null;
|
|
588
|
+
from?: string;
|
|
589
|
+
to?: string;
|
|
578
590
|
} | {
|
|
579
591
|
type: "workflow_spec.removed";
|
|
580
592
|
sourcePath: string;
|
|
@@ -801,6 +813,12 @@ export interface NodeInventoryEntry {
|
|
|
801
813
|
logicalId: string;
|
|
802
814
|
podId: string | null;
|
|
803
815
|
podNamespace?: string | null;
|
|
816
|
+
/**
|
|
817
|
+
* OPR.0.4.6.FAC1: the seat's declared role (`nodes.role`, written by
|
|
818
|
+
* the pod-member path). The workflow binding layer's role→seat
|
|
819
|
+
* candidate filter reads exactly this. null = role-less.
|
|
820
|
+
*/
|
|
821
|
+
role: string | null;
|
|
804
822
|
canonicalSessionName: string | null;
|
|
805
823
|
attachmentType?: "tmux" | "external_cli" | null;
|
|
806
824
|
nodeKind: "agent" | "infrastructure";
|
|
@@ -1191,6 +1209,14 @@ export interface RigSpecPodMember {
|
|
|
1191
1209
|
runtime: string;
|
|
1192
1210
|
codexConfigProfile?: string;
|
|
1193
1211
|
model?: string;
|
|
1212
|
+
/**
|
|
1213
|
+
* OPR.0.4.6.FAC1: optional seat-side role declaration (writes the
|
|
1214
|
+
* existing `nodes.role` column via createMemberNode → addNode). The
|
|
1215
|
+
* workflow binding layer resolves workflow roles to seats by this
|
|
1216
|
+
* dimension. Opt-in: a role-less member is never role-resolved and
|
|
1217
|
+
* stays reachable only via explicit preferred_targets.
|
|
1218
|
+
*/
|
|
1219
|
+
role?: string;
|
|
1194
1220
|
cwd: string;
|
|
1195
1221
|
restorePolicy?: string;
|
|
1196
1222
|
startup?: StartupBlock;
|
|
@@ -1417,6 +1443,13 @@ export interface ExpansionPodFragment {
|
|
|
1417
1443
|
codexConfigProfile?: string;
|
|
1418
1444
|
restorePolicy?: string;
|
|
1419
1445
|
label?: string;
|
|
1446
|
+
/**
|
|
1447
|
+
* OPR.0.4.6.FAC1: optional seat-side role; threaded through
|
|
1448
|
+
* buildExpansionSpecObject → the pod-member schema → nodes.role
|
|
1449
|
+
* (a provided role is never silently dropped — the sibling-layer
|
|
1450
|
+
* rule).
|
|
1451
|
+
*/
|
|
1452
|
+
role?: string;
|
|
1420
1453
|
/** Optional session source declaration; threaded through to launch. */
|
|
1421
1454
|
sessionSource?: SessionSourceSpec;
|
|
1422
1455
|
/**
|