@jstn-sdk/rcs 0.1.0 → 0.1.1
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 +142 -102
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +0 -101
- package/dist/agents/definitions.js.map +1 -1
- package/dist/blueprint/runtime.d.ts +52 -0
- package/dist/blueprint/runtime.d.ts.map +1 -0
- package/dist/{ralplan → blueprint}/runtime.js +19 -19
- package/dist/blueprint/runtime.js.map +1 -0
- package/dist/catalog/reader.d.ts.map +1 -1
- package/dist/catalog/reader.js +8 -2
- package/dist/catalog/reader.js.map +1 -1
- package/dist/catalog/schema.js +1 -1
- package/dist/catalog/schema.js.map +1 -1
- package/dist/cli/forge.d.ts +17 -0
- package/dist/cli/{ralph.d.ts.map → forge.d.ts.map} +1 -1
- package/dist/cli/{ralph.js → forge.js} +82 -82
- package/dist/cli/{ralph.js.map → forge.js.map} +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +15 -15
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +2 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/star-prompt.js +2 -2
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/state.js +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +3 -2
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/tmux-hook.d.ts.map +1 -1
- package/dist/cli/tmux-hook.js +9 -1
- package/dist/cli/tmux-hook.js.map +1 -1
- package/dist/config/generator.d.ts +1 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +1 -1
- package/dist/config/generator.js.map +1 -1
- package/dist/forge/contract.d.ts +17 -0
- package/dist/{ralph → forge}/contract.d.ts.map +1 -1
- package/dist/{ralph → forge}/contract.js +16 -16
- package/dist/{ralph → forge}/contract.js.map +1 -1
- package/dist/{ralph → forge}/persistence.d.ts +5 -5
- package/dist/{ralph → forge}/persistence.d.ts.map +1 -1
- package/dist/{ralph → forge}/persistence.js +7 -6
- package/dist/forge/persistence.js.map +1 -0
- package/dist/hooks/agents-overlay.d.ts +1 -1
- package/dist/hooks/agents-overlay.d.ts.map +1 -1
- package/dist/hooks/agents-overlay.js +37 -31
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +82 -14
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +8 -8
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +94 -64
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +9 -11
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +10 -21
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/task-size-detector.js +2 -2
- package/dist/hooks/task-size-detector.js.map +1 -1
- package/dist/hooks/triage-state.d.ts +1 -1
- package/dist/hooks/triage-state.js +1 -1
- package/dist/hud/colors.d.ts +2 -2
- package/dist/hud/colors.js +2 -2
- package/dist/hud/render.js +21 -21
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts +3 -3
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +18 -15
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/types.d.ts +6 -6
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +36 -2
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +1 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +4 -1
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +4 -4
- package/dist/mcp/state-server.js +2 -2
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/base.d.ts +2 -2
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +29 -26
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +7 -1
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +39 -6
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/pipeline/index.d.ts +7 -6
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +5 -4
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts +5 -5
- package/dist/pipeline/orchestrator.js +25 -25
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/stages/blueprint.d.ts +25 -0
- package/dist/pipeline/stages/blueprint.d.ts.map +1 -0
- package/dist/pipeline/stages/{ralplan.js → blueprint.js} +16 -16
- package/dist/pipeline/stages/blueprint.js.map +1 -0
- package/dist/pipeline/stages/code-review.d.ts +2 -2
- package/dist/pipeline/stages/code-review.js +6 -6
- package/dist/pipeline/stages/code-review.js.map +1 -1
- package/dist/pipeline/stages/forge-verify.d.ts +50 -0
- package/dist/pipeline/stages/forge-verify.d.ts.map +1 -0
- package/dist/pipeline/stages/{ralph-verify.js → forge-verify.js} +21 -24
- package/dist/pipeline/stages/forge-verify.js.map +1 -0
- package/dist/pipeline/stages/team-exec.d.ts +1 -1
- package/dist/pipeline/stages/team-exec.js +19 -19
- package/dist/pipeline/stages/team-exec.js.map +1 -1
- package/dist/pipeline/types.d.ts +12 -12
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/pipeline/types.js +1 -1
- package/dist/planning/artifacts.d.ts +3 -4
- package/dist/planning/artifacts.d.ts.map +1 -1
- package/dist/planning/artifacts.js +2 -3
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/question/policy.js +1 -1
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +70 -13
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/scripts/codex-native-hook.js +30 -30
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/eval/eval-cross-server-party-flow.d.ts +3 -0
- package/dist/scripts/eval/eval-cross-server-party-flow.d.ts.map +1 -0
- package/dist/scripts/eval/eval-cross-server-party-flow.js +12 -0
- package/dist/scripts/eval/eval-cross-server-party-flow.js.map +1 -0
- package/dist/scripts/eval/eval-gui-onboarding-clarity.d.ts +3 -0
- package/dist/scripts/eval/eval-gui-onboarding-clarity.d.ts.map +1 -0
- package/dist/scripts/eval/eval-gui-onboarding-clarity.js +17 -0
- package/dist/scripts/eval/eval-gui-onboarding-clarity.js.map +1 -0
- package/dist/scripts/eval/eval-liveops-reward-loop-balance.d.ts +3 -0
- package/dist/scripts/eval/eval-liveops-reward-loop-balance.d.ts.map +1 -0
- package/dist/scripts/eval/eval-liveops-reward-loop-balance.js +12 -0
- package/dist/scripts/eval/eval-liveops-reward-loop-balance.js.map +1 -0
- package/dist/scripts/eval/eval-profile-datastore-recovery.d.ts +3 -0
- package/dist/scripts/eval/eval-profile-datastore-recovery.d.ts.map +1 -0
- package/dist/scripts/eval/eval-profile-datastore-recovery.js +17 -0
- package/dist/scripts/eval/eval-profile-datastore-recovery.js.map +1 -0
- package/dist/scripts/eval/eval-remote-contract-hardening.d.ts +3 -0
- package/dist/scripts/eval/eval-remote-contract-hardening.d.ts.map +1 -0
- package/dist/scripts/eval/eval-remote-contract-hardening.js +17 -0
- package/dist/scripts/eval/eval-remote-contract-hardening.js.map +1 -0
- package/dist/scripts/notify-fallback-watcher.js +140 -139
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/forge-session-resume.d.ts +23 -0
- package/dist/scripts/notify-hook/{ralph-session-resume.d.ts.map → forge-session-resume.d.ts.map} +1 -1
- package/dist/scripts/notify-hook/{ralph-session-resume.js → forge-session-resume.js} +37 -36
- package/dist/scripts/notify-hook/{ralph-session-resume.js.map → forge-session-resume.js.map} +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +34 -4
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/visual-verdict.js +3 -3
- package/dist/scripts/notify-hook.js +9 -9
- package/dist/scripts/run-test-files.js +1 -1
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/scripts/surface-taxonomy.d.ts +23 -0
- package/dist/scripts/surface-taxonomy.d.ts.map +1 -0
- package/dist/scripts/surface-taxonomy.js +271 -0
- package/dist/scripts/surface-taxonomy.js.map +1 -0
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js +5 -4
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +29 -20
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/state/operations.d.ts +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +18 -18
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +13 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +38 -17
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +6 -5
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +27 -15
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/team/contracts.d.ts +1 -1
- package/dist/team/contracts.js +2 -2
- package/dist/team/followup-planner.d.ts +2 -2
- package/dist/team/followup-planner.d.ts.map +1 -1
- package/dist/team/followup-planner.js +16 -14
- package/dist/team/followup-planner.js.map +1 -1
- package/dist/team/idle-nudge.d.ts.map +1 -1
- package/dist/team/idle-nudge.js +3 -2
- package/dist/team/idle-nudge.js.map +1 -1
- package/dist/team/leader-activity.js +1 -1
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +4 -1
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/orchestrator.js +4 -4
- package/dist/team/orchestrator.js.map +1 -1
- package/dist/team/role-router.js +3 -3
- package/dist/team/role-router.js.map +1 -1
- package/dist/team/state/dispatch.d.ts.map +1 -1
- package/dist/team/state/dispatch.js +4 -1
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/tmux-session.d.ts +4 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +42 -9
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worktree.d.ts +1 -1
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +9 -0
- package/dist/utils/platform-command.js.map +1 -1
- package/dist/verification/verifier.d.ts +1 -1
- package/dist/verification/verifier.js +2 -2
- package/docs/STATE_MODEL.md +24 -24
- package/docs/agents.html +8 -16
- package/docs/archive/README.md +15 -0
- package/docs/{prompt-migration-changelog.md → archive/prompt-migration-changelog.md} +0 -11
- package/docs/{release-body-0.9.0.md → archive/release-body-0.9.0.md} +6 -24
- package/docs/{release-body-0.9.1.md → archive/release-body-0.9.1.md} +3 -3
- package/docs/codex-native-hooks.md +4 -4
- package/docs/contracts/forge-cancel-contract.md +20 -0
- package/docs/contracts/forge-state-contract.md +52 -0
- package/docs/contracts/multi-state-transition-contract.md +5 -5
- package/docs/contracts/multi-state-transition-review.md +3 -3
- package/docs/contracts/repo-aware-team-dag-decomposition.md +1 -1
- package/docs/contracts/rust-runtime-thin-adapter-contract.md +1 -1
- package/docs/contracts/team-startup-dispatch-latency.md +1 -1
- package/docs/getting-started.html +6 -1
- package/docs/guidance-schema.md +6 -3
- package/docs/index.html +55 -4
- package/docs/integrations.html +4 -3
- package/docs/issues/team-forge-followup-team.md +38 -0
- package/docs/openclaw-integration.md +2 -2
- package/docs/prompt-guidance-contract.md +11 -11
- package/docs/prs/{dev-deprecate-team-ralph.md → dev-deprecate-team-forge.md} +27 -27
- package/docs/prs/{dev-fix-ralph-live-pane-invariant.md → dev-fix-forge-live-pane-invariant.md} +7 -7
- package/docs/prs/{dev-team-ralph-workflow-positioning.md → dev-team-forge-workflow-positioning.md} +7 -7
- package/docs/qa/forge-persistence-gate.md +20 -0
- package/docs/qa/rust-runtime-thin-adapter-gate.md +31 -40
- package/docs/readme/README.de.md +13 -0
- package/docs/readme/README.el.md +13 -0
- package/docs/readme/README.es.md +13 -0
- package/docs/readme/README.fr.md +13 -0
- package/docs/readme/README.it.md +13 -0
- package/docs/readme/README.ja.md +13 -0
- package/docs/readme/README.ko.md +13 -0
- package/docs/readme/README.pl.md +13 -0
- package/docs/readme/README.pt.md +13 -0
- package/docs/readme/README.ru.md +13 -0
- package/docs/readme/README.tr.md +13 -0
- package/docs/readme/README.uk.md +13 -0
- package/docs/readme/README.vi.md +13 -0
- package/docs/readme/README.zh-TW.md +13 -0
- package/docs/readme/README.zh.md +13 -0
- package/docs/readme/rcs-cover.svg +75 -0
- package/docs/reference/canonical-vocabulary.md +106 -0
- package/docs/reference/forge-parity-matrix.md +26 -0
- package/docs/reference/forge-upstream-baseline.md +32 -0
- package/docs/reference/rcs-config-schema-routing.md +5 -5
- package/docs/reference/roblox-pre-action-protocol.md +4 -0
- package/docs/reference/roblox-taxonomy-migration-plan.md +46 -0
- package/docs/reference/roblox-workspace-standard.md +83 -0
- package/docs/reference/robloxstudio-mcp-compatibility.md +117 -0
- package/docs/reference/semantic-design-system.md +110 -0
- package/docs/reference/surface-map.md +131 -0
- package/docs/reference/team-allocation-rebalance-policy.md +1 -1
- package/docs/release-notes-v0.1.0.md +1 -1
- package/docs/release-notes-v0.1.1.md +49 -0
- package/docs/reports/open-prs-dev-readiness-2026-04-09.md +2 -2
- package/docs/shared/agent-tiers.md +3 -3
- package/docs/skills.html +10 -12
- package/docs/troubleshooting.md +1 -1
- package/package.json +20 -13
- package/plugins/roblox-ai-os-creator-skills/.codex-plugin/plugin.json +1 -1
- package/plugins/roblox-ai-os-creator-skills/docs/reference/roblox-pre-action-protocol.md +4 -0
- package/plugins/roblox-ai-os-creator-skills/skills/ai-slop-cleaner/SKILL.md +14 -7
- package/plugins/roblox-ai-os-creator-skills/skills/analyze/SKILL.md +9 -2
- package/plugins/roblox-ai-os-creator-skills/skills/ask-claude/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/ask-gemini/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/autoforge/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/autopilot/SKILL.md +48 -41
- package/plugins/roblox-ai-os-creator-skills/skills/autoresearch/SKILL.md +8 -1
- package/plugins/roblox-ai-os-creator-skills/skills/blueprint/SKILL.md +227 -9
- package/plugins/roblox-ai-os-creator-skills/skills/blueprint-loop/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/blueprint-psych/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/blueprint-retention/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/blueprint-social/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/brief/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/brief-audience/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/brief-motivation/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/cancel/SKILL.md +59 -52
- package/plugins/roblox-ai-os-creator-skills/skills/code-review/SKILL.md +30 -24
- package/plugins/roblox-ai-os-creator-skills/skills/configure-notifications/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/crew/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/deep-interview/SKILL.md +25 -18
- package/plugins/roblox-ai-os-creator-skills/skills/doctor/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge/SKILL.md +174 -11
- package/plugins/roblox-ai-os-creator-skills/skills/forge-community/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-daily-loop/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-event-loop/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-fomo/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-mastery/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-progression/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-reward-loop/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/forge-status/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/help/SKILL.md +8 -1
- package/plugins/roblox-ai-os-creator-skills/skills/hud/SKILL.md +16 -9
- package/plugins/roblox-ai-os-creator-skills/skills/note/SKILL.md +8 -1
- package/plugins/roblox-ai-os-creator-skills/skills/pipeline/SKILL.md +18 -11
- package/plugins/roblox-ai-os-creator-skills/skills/plan/SKILL.md +36 -29
- package/plugins/roblox-ai-os-creator-skills/skills/rcs-setup/SKILL.md +8 -1
- package/plugins/roblox-ai-os-creator-skills/skills/security-review/SKILL.md +120 -236
- package/plugins/roblox-ai-os-creator-skills/skills/skill/SKILL.md +20 -13
- package/plugins/roblox-ai-os-creator-skills/skills/team/SKILL.md +17 -11
- package/plugins/roblox-ai-os-creator-skills/skills/trace/SKILL.md +7 -0
- package/plugins/roblox-ai-os-creator-skills/skills/ultraqa/SKILL.md +10 -3
- package/plugins/roblox-ai-os-creator-skills/skills/ultrawork/SKILL.md +19 -12
- package/plugins/roblox-ai-os-creator-skills/skills/{visual-ralph → visual-forge}/SKILL.md +36 -27
- package/plugins/roblox-ai-os-creator-skills/skills/visual-verdict/SKILL.md +9 -2
- package/plugins/roblox-ai-os-creator-skills/skills/wiki/SKILL.md +10 -3
- package/plugins/roblox-ai-os-creator-skills/skills/worker/SKILL.md +16 -7
- package/plugins/roblox-ai-os-creator-skills/templates/roblox/pre-action-plan.md +1 -0
- package/prompts/analyst.md +7 -0
- package/prompts/architect.md +11 -4
- package/prompts/build-fixer.md +7 -0
- package/prompts/code-reviewer.md +9 -2
- package/prompts/code-simplifier.md +4 -0
- package/prompts/critic.md +13 -6
- package/prompts/debugger.md +8 -1
- package/prompts/dependency-expert.md +8 -1
- package/prompts/designer.md +20 -10
- package/prompts/executor.md +7 -0
- package/prompts/explore-harness.md +7 -0
- package/prompts/explore.md +7 -0
- package/prompts/git-master.md +8 -1
- package/prompts/planner.md +10 -3
- package/prompts/researcher.md +7 -0
- package/prompts/security-reviewer.md +76 -92
- package/prompts/sisyphus-lite.md +7 -0
- package/prompts/team-executor.md +7 -0
- package/prompts/team-orchestrator.md +9 -2
- package/prompts/test-engineer.md +11 -3
- package/prompts/verifier.md +7 -0
- package/prompts/vision.md +9 -2
- package/prompts/writer.md +11 -4
- package/skills/.agents/skills/roblox-animations/SKILL.md +220 -0
- package/skills/.agents/skills/roblox-datastores/SKILL.md +219 -0
- package/skills/.agents/skills/roblox-gui/SKILL.md +192 -0
- package/skills/.agents/skills/roblox-monetization/SKILL.md +208 -0
- package/skills/.agents/skills/roblox-performance/SKILL.md +230 -0
- package/skills/.agents/skills/roblox-remote-events/SKILL.md +199 -0
- package/skills/.agents/skills/roblox-security/SKILL.md +236 -0
- package/skills/ai-slop-cleaner/SKILL.md +14 -7
- package/skills/analyze/SKILL.md +9 -2
- package/skills/ask-claude/SKILL.md +7 -0
- package/skills/ask-gemini/SKILL.md +7 -0
- package/skills/autoforge/SKILL.md +7 -0
- package/skills/autopilot/SKILL.md +48 -41
- package/skills/autoresearch/SKILL.md +8 -1
- package/skills/blueprint/SKILL.md +227 -9
- package/skills/blueprint-loop/SKILL.md +7 -0
- package/skills/blueprint-psych/SKILL.md +7 -0
- package/skills/blueprint-retention/SKILL.md +7 -0
- package/skills/blueprint-social/SKILL.md +7 -0
- package/skills/brief/SKILL.md +7 -0
- package/skills/brief-audience/SKILL.md +7 -0
- package/skills/brief-motivation/SKILL.md +7 -0
- package/skills/build-fix/SKILL.md +9 -2
- package/skills/cancel/SKILL.md +59 -52
- package/skills/code-review/SKILL.md +30 -24
- package/skills/configure-notifications/SKILL.md +7 -0
- package/skills/crew/SKILL.md +7 -0
- package/skills/deep-interview/SKILL.md +25 -18
- package/skills/deepsearch/SKILL.md +7 -0
- package/skills/doctor/SKILL.md +7 -0
- package/skills/ecomode/SKILL.md +9 -2
- package/skills/forge/SKILL.md +174 -11
- package/skills/forge-community/SKILL.md +7 -0
- package/skills/forge-daily-loop/SKILL.md +7 -0
- package/skills/forge-event-loop/SKILL.md +7 -0
- package/skills/forge-fomo/SKILL.md +7 -0
- package/skills/{ralph-init → forge-init}/SKILL.md +20 -13
- package/skills/forge-mastery/SKILL.md +7 -0
- package/skills/forge-progression/SKILL.md +7 -0
- package/skills/forge-reward-loop/SKILL.md +7 -0
- package/skills/forge-status/SKILL.md +7 -0
- package/skills/git-master/SKILL.md +7 -0
- package/skills/help/SKILL.md +8 -1
- package/skills/hud/SKILL.md +16 -9
- package/skills/note/SKILL.md +8 -1
- package/skills/pipeline/SKILL.md +18 -11
- package/skills/plan/SKILL.md +36 -29
- package/skills/rcs-setup/SKILL.md +8 -1
- package/skills/review/SKILL.md +7 -0
- package/skills/security-review/SKILL.md +120 -236
- package/skills/skill/SKILL.md +20 -13
- package/skills/skills-lock.json +47 -0
- package/skills/swarm/SKILL.md +8 -1
- package/skills/tdd/SKILL.md +7 -0
- package/skills/team/SKILL.md +17 -11
- package/skills/trace/SKILL.md +7 -0
- package/skills/ultraqa/SKILL.md +10 -3
- package/skills/ultrawork/SKILL.md +19 -12
- package/skills/{visual-ralph → visual-forge}/SKILL.md +36 -27
- package/skills/visual-verdict/SKILL.md +9 -2
- package/skills/web-clone/SKILL.md +14 -7
- package/skills/wiki/SKILL.md +10 -3
- package/skills/worker/SKILL.md +16 -7
- package/src/scripts/__tests__/codex-native-hook.test.ts +386 -319
- package/src/scripts/__tests__/run-test-files.test.ts +6 -4
- package/src/scripts/__tests__/verify-native-agents.test.ts +16 -16
- package/src/scripts/codex-native-hook.ts +34 -34
- package/src/scripts/eval/eval-cross-server-party-flow.ts +14 -0
- package/src/scripts/eval/eval-gui-onboarding-clarity.ts +20 -0
- package/src/scripts/eval/eval-liveops-reward-loop-balance.ts +14 -0
- package/src/scripts/eval/eval-profile-datastore-recovery.ts +20 -0
- package/src/scripts/eval/eval-remote-contract-hardening.ts +20 -0
- package/src/scripts/notify-fallback-watcher.ts +147 -146
- package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +24 -10
- package/src/scripts/notify-hook/{ralph-session-resume.ts → forge-session-resume.ts} +45 -43
- package/src/scripts/notify-hook/team-dispatch.ts +31 -4
- package/src/scripts/notify-hook/visual-verdict.ts +3 -3
- package/src/scripts/notify-hook.ts +10 -10
- package/src/scripts/run-test-files.ts +1 -1
- package/src/scripts/surface-taxonomy.ts +316 -0
- package/src/scripts/sync-plugin-mirror.ts +5 -4
- package/src/scripts/tmux-hook-engine.ts +31 -19
- package/templates/AGENTS.md +24 -15
- package/templates/catalog-manifest.json +5 -88
- package/templates/roblox/pre-action-plan.md +1 -0
- package/templates/roblox/robloxstudio-mcp.codex.json +18 -0
- package/templates/roblox/robloxstudio-mcp.windows.json +22 -0
- package/dist/adapt/__tests__/foundation.test.d.ts +0 -2
- package/dist/adapt/__tests__/foundation.test.d.ts.map +0 -1
- package/dist/adapt/__tests__/foundation.test.js +0 -171
- package/dist/adapt/__tests__/foundation.test.js.map +0 -1
- package/dist/adapt/__tests__/hermes.test.d.ts +0 -2
- package/dist/adapt/__tests__/hermes.test.d.ts.map +0 -1
- package/dist/adapt/__tests__/hermes.test.js +0 -137
- package/dist/adapt/__tests__/hermes.test.js.map +0 -1
- package/dist/agents/__tests__/definitions.test.d.ts +0 -2
- package/dist/agents/__tests__/definitions.test.d.ts.map +0 -1
- package/dist/agents/__tests__/definitions.test.js +0 -62
- package/dist/agents/__tests__/definitions.test.js.map +0 -1
- package/dist/agents/__tests__/native-config.test.d.ts +0 -2
- package/dist/agents/__tests__/native-config.test.d.ts.map +0 -1
- package/dist/agents/__tests__/native-config.test.js +0 -278
- package/dist/agents/__tests__/native-config.test.js.map +0 -1
- package/dist/autoresearch/__tests__/contracts.test.d.ts +0 -2
- package/dist/autoresearch/__tests__/contracts.test.d.ts.map +0 -1
- package/dist/autoresearch/__tests__/contracts.test.js +0 -127
- package/dist/autoresearch/__tests__/contracts.test.js.map +0 -1
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts +0 -2
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts.map +0 -1
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.js +0 -356
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.js.map +0 -1
- package/dist/autoresearch/__tests__/runtime.test.d.ts +0 -2
- package/dist/autoresearch/__tests__/runtime.test.d.ts.map +0 -1
- package/dist/autoresearch/__tests__/runtime.test.js +0 -218
- package/dist/autoresearch/__tests__/runtime.test.js.map +0 -1
- package/dist/autoresearch/__tests__/skill-validation.test.d.ts +0 -2
- package/dist/autoresearch/__tests__/skill-validation.test.d.ts.map +0 -1
- package/dist/autoresearch/__tests__/skill-validation.test.js +0 -91
- package/dist/autoresearch/__tests__/skill-validation.test.js.map +0 -1
- package/dist/catalog/__tests__/generator.test.d.ts +0 -2
- package/dist/catalog/__tests__/generator.test.d.ts.map +0 -1
- package/dist/catalog/__tests__/generator.test.js +0 -49
- package/dist/catalog/__tests__/generator.test.js.map +0 -1
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts +0 -2
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts.map +0 -1
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +0 -83
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +0 -1
- package/dist/catalog/__tests__/schema.test.d.ts +0 -2
- package/dist/catalog/__tests__/schema.test.d.ts.map +0 -1
- package/dist/catalog/__tests__/schema.test.js +0 -91
- package/dist/catalog/__tests__/schema.test.js.map +0 -1
- package/dist/cli/__tests__/adapt-help.test.d.ts +0 -2
- package/dist/cli/__tests__/adapt-help.test.d.ts.map +0 -1
- package/dist/cli/__tests__/adapt-help.test.js +0 -37
- package/dist/cli/__tests__/adapt-help.test.js.map +0 -1
- package/dist/cli/__tests__/adapt.test.d.ts +0 -2
- package/dist/cli/__tests__/adapt.test.d.ts.map +0 -1
- package/dist/cli/__tests__/adapt.test.js +0 -62
- package/dist/cli/__tests__/adapt.test.js.map +0 -1
- package/dist/cli/__tests__/agents-init.test.d.ts +0 -2
- package/dist/cli/__tests__/agents-init.test.d.ts.map +0 -1
- package/dist/cli/__tests__/agents-init.test.js +0 -184
- package/dist/cli/__tests__/agents-init.test.js.map +0 -1
- package/dist/cli/__tests__/agents.test.d.ts +0 -2
- package/dist/cli/__tests__/agents.test.d.ts.map +0 -1
- package/dist/cli/__tests__/agents.test.js +0 -137
- package/dist/cli/__tests__/agents.test.js.map +0 -1
- package/dist/cli/__tests__/ask.test.d.ts +0 -2
- package/dist/cli/__tests__/ask.test.d.ts.map +0 -1
- package/dist/cli/__tests__/ask.test.js +0 -265
- package/dist/cli/__tests__/ask.test.js.map +0 -1
- package/dist/cli/__tests__/autoresearch-guided.test.d.ts +0 -2
- package/dist/cli/__tests__/autoresearch-guided.test.d.ts.map +0 -1
- package/dist/cli/__tests__/autoresearch-guided.test.js +0 -365
- package/dist/cli/__tests__/autoresearch-guided.test.js.map +0 -1
- package/dist/cli/__tests__/autoresearch.test.d.ts +0 -2
- package/dist/cli/__tests__/autoresearch.test.d.ts.map +0 -1
- package/dist/cli/__tests__/autoresearch.test.js +0 -203
- package/dist/cli/__tests__/autoresearch.test.js.map +0 -1
- package/dist/cli/__tests__/catalog-contract.test.d.ts +0 -2
- package/dist/cli/__tests__/catalog-contract.test.d.ts.map +0 -1
- package/dist/cli/__tests__/catalog-contract.test.js +0 -18
- package/dist/cli/__tests__/catalog-contract.test.js.map +0 -1
- package/dist/cli/__tests__/cleanup.test.d.ts +0 -2
- package/dist/cli/__tests__/cleanup.test.d.ts.map +0 -1
- package/dist/cli/__tests__/cleanup.test.js +0 -419
- package/dist/cli/__tests__/cleanup.test.js.map +0 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.d.ts +0 -2
- package/dist/cli/__tests__/codex-plugin-layout.test.d.ts.map +0 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +0 -210
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +0 -1
- package/dist/cli/__tests__/doctor-context-window-warning.test.d.ts +0 -2
- package/dist/cli/__tests__/doctor-context-window-warning.test.d.ts.map +0 -1
- package/dist/cli/__tests__/doctor-context-window-warning.test.js +0 -122
- package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +0 -1
- package/dist/cli/__tests__/doctor-invalid-config.test.d.ts +0 -2
- package/dist/cli/__tests__/doctor-invalid-config.test.d.ts.map +0 -1
- package/dist/cli/__tests__/doctor-invalid-config.test.js +0 -52
- package/dist/cli/__tests__/doctor-invalid-config.test.js.map +0 -1
- package/dist/cli/__tests__/doctor-team.test.d.ts +0 -2
- package/dist/cli/__tests__/doctor-team.test.d.ts.map +0 -1
- package/dist/cli/__tests__/doctor-team.test.js +0 -299
- package/dist/cli/__tests__/doctor-team.test.js.map +0 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.d.ts +0 -2
- package/dist/cli/__tests__/doctor-warning-copy.test.d.ts.map +0 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +0 -438
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +0 -1
- package/dist/cli/__tests__/error-handling-warnings.test.d.ts +0 -2
- package/dist/cli/__tests__/error-handling-warnings.test.d.ts.map +0 -1
- package/dist/cli/__tests__/error-handling-warnings.test.js +0 -52
- package/dist/cli/__tests__/error-handling-warnings.test.js.map +0 -1
- package/dist/cli/__tests__/exec.test.d.ts +0 -2
- package/dist/cli/__tests__/exec.test.d.ts.map +0 -1
- package/dist/cli/__tests__/exec.test.js +0 -213
- package/dist/cli/__tests__/exec.test.js.map +0 -1
- package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts +0 -2
- package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts.map +0 -1
- package/dist/cli/__tests__/explore-windows-diagnostics.test.js +0 -17
- package/dist/cli/__tests__/explore-windows-diagnostics.test.js.map +0 -1
- package/dist/cli/__tests__/explore.test.d.ts +0 -2
- package/dist/cli/__tests__/explore.test.d.ts.map +0 -1
- package/dist/cli/__tests__/explore.test.js +0 -1090
- package/dist/cli/__tests__/explore.test.js.map +0 -1
- package/dist/cli/__tests__/hooks.test.d.ts +0 -2
- package/dist/cli/__tests__/hooks.test.d.ts.map +0 -1
- package/dist/cli/__tests__/hooks.test.js +0 -55
- package/dist/cli/__tests__/hooks.test.js.map +0 -1
- package/dist/cli/__tests__/index.test.d.ts +0 -2
- package/dist/cli/__tests__/index.test.d.ts.map +0 -1
- package/dist/cli/__tests__/index.test.js +0 -2259
- package/dist/cli/__tests__/index.test.js.map +0 -1
- package/dist/cli/__tests__/launch-fallback.test.d.ts +0 -2
- package/dist/cli/__tests__/launch-fallback.test.d.ts.map +0 -1
- package/dist/cli/__tests__/launch-fallback.test.js +0 -661
- package/dist/cli/__tests__/launch-fallback.test.js.map +0 -1
- package/dist/cli/__tests__/lifecycle-notifications.test.d.ts +0 -2
- package/dist/cli/__tests__/lifecycle-notifications.test.d.ts.map +0 -1
- package/dist/cli/__tests__/lifecycle-notifications.test.js +0 -48
- package/dist/cli/__tests__/lifecycle-notifications.test.js.map +0 -1
- package/dist/cli/__tests__/list.test.d.ts +0 -2
- package/dist/cli/__tests__/list.test.d.ts.map +0 -1
- package/dist/cli/__tests__/list.test.js +0 -38
- package/dist/cli/__tests__/list.test.js.map +0 -1
- package/dist/cli/__tests__/mcp-parity.test.d.ts +0 -2
- package/dist/cli/__tests__/mcp-parity.test.d.ts.map +0 -1
- package/dist/cli/__tests__/mcp-parity.test.js +0 -228
- package/dist/cli/__tests__/mcp-parity.test.js.map +0 -1
- package/dist/cli/__tests__/mcp-serve.test.d.ts +0 -2
- package/dist/cli/__tests__/mcp-serve.test.d.ts.map +0 -1
- package/dist/cli/__tests__/mcp-serve.test.js +0 -64
- package/dist/cli/__tests__/mcp-serve.test.js.map +0 -1
- package/dist/cli/__tests__/native-assets.test.d.ts +0 -2
- package/dist/cli/__tests__/native-assets.test.d.ts.map +0 -1
- package/dist/cli/__tests__/native-assets.test.js +0 -308
- package/dist/cli/__tests__/native-assets.test.js.map +0 -1
- package/dist/cli/__tests__/native-hook-dispatch-contract.test.d.ts +0 -2
- package/dist/cli/__tests__/native-hook-dispatch-contract.test.d.ts.map +0 -1
- package/dist/cli/__tests__/native-hook-dispatch-contract.test.js +0 -11
- package/dist/cli/__tests__/native-hook-dispatch-contract.test.js.map +0 -1
- package/dist/cli/__tests__/nested-help-routing.test.d.ts +0 -2
- package/dist/cli/__tests__/nested-help-routing.test.d.ts.map +0 -1
- package/dist/cli/__tests__/nested-help-routing.test.js +0 -96
- package/dist/cli/__tests__/nested-help-routing.test.js.map +0 -1
- package/dist/cli/__tests__/package-bin-contract.test.d.ts +0 -2
- package/dist/cli/__tests__/package-bin-contract.test.d.ts.map +0 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +0 -177
- package/dist/cli/__tests__/package-bin-contract.test.js.map +0 -1
- package/dist/cli/__tests__/packaged-explore-harness-lock.d.ts +0 -3
- package/dist/cli/__tests__/packaged-explore-harness-lock.d.ts.map +0 -1
- package/dist/cli/__tests__/packaged-explore-harness-lock.js +0 -67
- package/dist/cli/__tests__/packaged-explore-harness-lock.js.map +0 -1
- package/dist/cli/__tests__/packaged-script-resolution.test.d.ts +0 -2
- package/dist/cli/__tests__/packaged-script-resolution.test.d.ts.map +0 -1
- package/dist/cli/__tests__/packaged-script-resolution.test.js +0 -19
- package/dist/cli/__tests__/packaged-script-resolution.test.js.map +0 -1
- package/dist/cli/__tests__/prompt-skill-sanitization.test.d.ts +0 -2
- package/dist/cli/__tests__/prompt-skill-sanitization.test.d.ts.map +0 -1
- package/dist/cli/__tests__/prompt-skill-sanitization.test.js +0 -48
- package/dist/cli/__tests__/prompt-skill-sanitization.test.js.map +0 -1
- package/dist/cli/__tests__/question.test.d.ts +0 -2
- package/dist/cli/__tests__/question.test.d.ts.map +0 -1
- package/dist/cli/__tests__/question.test.js +0 -633
- package/dist/cli/__tests__/question.test.js.map +0 -1
- package/dist/cli/__tests__/ralph-deslop-contract.test.d.ts +0 -2
- package/dist/cli/__tests__/ralph-deslop-contract.test.d.ts.map +0 -1
- package/dist/cli/__tests__/ralph-deslop-contract.test.js +0 -28
- package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +0 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts +0 -2
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts.map +0 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +0 -24
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +0 -1
- package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts +0 -2
- package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts.map +0 -1
- package/dist/cli/__tests__/ralph-prd-smoke.test.js +0 -167
- package/dist/cli/__tests__/ralph-prd-smoke.test.js.map +0 -1
- package/dist/cli/__tests__/ralph.test.d.ts +0 -2
- package/dist/cli/__tests__/ralph.test.d.ts.map +0 -1
- package/dist/cli/__tests__/ralph.test.js +0 -256
- package/dist/cli/__tests__/ralph.test.js.map +0 -1
- package/dist/cli/__tests__/resume.test.d.ts +0 -2
- package/dist/cli/__tests__/resume.test.d.ts.map +0 -1
- package/dist/cli/__tests__/resume.test.js +0 -84
- package/dist/cli/__tests__/resume.test.js.map +0 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.d.ts +0 -2
- package/dist/cli/__tests__/session-scoped-runtime.test.d.ts.map +0 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +0 -146
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +0 -1
- package/dist/cli/__tests__/session-search-help.test.d.ts +0 -2
- package/dist/cli/__tests__/session-search-help.test.d.ts.map +0 -1
- package/dist/cli/__tests__/session-search-help.test.js +0 -76
- package/dist/cli/__tests__/session-search-help.test.js.map +0 -1
- package/dist/cli/__tests__/session-search.test.d.ts +0 -2
- package/dist/cli/__tests__/session-search.test.d.ts.map +0 -1
- package/dist/cli/__tests__/session-search.test.js +0 -77
- package/dist/cli/__tests__/session-search.test.js.map +0 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +0 -457
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +0 -1
- package/dist/cli/__tests__/setup-gh-star.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-gh-star.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-gh-star.test.js +0 -67
- package/dist/cli/__tests__/setup-gh-star.test.js.map +0 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +0 -189
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +0 -1
- package/dist/cli/__tests__/setup-install-mode.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-install-mode.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +0 -873
- package/dist/cli/__tests__/setup-install-mode.test.js.map +0 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-prompts-overwrite.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +0 -191
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +0 -1
- package/dist/cli/__tests__/setup-refresh.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-refresh.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-refresh.test.js +0 -591
- package/dist/cli/__tests__/setup-refresh.test.js.map +0 -1
- package/dist/cli/__tests__/setup-scope.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-scope.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-scope.test.js +0 -340
- package/dist/cli/__tests__/setup-scope.test.js.map +0 -1
- package/dist/cli/__tests__/setup-skill-validation.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-skill-validation.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-skill-validation.test.js +0 -44
- package/dist/cli/__tests__/setup-skill-validation.test.js.map +0 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts +0 -2
- package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts.map +0 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +0 -295
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +0 -1
- package/dist/cli/__tests__/sidecar.test.d.ts +0 -2
- package/dist/cli/__tests__/sidecar.test.d.ts.map +0 -1
- package/dist/cli/__tests__/sidecar.test.js +0 -24
- package/dist/cli/__tests__/sidecar.test.js.map +0 -1
- package/dist/cli/__tests__/sparkshell-cli.test.d.ts +0 -2
- package/dist/cli/__tests__/sparkshell-cli.test.d.ts.map +0 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js +0 -400
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +0 -1
- package/dist/cli/__tests__/sparkshell-packaging.test.d.ts +0 -2
- package/dist/cli/__tests__/sparkshell-packaging.test.d.ts.map +0 -1
- package/dist/cli/__tests__/sparkshell-packaging.test.js +0 -74
- package/dist/cli/__tests__/sparkshell-packaging.test.js.map +0 -1
- package/dist/cli/__tests__/star-prompt.test.d.ts +0 -2
- package/dist/cli/__tests__/star-prompt.test.d.ts.map +0 -1
- package/dist/cli/__tests__/star-prompt.test.js +0 -172
- package/dist/cli/__tests__/star-prompt.test.js.map +0 -1
- package/dist/cli/__tests__/state.test.d.ts +0 -2
- package/dist/cli/__tests__/state.test.d.ts.map +0 -1
- package/dist/cli/__tests__/state.test.js +0 -46
- package/dist/cli/__tests__/state.test.js.map +0 -1
- package/dist/cli/__tests__/team-decompose.test.d.ts +0 -2
- package/dist/cli/__tests__/team-decompose.test.d.ts.map +0 -1
- package/dist/cli/__tests__/team-decompose.test.js +0 -133
- package/dist/cli/__tests__/team-decompose.test.js.map +0 -1
- package/dist/cli/__tests__/team.test.d.ts +0 -2
- package/dist/cli/__tests__/team.test.d.ts.map +0 -1
- package/dist/cli/__tests__/team.test.js +0 -1820
- package/dist/cli/__tests__/team.test.js.map +0 -1
- package/dist/cli/__tests__/uninstall.test.d.ts +0 -2
- package/dist/cli/__tests__/uninstall.test.d.ts.map +0 -1
- package/dist/cli/__tests__/uninstall.test.js +0 -766
- package/dist/cli/__tests__/uninstall.test.js.map +0 -1
- package/dist/cli/__tests__/update.test.d.ts +0 -2
- package/dist/cli/__tests__/update.test.d.ts.map +0 -1
- package/dist/cli/__tests__/update.test.js +0 -589
- package/dist/cli/__tests__/update.test.js.map +0 -1
- package/dist/cli/__tests__/version-sync-contract.test.d.ts +0 -2
- package/dist/cli/__tests__/version-sync-contract.test.d.ts.map +0 -1
- package/dist/cli/__tests__/version-sync-contract.test.js +0 -41
- package/dist/cli/__tests__/version-sync-contract.test.js.map +0 -1
- package/dist/cli/__tests__/version.test.d.ts +0 -2
- package/dist/cli/__tests__/version.test.d.ts.map +0 -1
- package/dist/cli/__tests__/version.test.js +0 -21
- package/dist/cli/__tests__/version.test.js.map +0 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +0 -2
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +0 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +0 -31
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +0 -1
- package/dist/cli/ralph.d.ts +0 -17
- package/dist/compat/__tests__/doctor-contract.test.d.ts +0 -2
- package/dist/compat/__tests__/doctor-contract.test.d.ts.map +0 -1
- package/dist/compat/__tests__/doctor-contract.test.js +0 -108
- package/dist/compat/__tests__/doctor-contract.test.js.map +0 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.d.ts +0 -2
- package/dist/compat/__tests__/rust-runtime-compat.test.d.ts.map +0 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.js +0 -218
- package/dist/compat/__tests__/rust-runtime-compat.test.js.map +0 -1
- package/dist/config/__tests__/codex-hooks.test.d.ts +0 -2
- package/dist/config/__tests__/codex-hooks.test.d.ts.map +0 -1
- package/dist/config/__tests__/codex-hooks.test.js +0 -77
- package/dist/config/__tests__/codex-hooks.test.js.map +0 -1
- package/dist/config/__tests__/generator-idempotent.test.d.ts +0 -2
- package/dist/config/__tests__/generator-idempotent.test.d.ts.map +0 -1
- package/dist/config/__tests__/generator-idempotent.test.js +0 -882
- package/dist/config/__tests__/generator-idempotent.test.js.map +0 -1
- package/dist/config/__tests__/generator-notify.test.d.ts +0 -2
- package/dist/config/__tests__/generator-notify.test.d.ts.map +0 -1
- package/dist/config/__tests__/generator-notify.test.js +0 -343
- package/dist/config/__tests__/generator-notify.test.js.map +0 -1
- package/dist/config/__tests__/generator-status-line-presets.test.d.ts +0 -2
- package/dist/config/__tests__/generator-status-line-presets.test.d.ts.map +0 -1
- package/dist/config/__tests__/generator-status-line-presets.test.js +0 -203
- package/dist/config/__tests__/generator-status-line-presets.test.js.map +0 -1
- package/dist/config/__tests__/mcp-registry.test.d.ts +0 -2
- package/dist/config/__tests__/mcp-registry.test.d.ts.map +0 -1
- package/dist/config/__tests__/mcp-registry.test.js +0 -190
- package/dist/config/__tests__/mcp-registry.test.js.map +0 -1
- package/dist/config/__tests__/models.test.d.ts +0 -2
- package/dist/config/__tests__/models.test.d.ts.map +0 -1
- package/dist/config/__tests__/models.test.js +0 -224
- package/dist/config/__tests__/models.test.js.map +0 -1
- package/dist/config/__tests__/wiki-config-contract.test.d.ts +0 -2
- package/dist/config/__tests__/wiki-config-contract.test.d.ts.map +0 -1
- package/dist/config/__tests__/wiki-config-contract.test.js +0 -19
- package/dist/config/__tests__/wiki-config-contract.test.js.map +0 -1
- package/dist/document-refresh/__tests__/enforcer.test.d.ts +0 -2
- package/dist/document-refresh/__tests__/enforcer.test.d.ts.map +0 -1
- package/dist/document-refresh/__tests__/enforcer.test.js +0 -128
- package/dist/document-refresh/__tests__/enforcer.test.js.map +0 -1
- package/dist/hooks/__tests__/agents-overlay.test.d.ts +0 -8
- package/dist/hooks/__tests__/agents-overlay.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +0 -644
- package/dist/hooks/__tests__/agents-overlay.test.js.map +0 -1
- package/dist/hooks/__tests__/analyze-routing-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/analyze-routing-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/analyze-routing-contract.test.js +0 -45
- package/dist/hooks/__tests__/analyze-routing-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/analyze-skill-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/analyze-skill-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/analyze-skill-contract.test.js +0 -48
- package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/anti-slop-workflow.test.d.ts +0 -2
- package/dist/hooks/__tests__/anti-slop-workflow.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/anti-slop-workflow.test.js +0 -146
- package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +0 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +0 -37
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/clawhip-event-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/clawhip-event-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/clawhip-event-contract.test.js +0 -37
- package/dist/hooks/__tests__/clawhip-event-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/code-review-skill-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.js +0 -56
- package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/codebase-map.test.d.ts +0 -8
- package/dist/hooks/__tests__/codebase-map.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/codebase-map.test.js +0 -218
- package/dist/hooks/__tests__/codebase-map.test.js.map +0 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +0 -18
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js +0 -234
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +0 -1
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.js +0 -20
- package/dist/hooks/__tests__/debugger-log-recency-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/deep-interview-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +0 -213
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.js +0 -43
- package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.js +0 -38
- package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/explore-routing.test.d.ts +0 -2
- package/dist/hooks/__tests__/explore-routing.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/explore-routing.test.js +0 -43
- package/dist/hooks/__tests__/explore-routing.test.js.map +0 -1
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +0 -69
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/keyword-detector.test.d.ts +0 -2
- package/dist/hooks/__tests__/keyword-detector.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +0 -1716
- package/dist/hooks/__tests__/keyword-detector.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +0 -3898
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +0 -786
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +0 -2397
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +0 -160
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +0 -1178
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.d.ts +0 -9
- package/dist/hooks/__tests__/notify-hook-modules.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +0 -529
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.js +0 -14
- package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +0 -682
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts +0 -9
- package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +0 -255
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +0 -162
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-session-scope.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +0 -301
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +0 -1510
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +0 -2879
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +0 -228
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +0 -35
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +0 -1589
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.d.ts +0 -10
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts +0 -11
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js +0 -266
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +0 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts +0 -2
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +0 -895
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +0 -1
- package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js +0 -61
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts +0 -2
- package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +0 -40
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-catalog.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-guidance-catalog.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-catalog.test.js +0 -11
- package/dist/hooks/__tests__/prompt-guidance-catalog.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-guidance-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js +0 -38
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js +0 -48
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-scenarios.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-guidance-scenarios.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-scenarios.test.js +0 -11
- package/dist/hooks/__tests__/prompt-guidance-scenarios.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-test-helpers.d.ts +0 -5
- package/dist/hooks/__tests__/prompt-guidance-test-helpers.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-test-helpers.js +0 -34
- package/dist/hooks/__tests__/prompt-guidance-test-helpers.js.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +0 -65
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-orchestration-boundary.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-orchestration-boundary.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-orchestration-boundary.test.js +0 -38
- package/dist/hooks/__tests__/prompt-orchestration-boundary.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-refactor-contract.test.js +0 -22
- package/dist/hooks/__tests__/prompt-refactor-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/prompt-team-routing.test.d.ts +0 -2
- package/dist/hooks/__tests__/prompt-team-routing.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prompt-team-routing.test.js +0 -49
- package/dist/hooks/__tests__/prompt-team-routing.test.js.map +0 -1
- package/dist/hooks/__tests__/session.test.d.ts +0 -2
- package/dist/hooks/__tests__/session.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/session.test.js +0 -322
- package/dist/hooks/__tests__/session.test.js.map +0 -1
- package/dist/hooks/__tests__/skill-guidance-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/skill-guidance-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/skill-guidance-contract.test.js +0 -29
- package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/task-size-detector.test.d.ts +0 -2
- package/dist/hooks/__tests__/task-size-detector.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/task-size-detector.test.js +0 -330
- package/dist/hooks/__tests__/task-size-detector.test.js.map +0 -1
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +0 -28
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +0 -1
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts +0 -2
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js +0 -24
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js.map +0 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.d.ts +0 -2
- package/dist/hooks/__tests__/tmux-hook-engine.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js +0 -403
- package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +0 -1
- package/dist/hooks/__tests__/triage-config.test.d.ts +0 -2
- package/dist/hooks/__tests__/triage-config.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/triage-config.test.js +0 -211
- package/dist/hooks/__tests__/triage-config.test.js.map +0 -1
- package/dist/hooks/__tests__/triage-heuristic.test.d.ts +0 -2
- package/dist/hooks/__tests__/triage-heuristic.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/triage-heuristic.test.js +0 -285
- package/dist/hooks/__tests__/triage-heuristic.test.js.map +0 -1
- package/dist/hooks/__tests__/triage-state.test.d.ts +0 -2
- package/dist/hooks/__tests__/triage-state.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/triage-state.test.js +0 -426
- package/dist/hooks/__tests__/triage-state.test.js.map +0 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts +0 -2
- package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.js +0 -44
- package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +0 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts +0 -2
- package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.js +0 -35
- package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +0 -1
- package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/wiki-docs-contract.test.js +0 -34
- package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +0 -1
- package/dist/hooks/code-simplifier/__tests__/index.test.d.ts +0 -2
- package/dist/hooks/code-simplifier/__tests__/index.test.d.ts.map +0 -1
- package/dist/hooks/code-simplifier/__tests__/index.test.js +0 -187
- package/dist/hooks/code-simplifier/__tests__/index.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +0 -242
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/events.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/events.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/events.test.js +0 -125
- package/dist/hooks/extensibility/__tests__/events.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js +0 -153
- package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/loader.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/loader.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/loader.test.js +0 -254
- package/dist/hooks/extensibility/__tests__/loader.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/logging.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/logging.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/logging.test.js +0 -74
- package/dist/hooks/extensibility/__tests__/logging.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +0 -202
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/runtime.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/runtime.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/runtime.test.js +0 -198
- package/dist/hooks/extensibility/__tests__/runtime.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.js +0 -32
- package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.js.map +0 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.d.ts +0 -2
- package/dist/hooks/extensibility/__tests__/sdk.test.d.ts.map +0 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js +0 -479
- package/dist/hooks/extensibility/__tests__/sdk.test.js.map +0 -1
- package/dist/hud/__tests__/authority.test.d.ts +0 -2
- package/dist/hud/__tests__/authority.test.d.ts.map +0 -1
- package/dist/hud/__tests__/authority.test.js +0 -56
- package/dist/hud/__tests__/authority.test.js.map +0 -1
- package/dist/hud/__tests__/colors.test.d.ts +0 -2
- package/dist/hud/__tests__/colors.test.d.ts.map +0 -1
- package/dist/hud/__tests__/colors.test.js +0 -92
- package/dist/hud/__tests__/colors.test.js.map +0 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.d.ts +0 -10
- package/dist/hud/__tests__/hud-tmux-injection.test.d.ts.map +0 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +0 -150
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +0 -1
- package/dist/hud/__tests__/index.test.d.ts +0 -2
- package/dist/hud/__tests__/index.test.d.ts.map +0 -1
- package/dist/hud/__tests__/index.test.js +0 -180
- package/dist/hud/__tests__/index.test.js.map +0 -1
- package/dist/hud/__tests__/reconcile.test.d.ts +0 -2
- package/dist/hud/__tests__/reconcile.test.d.ts.map +0 -1
- package/dist/hud/__tests__/reconcile.test.js +0 -125
- package/dist/hud/__tests__/reconcile.test.js.map +0 -1
- package/dist/hud/__tests__/render.test.d.ts +0 -2
- package/dist/hud/__tests__/render.test.d.ts.map +0 -1
- package/dist/hud/__tests__/render.test.js +0 -573
- package/dist/hud/__tests__/render.test.js.map +0 -1
- package/dist/hud/__tests__/state.test.d.ts +0 -2
- package/dist/hud/__tests__/state.test.d.ts.map +0 -1
- package/dist/hud/__tests__/state.test.js +0 -618
- package/dist/hud/__tests__/state.test.js.map +0 -1
- package/dist/hud/__tests__/types.test.d.ts +0 -2
- package/dist/hud/__tests__/types.test.d.ts.map +0 -1
- package/dist/hud/__tests__/types.test.js +0 -79
- package/dist/hud/__tests__/types.test.js.map +0 -1
- package/dist/hud/__tests__/watch.test.d.ts +0 -2
- package/dist/hud/__tests__/watch.test.d.ts.map +0 -1
- package/dist/hud/__tests__/watch.test.js +0 -63
- package/dist/hud/__tests__/watch.test.js.map +0 -1
- package/dist/mcp/__tests__/bootstrap.test.d.ts +0 -2
- package/dist/mcp/__tests__/bootstrap.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/bootstrap.test.js +0 -207
- package/dist/mcp/__tests__/bootstrap.test.js.map +0 -1
- package/dist/mcp/__tests__/code-intel-server.test.d.ts +0 -2
- package/dist/mcp/__tests__/code-intel-server.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/code-intel-server.test.js +0 -70
- package/dist/mcp/__tests__/code-intel-server.test.js.map +0 -1
- package/dist/mcp/__tests__/memory-server.test.d.ts +0 -2
- package/dist/mcp/__tests__/memory-server.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/memory-server.test.js +0 -36
- package/dist/mcp/__tests__/memory-server.test.js.map +0 -1
- package/dist/mcp/__tests__/memory-validation.test.d.ts +0 -2
- package/dist/mcp/__tests__/memory-validation.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/memory-validation.test.js +0 -29
- package/dist/mcp/__tests__/memory-validation.test.js.map +0 -1
- package/dist/mcp/__tests__/path-traversal.test.d.ts +0 -2
- package/dist/mcp/__tests__/path-traversal.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/path-traversal.test.js +0 -83
- package/dist/mcp/__tests__/path-traversal.test.js.map +0 -1
- package/dist/mcp/__tests__/server-lifecycle.test.d.ts +0 -2
- package/dist/mcp/__tests__/server-lifecycle.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +0 -260
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +0 -1
- package/dist/mcp/__tests__/state-paths.test.d.ts +0 -2
- package/dist/mcp/__tests__/state-paths.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/state-paths.test.js +0 -209
- package/dist/mcp/__tests__/state-paths.test.js.map +0 -1
- package/dist/mcp/__tests__/state-server-ralph-phase.test.d.ts +0 -2
- package/dist/mcp/__tests__/state-server-ralph-phase.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js +0 -109
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +0 -1
- package/dist/mcp/__tests__/state-server-schema.test.d.ts +0 -2
- package/dist/mcp/__tests__/state-server-schema.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/state-server-schema.test.js +0 -29
- package/dist/mcp/__tests__/state-server-schema.test.js.map +0 -1
- package/dist/mcp/__tests__/state-server-team-tools.test.d.ts +0 -2
- package/dist/mcp/__tests__/state-server-team-tools.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/state-server-team-tools.test.js +0 -35
- package/dist/mcp/__tests__/state-server-team-tools.test.js.map +0 -1
- package/dist/mcp/__tests__/state-server.test.d.ts +0 -2
- package/dist/mcp/__tests__/state-server.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/state-server.test.js +0 -965
- package/dist/mcp/__tests__/state-server.test.js.map +0 -1
- package/dist/mcp/__tests__/trace-server.test.d.ts +0 -2
- package/dist/mcp/__tests__/trace-server.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/trace-server.test.js +0 -119
- package/dist/mcp/__tests__/trace-server.test.js.map +0 -1
- package/dist/mcp/__tests__/wiki-server.test.d.ts +0 -2
- package/dist/mcp/__tests__/wiki-server.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/wiki-server.test.js +0 -30
- package/dist/mcp/__tests__/wiki-server.test.js.map +0 -1
- package/dist/modes/__tests__/base-autoresearch-contract.test.d.ts +0 -2
- package/dist/modes/__tests__/base-autoresearch-contract.test.d.ts.map +0 -1
- package/dist/modes/__tests__/base-autoresearch-contract.test.js +0 -123
- package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +0 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.d.ts +0 -2
- package/dist/modes/__tests__/base-multi-state-compat.test.d.ts.map +0 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.js +0 -38
- package/dist/modes/__tests__/base-multi-state-compat.test.js.map +0 -1
- package/dist/modes/__tests__/base-ralph-contract.test.d.ts +0 -2
- package/dist/modes/__tests__/base-ralph-contract.test.d.ts.map +0 -1
- package/dist/modes/__tests__/base-ralph-contract.test.js +0 -64
- package/dist/modes/__tests__/base-ralph-contract.test.js.map +0 -1
- package/dist/modes/__tests__/base-session-scope.test.d.ts +0 -2
- package/dist/modes/__tests__/base-session-scope.test.d.ts.map +0 -1
- package/dist/modes/__tests__/base-session-scope.test.js +0 -98
- package/dist/modes/__tests__/base-session-scope.test.js.map +0 -1
- package/dist/modes/__tests__/base-tmux-pane.test.d.ts +0 -2
- package/dist/modes/__tests__/base-tmux-pane.test.d.ts.map +0 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js +0 -39
- package/dist/modes/__tests__/base-tmux-pane.test.js.map +0 -1
- package/dist/notifications/__tests__/config.test.d.ts +0 -2
- package/dist/notifications/__tests__/config.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/config.test.js +0 -269
- package/dist/notifications/__tests__/config.test.js.map +0 -1
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +0 -2
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/custom-alias-enablement.test.js +0 -84
- package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +0 -1
- package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts +0 -5
- package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/dispatch-cooldown.test.js +0 -100
- package/dist/notifications/__tests__/dispatch-cooldown.test.js.map +0 -1
- package/dist/notifications/__tests__/dispatcher.test.d.ts +0 -2
- package/dist/notifications/__tests__/dispatcher.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/dispatcher.test.js +0 -202
- package/dist/notifications/__tests__/dispatcher.test.js.map +0 -1
- package/dist/notifications/__tests__/formatter.test.d.ts +0 -2
- package/dist/notifications/__tests__/formatter.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/formatter.test.js +0 -270
- package/dist/notifications/__tests__/formatter.test.js.map +0 -1
- package/dist/notifications/__tests__/hook-config.test.d.ts +0 -5
- package/dist/notifications/__tests__/hook-config.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/hook-config.test.js +0 -139
- package/dist/notifications/__tests__/hook-config.test.js.map +0 -1
- package/dist/notifications/__tests__/idle-cooldown.test.d.ts +0 -5
- package/dist/notifications/__tests__/idle-cooldown.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/idle-cooldown.test.js +0 -209
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +0 -1
- package/dist/notifications/__tests__/index.test.d.ts +0 -2
- package/dist/notifications/__tests__/index.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/index.test.js +0 -188
- package/dist/notifications/__tests__/index.test.js.map +0 -1
- package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts +0 -2
- package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/lifecycle-dedupe.test.js +0 -86
- package/dist/notifications/__tests__/lifecycle-dedupe.test.js.map +0 -1
- package/dist/notifications/__tests__/notifier.test.d.ts +0 -2
- package/dist/notifications/__tests__/notifier.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/notifier.test.js +0 -239
- package/dist/notifications/__tests__/notifier.test.js.map +0 -1
- package/dist/notifications/__tests__/profiles.test.d.ts +0 -2
- package/dist/notifications/__tests__/profiles.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/profiles.test.js +0 -404
- package/dist/notifications/__tests__/profiles.test.js.map +0 -1
- package/dist/notifications/__tests__/reply-config.test.d.ts +0 -2
- package/dist/notifications/__tests__/reply-config.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/reply-config.test.js +0 -79
- package/dist/notifications/__tests__/reply-config.test.js.map +0 -1
- package/dist/notifications/__tests__/reply-listener.test.d.ts +0 -2
- package/dist/notifications/__tests__/reply-listener.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/reply-listener.test.js +0 -723
- package/dist/notifications/__tests__/reply-listener.test.js.map +0 -1
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts +0 -2
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js +0 -93
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js.map +0 -1
- package/dist/notifications/__tests__/session-registry.test.d.ts +0 -2
- package/dist/notifications/__tests__/session-registry.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/session-registry.test.js +0 -234
- package/dist/notifications/__tests__/session-registry.test.js.map +0 -1
- package/dist/notifications/__tests__/session-status.test.d.ts +0 -2
- package/dist/notifications/__tests__/session-status.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/session-status.test.js +0 -249
- package/dist/notifications/__tests__/session-status.test.js.map +0 -1
- package/dist/notifications/__tests__/temp-mode.test.d.ts +0 -2
- package/dist/notifications/__tests__/temp-mode.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/temp-mode.test.js +0 -172
- package/dist/notifications/__tests__/temp-mode.test.js.map +0 -1
- package/dist/notifications/__tests__/template-engine.test.d.ts +0 -5
- package/dist/notifications/__tests__/template-engine.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/template-engine.test.js +0 -158
- package/dist/notifications/__tests__/template-engine.test.js.map +0 -1
- package/dist/notifications/__tests__/tmux-detector.test.d.ts +0 -2
- package/dist/notifications/__tests__/tmux-detector.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/tmux-detector.test.js +0 -208
- package/dist/notifications/__tests__/tmux-detector.test.js.map +0 -1
- package/dist/notifications/__tests__/tmux.test.d.ts +0 -2
- package/dist/notifications/__tests__/tmux.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/tmux.test.js +0 -285
- package/dist/notifications/__tests__/tmux.test.js.map +0 -1
- package/dist/notifications/__tests__/verbosity.test.d.ts +0 -2
- package/dist/notifications/__tests__/verbosity.test.d.ts.map +0 -1
- package/dist/notifications/__tests__/verbosity.test.js +0 -237
- package/dist/notifications/__tests__/verbosity.test.js.map +0 -1
- package/dist/openclaw/__tests__/config.test.d.ts +0 -6
- package/dist/openclaw/__tests__/config.test.d.ts.map +0 -1
- package/dist/openclaw/__tests__/config.test.js +0 -344
- package/dist/openclaw/__tests__/config.test.js.map +0 -1
- package/dist/openclaw/__tests__/dispatcher.test.d.ts +0 -5
- package/dist/openclaw/__tests__/dispatcher.test.d.ts.map +0 -1
- package/dist/openclaw/__tests__/dispatcher.test.js +0 -169
- package/dist/openclaw/__tests__/dispatcher.test.js.map +0 -1
- package/dist/openclaw/__tests__/index.test.d.ts +0 -6
- package/dist/openclaw/__tests__/index.test.d.ts.map +0 -1
- package/dist/openclaw/__tests__/index.test.js +0 -382
- package/dist/openclaw/__tests__/index.test.js.map +0 -1
- package/dist/pipeline/__tests__/orchestrator.test.d.ts +0 -2
- package/dist/pipeline/__tests__/orchestrator.test.d.ts.map +0 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +0 -505
- package/dist/pipeline/__tests__/orchestrator.test.js.map +0 -1
- package/dist/pipeline/__tests__/stages.test.d.ts +0 -2
- package/dist/pipeline/__tests__/stages.test.d.ts.map +0 -1
- package/dist/pipeline/__tests__/stages.test.js +0 -754
- package/dist/pipeline/__tests__/stages.test.js.map +0 -1
- package/dist/pipeline/stages/ralph-verify.d.ts +0 -53
- package/dist/pipeline/stages/ralph-verify.d.ts.map +0 -1
- package/dist/pipeline/stages/ralph-verify.js.map +0 -1
- package/dist/pipeline/stages/ralplan.d.ts +0 -25
- package/dist/pipeline/stages/ralplan.d.ts.map +0 -1
- package/dist/pipeline/stages/ralplan.js.map +0 -1
- package/dist/planning/__tests__/artifacts.test.d.ts +0 -2
- package/dist/planning/__tests__/artifacts.test.d.ts.map +0 -1
- package/dist/planning/__tests__/artifacts.test.js +0 -544
- package/dist/planning/__tests__/artifacts.test.js.map +0 -1
- package/dist/question/__tests__/client.test.d.ts +0 -2
- package/dist/question/__tests__/client.test.d.ts.map +0 -1
- package/dist/question/__tests__/client.test.js +0 -90
- package/dist/question/__tests__/client.test.js.map +0 -1
- package/dist/question/__tests__/deep-interview.test.d.ts +0 -2
- package/dist/question/__tests__/deep-interview.test.d.ts.map +0 -1
- package/dist/question/__tests__/deep-interview.test.js +0 -209
- package/dist/question/__tests__/deep-interview.test.js.map +0 -1
- package/dist/question/__tests__/policy.test.d.ts +0 -2
- package/dist/question/__tests__/policy.test.d.ts.map +0 -1
- package/dist/question/__tests__/policy.test.js +0 -107
- package/dist/question/__tests__/policy.test.js.map +0 -1
- package/dist/question/__tests__/renderer.test.d.ts +0 -2
- package/dist/question/__tests__/renderer.test.d.ts.map +0 -1
- package/dist/question/__tests__/renderer.test.js +0 -707
- package/dist/question/__tests__/renderer.test.js.map +0 -1
- package/dist/question/__tests__/state.test.d.ts +0 -2
- package/dist/question/__tests__/state.test.d.ts.map +0 -1
- package/dist/question/__tests__/state.test.js +0 -102
- package/dist/question/__tests__/state.test.js.map +0 -1
- package/dist/question/__tests__/types.test.d.ts +0 -2
- package/dist/question/__tests__/types.test.d.ts.map +0 -1
- package/dist/question/__tests__/types.test.js +0 -65
- package/dist/question/__tests__/types.test.js.map +0 -1
- package/dist/question/__tests__/ui.test.d.ts +0 -2
- package/dist/question/__tests__/ui.test.d.ts.map +0 -1
- package/dist/question/__tests__/ui.test.js +0 -446
- package/dist/question/__tests__/ui.test.js.map +0 -1
- package/dist/ralph/__tests__/persistence.test.d.ts +0 -2
- package/dist/ralph/__tests__/persistence.test.d.ts.map +0 -1
- package/dist/ralph/__tests__/persistence.test.js +0 -116
- package/dist/ralph/__tests__/persistence.test.js.map +0 -1
- package/dist/ralph/contract.d.ts +0 -17
- package/dist/ralph/persistence.js.map +0 -1
- package/dist/ralplan/__tests__/runtime.test.d.ts +0 -2
- package/dist/ralplan/__tests__/runtime.test.d.ts.map +0 -1
- package/dist/ralplan/__tests__/runtime.test.js +0 -165
- package/dist/ralplan/__tests__/runtime.test.js.map +0 -1
- package/dist/ralplan/runtime.d.ts +0 -52
- package/dist/ralplan/runtime.d.ts.map +0 -1
- package/dist/ralplan/runtime.js.map +0 -1
- package/dist/runtime/__tests__/bridge.test.d.ts +0 -2
- package/dist/runtime/__tests__/bridge.test.d.ts.map +0 -1
- package/dist/runtime/__tests__/bridge.test.js +0 -194
- package/dist/runtime/__tests__/bridge.test.js.map +0 -1
- package/dist/runtime/__tests__/run-loop.test.d.ts +0 -2
- package/dist/runtime/__tests__/run-loop.test.d.ts.map +0 -1
- package/dist/runtime/__tests__/run-loop.test.js +0 -35
- package/dist/runtime/__tests__/run-loop.test.js.map +0 -1
- package/dist/runtime/__tests__/run-outcome.test.d.ts +0 -2
- package/dist/runtime/__tests__/run-outcome.test.d.ts.map +0 -1
- package/dist/runtime/__tests__/run-outcome.test.js +0 -102
- package/dist/runtime/__tests__/run-outcome.test.js.map +0 -1
- package/dist/runtime/__tests__/run-state.test.d.ts +0 -2
- package/dist/runtime/__tests__/run-state.test.d.ts.map +0 -1
- package/dist/runtime/__tests__/run-state.test.js +0 -37
- package/dist/runtime/__tests__/run-state.test.js.map +0 -1
- package/dist/scripts/__tests__/codex-native-hook.test.d.ts +0 -2
- package/dist/scripts/__tests__/codex-native-hook.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +0 -6788
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +0 -1
- package/dist/scripts/__tests__/generate-release-body.test.d.ts +0 -2
- package/dist/scripts/__tests__/generate-release-body.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/generate-release-body.test.js +0 -233
- package/dist/scripts/__tests__/generate-release-body.test.js.map +0 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts +0 -2
- package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.js +0 -195
- package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +0 -1
- package/dist/scripts/__tests__/postinstall.test.d.ts +0 -2
- package/dist/scripts/__tests__/postinstall.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/postinstall.test.js +0 -92
- package/dist/scripts/__tests__/postinstall.test.js.map +0 -1
- package/dist/scripts/__tests__/prompt-inventory.test.d.ts +0 -2
- package/dist/scripts/__tests__/prompt-inventory.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/prompt-inventory.test.js +0 -56
- package/dist/scripts/__tests__/prompt-inventory.test.js.map +0 -1
- package/dist/scripts/__tests__/run-test-files.test.d.ts +0 -2
- package/dist/scripts/__tests__/run-test-files.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/run-test-files.test.js +0 -62
- package/dist/scripts/__tests__/run-test-files.test.js.map +0 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.d.ts +0 -2
- package/dist/scripts/__tests__/smoke-packed-install.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +0 -135
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +0 -1
- package/dist/scripts/__tests__/test-reply-listener-live.test.d.ts +0 -2
- package/dist/scripts/__tests__/test-reply-listener-live.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/test-reply-listener-live.test.js +0 -82
- package/dist/scripts/__tests__/test-reply-listener-live.test.js.map +0 -1
- package/dist/scripts/__tests__/verify-native-agents.test.d.ts +0 -2
- package/dist/scripts/__tests__/verify-native-agents.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/verify-native-agents.test.js +0 -166
- package/dist/scripts/__tests__/verify-native-agents.test.js.map +0 -1
- package/dist/scripts/eval/eval-candidate-handoff.d.ts +0 -2
- package/dist/scripts/eval/eval-candidate-handoff.d.ts.map +0 -1
- package/dist/scripts/eval/eval-candidate-handoff.js +0 -11
- package/dist/scripts/eval/eval-candidate-handoff.js.map +0 -1
- package/dist/scripts/eval/eval-cli-discoverability.d.ts +0 -3
- package/dist/scripts/eval/eval-cli-discoverability.d.ts.map +0 -1
- package/dist/scripts/eval/eval-cli-discoverability.js +0 -37
- package/dist/scripts/eval/eval-cli-discoverability.js.map +0 -1
- package/dist/scripts/eval/eval-fresh-run-tagging.d.ts +0 -2
- package/dist/scripts/eval/eval-fresh-run-tagging.d.ts.map +0 -1
- package/dist/scripts/eval/eval-fresh-run-tagging.js +0 -11
- package/dist/scripts/eval/eval-fresh-run-tagging.js.map +0 -1
- package/dist/scripts/eval/eval-help-consistency.d.ts +0 -2
- package/dist/scripts/eval/eval-help-consistency.d.ts.map +0 -1
- package/dist/scripts/eval/eval-help-consistency.js +0 -12
- package/dist/scripts/eval/eval-help-consistency.js.map +0 -1
- package/dist/scripts/eval/eval-in-action-cat-shellout-demo.d.ts +0 -2
- package/dist/scripts/eval/eval-in-action-cat-shellout-demo.d.ts.map +0 -1
- package/dist/scripts/eval/eval-in-action-cat-shellout-demo.js +0 -31
- package/dist/scripts/eval/eval-in-action-cat-shellout-demo.js.map +0 -1
- package/dist/scripts/eval/eval-parity-smoke.d.ts +0 -2
- package/dist/scripts/eval/eval-parity-smoke.d.ts.map +0 -1
- package/dist/scripts/eval/eval-parity-smoke.js +0 -23
- package/dist/scripts/eval/eval-parity-smoke.js.map +0 -1
- package/dist/scripts/eval/eval-parity-sweep.d.ts +0 -2
- package/dist/scripts/eval/eval-parity-sweep.d.ts.map +0 -1
- package/dist/scripts/eval/eval-parity-sweep.js +0 -29
- package/dist/scripts/eval/eval-parity-sweep.js.map +0 -1
- package/dist/scripts/eval/eval-resume-dirty-guard.d.ts +0 -2
- package/dist/scripts/eval/eval-resume-dirty-guard.d.ts.map +0 -1
- package/dist/scripts/eval/eval-resume-dirty-guard.js +0 -11
- package/dist/scripts/eval/eval-resume-dirty-guard.js.map +0 -1
- package/dist/scripts/eval/eval-security-path-traversal.d.ts +0 -3
- package/dist/scripts/eval/eval-security-path-traversal.d.ts.map +0 -1
- package/dist/scripts/eval/eval-security-path-traversal.js +0 -35
- package/dist/scripts/eval/eval-security-path-traversal.js.map +0 -1
- package/dist/scripts/notify-hook/__tests__/operational-events.test.d.ts +0 -2
- package/dist/scripts/notify-hook/__tests__/operational-events.test.d.ts.map +0 -1
- package/dist/scripts/notify-hook/__tests__/operational-events.test.js +0 -24
- package/dist/scripts/notify-hook/__tests__/operational-events.test.js.map +0 -1
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts +0 -2
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts.map +0 -1
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js +0 -153
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js.map +0 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +0 -22
- package/dist/session-history/__tests__/search.test.d.ts +0 -2
- package/dist/session-history/__tests__/search.test.d.ts.map +0 -1
- package/dist/session-history/__tests__/search.test.js +0 -150
- package/dist/session-history/__tests__/search.test.js.map +0 -1
- package/dist/sidecar/__tests__/boundary.test.d.ts +0 -2
- package/dist/sidecar/__tests__/boundary.test.d.ts.map +0 -1
- package/dist/sidecar/__tests__/boundary.test.js +0 -48
- package/dist/sidecar/__tests__/boundary.test.js.map +0 -1
- package/dist/sidecar/__tests__/collector.test.d.ts +0 -2
- package/dist/sidecar/__tests__/collector.test.d.ts.map +0 -1
- package/dist/sidecar/__tests__/collector.test.js +0 -162
- package/dist/sidecar/__tests__/collector.test.js.map +0 -1
- package/dist/sidecar/__tests__/render.test.d.ts +0 -2
- package/dist/sidecar/__tests__/render.test.d.ts.map +0 -1
- package/dist/sidecar/__tests__/render.test.js +0 -67
- package/dist/sidecar/__tests__/render.test.js.map +0 -1
- package/dist/sidecar/__tests__/tmux.test.d.ts +0 -2
- package/dist/sidecar/__tests__/tmux.test.d.ts.map +0 -1
- package/dist/sidecar/__tests__/tmux.test.js +0 -30
- package/dist/sidecar/__tests__/tmux.test.js.map +0 -1
- package/dist/sidecar/__tests__/watch.test.d.ts +0 -2
- package/dist/sidecar/__tests__/watch.test.d.ts.map +0 -1
- package/dist/sidecar/__tests__/watch.test.js +0 -42
- package/dist/sidecar/__tests__/watch.test.js.map +0 -1
- package/dist/state/__tests__/mode-state-context.test.d.ts +0 -2
- package/dist/state/__tests__/mode-state-context.test.d.ts.map +0 -1
- package/dist/state/__tests__/mode-state-context.test.js +0 -35
- package/dist/state/__tests__/mode-state-context.test.js.map +0 -1
- package/dist/state/__tests__/operations-ralph-phase.test.d.ts +0 -2
- package/dist/state/__tests__/operations-ralph-phase.test.d.ts.map +0 -1
- package/dist/state/__tests__/operations-ralph-phase.test.js +0 -103
- package/dist/state/__tests__/operations-ralph-phase.test.js.map +0 -1
- package/dist/state/__tests__/operations.test.d.ts +0 -2
- package/dist/state/__tests__/operations.test.d.ts.map +0 -1
- package/dist/state/__tests__/operations.test.js +0 -439
- package/dist/state/__tests__/operations.test.js.map +0 -1
- package/dist/state/__tests__/path-traversal.test.d.ts +0 -2
- package/dist/state/__tests__/path-traversal.test.d.ts.map +0 -1
- package/dist/state/__tests__/path-traversal.test.js +0 -49
- package/dist/state/__tests__/path-traversal.test.js.map +0 -1
- package/dist/state/__tests__/skill-active.test.d.ts +0 -2
- package/dist/state/__tests__/skill-active.test.d.ts.map +0 -1
- package/dist/state/__tests__/skill-active.test.js +0 -160
- package/dist/state/__tests__/skill-active.test.js.map +0 -1
- package/dist/state/__tests__/workflow-transition.test.d.ts +0 -2
- package/dist/state/__tests__/workflow-transition.test.d.ts.map +0 -1
- package/dist/state/__tests__/workflow-transition.test.js +0 -77
- package/dist/state/__tests__/workflow-transition.test.js.map +0 -1
- package/dist/subagents/__tests__/tracker.test.d.ts +0 -2
- package/dist/subagents/__tests__/tracker.test.d.ts.map +0 -1
- package/dist/subagents/__tests__/tracker.test.js +0 -47
- package/dist/subagents/__tests__/tracker.test.js.map +0 -1
- package/dist/team/__tests__/allocation-policy.test.d.ts +0 -2
- package/dist/team/__tests__/allocation-policy.test.d.ts.map +0 -1
- package/dist/team/__tests__/allocation-policy.test.js +0 -111
- package/dist/team/__tests__/allocation-policy.test.js.map +0 -1
- package/dist/team/__tests__/api-interop.test.d.ts +0 -2
- package/dist/team/__tests__/api-interop.test.d.ts.map +0 -1
- package/dist/team/__tests__/api-interop.test.js +0 -2262
- package/dist/team/__tests__/api-interop.test.js.map +0 -1
- package/dist/team/__tests__/commit-hygiene.test.d.ts +0 -2
- package/dist/team/__tests__/commit-hygiene.test.d.ts.map +0 -1
- package/dist/team/__tests__/commit-hygiene.test.js +0 -93
- package/dist/team/__tests__/commit-hygiene.test.js.map +0 -1
- package/dist/team/__tests__/cross-rebase-smoke.test.d.ts +0 -2
- package/dist/team/__tests__/cross-rebase-smoke.test.d.ts.map +0 -1
- package/dist/team/__tests__/cross-rebase-smoke.test.js +0 -161
- package/dist/team/__tests__/cross-rebase-smoke.test.js.map +0 -1
- package/dist/team/__tests__/current-task-baseline.test.d.ts +0 -2
- package/dist/team/__tests__/current-task-baseline.test.d.ts.map +0 -1
- package/dist/team/__tests__/current-task-baseline.test.js +0 -87
- package/dist/team/__tests__/current-task-baseline.test.js.map +0 -1
- package/dist/team/__tests__/delegation-policy.test.d.ts +0 -2
- package/dist/team/__tests__/delegation-policy.test.d.ts.map +0 -1
- package/dist/team/__tests__/delegation-policy.test.js +0 -69
- package/dist/team/__tests__/delegation-policy.test.js.map +0 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts +0 -2
- package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts.map +0 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.js +0 -679
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +0 -1
- package/dist/team/__tests__/events.test.d.ts +0 -2
- package/dist/team/__tests__/events.test.d.ts.map +0 -1
- package/dist/team/__tests__/events.test.js +0 -313
- package/dist/team/__tests__/events.test.js.map +0 -1
- package/dist/team/__tests__/followup-planner.test.d.ts +0 -2
- package/dist/team/__tests__/followup-planner.test.d.ts.map +0 -1
- package/dist/team/__tests__/followup-planner.test.js +0 -84
- package/dist/team/__tests__/followup-planner.test.js.map +0 -1
- package/dist/team/__tests__/hardening-e2e.test.d.ts +0 -2
- package/dist/team/__tests__/hardening-e2e.test.d.ts.map +0 -1
- package/dist/team/__tests__/hardening-e2e.test.js +0 -98
- package/dist/team/__tests__/hardening-e2e.test.js.map +0 -1
- package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts +0 -2
- package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts.map +0 -1
- package/dist/team/__tests__/hook-primary-e2e-contract.test.js +0 -78
- package/dist/team/__tests__/hook-primary-e2e-contract.test.js.map +0 -1
- package/dist/team/__tests__/idle-nudge.test.d.ts +0 -2
- package/dist/team/__tests__/idle-nudge.test.d.ts.map +0 -1
- package/dist/team/__tests__/idle-nudge.test.js +0 -230
- package/dist/team/__tests__/idle-nudge.test.js.map +0 -1
- package/dist/team/__tests__/leader-activity.test.d.ts +0 -2
- package/dist/team/__tests__/leader-activity.test.d.ts.map +0 -1
- package/dist/team/__tests__/leader-activity.test.js +0 -261
- package/dist/team/__tests__/leader-activity.test.js.map +0 -1
- package/dist/team/__tests__/mcp-comm.test.d.ts +0 -2
- package/dist/team/__tests__/mcp-comm.test.d.ts.map +0 -1
- package/dist/team/__tests__/mcp-comm.test.js +0 -289
- package/dist/team/__tests__/mcp-comm.test.js.map +0 -1
- package/dist/team/__tests__/model-contract.test.d.ts +0 -2
- package/dist/team/__tests__/model-contract.test.d.ts.map +0 -1
- package/dist/team/__tests__/model-contract.test.js +0 -171
- package/dist/team/__tests__/model-contract.test.js.map +0 -1
- package/dist/team/__tests__/orchestrator.test.d.ts +0 -2
- package/dist/team/__tests__/orchestrator.test.d.ts.map +0 -1
- package/dist/team/__tests__/orchestrator.test.js +0 -111
- package/dist/team/__tests__/orchestrator.test.js.map +0 -1
- package/dist/team/__tests__/phase-controller.test.d.ts +0 -2
- package/dist/team/__tests__/phase-controller.test.d.ts.map +0 -1
- package/dist/team/__tests__/phase-controller.test.js +0 -50
- package/dist/team/__tests__/phase-controller.test.js.map +0 -1
- package/dist/team/__tests__/rebalance-policy.test.d.ts +0 -2
- package/dist/team/__tests__/rebalance-policy.test.d.ts.map +0 -1
- package/dist/team/__tests__/rebalance-policy.test.js +0 -168
- package/dist/team/__tests__/rebalance-policy.test.js.map +0 -1
- package/dist/team/__tests__/repo-aware-decomposition.test.d.ts +0 -2
- package/dist/team/__tests__/repo-aware-decomposition.test.d.ts.map +0 -1
- package/dist/team/__tests__/repo-aware-decomposition.test.js +0 -136
- package/dist/team/__tests__/repo-aware-decomposition.test.js.map +0 -1
- package/dist/team/__tests__/role-router.test.d.ts +0 -2
- package/dist/team/__tests__/role-router.test.d.ts.map +0 -1
- package/dist/team/__tests__/role-router.test.js +0 -263
- package/dist/team/__tests__/role-router.test.js.map +0 -1
- package/dist/team/__tests__/runtime-cli.test.d.ts +0 -2
- package/dist/team/__tests__/runtime-cli.test.d.ts.map +0 -1
- package/dist/team/__tests__/runtime-cli.test.js +0 -304
- package/dist/team/__tests__/runtime-cli.test.js.map +0 -1
- package/dist/team/__tests__/runtime.test.d.ts +0 -2
- package/dist/team/__tests__/runtime.test.d.ts.map +0 -1
- package/dist/team/__tests__/runtime.test.js +0 -5734
- package/dist/team/__tests__/runtime.test.js.map +0 -1
- package/dist/team/__tests__/scaling.test.d.ts +0 -2
- package/dist/team/__tests__/scaling.test.d.ts.map +0 -1
- package/dist/team/__tests__/scaling.test.js +0 -1005
- package/dist/team/__tests__/scaling.test.js.map +0 -1
- package/dist/team/__tests__/shutdown-fallback.test.d.ts +0 -2
- package/dist/team/__tests__/shutdown-fallback.test.d.ts.map +0 -1
- package/dist/team/__tests__/shutdown-fallback.test.js +0 -125
- package/dist/team/__tests__/shutdown-fallback.test.js.map +0 -1
- package/dist/team/__tests__/state-root.test.d.ts +0 -2
- package/dist/team/__tests__/state-root.test.d.ts.map +0 -1
- package/dist/team/__tests__/state-root.test.js +0 -195
- package/dist/team/__tests__/state-root.test.js.map +0 -1
- package/dist/team/__tests__/state.test.d.ts +0 -2
- package/dist/team/__tests__/state.test.d.ts.map +0 -1
- package/dist/team/__tests__/state.test.js +0 -1859
- package/dist/team/__tests__/state.test.js.map +0 -1
- package/dist/team/__tests__/team-identity.test.d.ts +0 -2
- package/dist/team/__tests__/team-identity.test.d.ts.map +0 -1
- package/dist/team/__tests__/team-identity.test.js +0 -166
- package/dist/team/__tests__/team-identity.test.js.map +0 -1
- package/dist/team/__tests__/team-ops-contract.test.d.ts +0 -2
- package/dist/team/__tests__/team-ops-contract.test.d.ts.map +0 -1
- package/dist/team/__tests__/team-ops-contract.test.js +0 -96
- package/dist/team/__tests__/team-ops-contract.test.js.map +0 -1
- package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts +0 -2
- package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts.map +0 -1
- package/dist/team/__tests__/tmux-claude-workers-demo.test.js +0 -191
- package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +0 -1
- package/dist/team/__tests__/tmux-session.test.d.ts +0 -2
- package/dist/team/__tests__/tmux-session.test.d.ts.map +0 -1
- package/dist/team/__tests__/tmux-session.test.js +0 -3785
- package/dist/team/__tests__/tmux-session.test.js.map +0 -1
- package/dist/team/__tests__/tmux-test-fixture.d.ts +0 -20
- package/dist/team/__tests__/tmux-test-fixture.d.ts.map +0 -1
- package/dist/team/__tests__/tmux-test-fixture.js +0 -152
- package/dist/team/__tests__/tmux-test-fixture.js.map +0 -1
- package/dist/team/__tests__/tmux-test-fixture.test.d.ts +0 -2
- package/dist/team/__tests__/tmux-test-fixture.test.d.ts.map +0 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js +0 -113
- package/dist/team/__tests__/tmux-test-fixture.test.js.map +0 -1
- package/dist/team/__tests__/worker-bootstrap.test.d.ts +0 -2
- package/dist/team/__tests__/worker-bootstrap.test.d.ts.map +0 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +0 -685
- package/dist/team/__tests__/worker-bootstrap.test.js.map +0 -1
- package/dist/team/__tests__/worker-runtime-identity.test.d.ts +0 -2
- package/dist/team/__tests__/worker-runtime-identity.test.d.ts.map +0 -1
- package/dist/team/__tests__/worker-runtime-identity.test.js +0 -250
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +0 -1
- package/dist/team/__tests__/worktree.test.d.ts +0 -2
- package/dist/team/__tests__/worktree.test.d.ts.map +0 -1
- package/dist/team/__tests__/worktree.test.js +0 -317
- package/dist/team/__tests__/worktree.test.js.map +0 -1
- package/dist/utils/__tests__/agents-md.test.d.ts +0 -2
- package/dist/utils/__tests__/agents-md.test.d.ts.map +0 -1
- package/dist/utils/__tests__/agents-md.test.js +0 -52
- package/dist/utils/__tests__/agents-md.test.js.map +0 -1
- package/dist/utils/__tests__/agents-model-table.test.d.ts +0 -2
- package/dist/utils/__tests__/agents-model-table.test.d.ts.map +0 -1
- package/dist/utils/__tests__/agents-model-table.test.js +0 -104
- package/dist/utils/__tests__/agents-model-table.test.js.map +0 -1
- package/dist/utils/__tests__/dep-versions.test.d.ts +0 -2
- package/dist/utils/__tests__/dep-versions.test.d.ts.map +0 -1
- package/dist/utils/__tests__/dep-versions.test.js +0 -46
- package/dist/utils/__tests__/dep-versions.test.js.map +0 -1
- package/dist/utils/__tests__/package.test.d.ts +0 -2
- package/dist/utils/__tests__/package.test.d.ts.map +0 -1
- package/dist/utils/__tests__/package.test.js +0 -21
- package/dist/utils/__tests__/package.test.js.map +0 -1
- package/dist/utils/__tests__/paths.test.d.ts +0 -2
- package/dist/utils/__tests__/paths.test.d.ts.map +0 -1
- package/dist/utils/__tests__/paths.test.js +0 -541
- package/dist/utils/__tests__/paths.test.js.map +0 -1
- package/dist/utils/__tests__/platform-command.test.d.ts +0 -2
- package/dist/utils/__tests__/platform-command.test.d.ts.map +0 -1
- package/dist/utils/__tests__/platform-command.test.js +0 -410
- package/dist/utils/__tests__/platform-command.test.js.map +0 -1
- package/dist/utils/__tests__/repo-deps.test.d.ts +0 -2
- package/dist/utils/__tests__/repo-deps.test.d.ts.map +0 -1
- package/dist/utils/__tests__/repo-deps.test.js +0 -71
- package/dist/utils/__tests__/repo-deps.test.js.map +0 -1
- package/dist/verification/__tests__/ci-rust-gates.test.d.ts +0 -2
- package/dist/verification/__tests__/ci-rust-gates.test.d.ts.map +0 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +0 -89
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +0 -1
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts +0 -2
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts.map +0 -1
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +0 -54
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +0 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.d.ts +0 -2
- package/dist/verification/__tests__/explore-harness-release-workflow.test.d.ts.map +0 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js +0 -73
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +0 -1
- package/dist/verification/__tests__/native-release-manifest.test.d.ts +0 -2
- package/dist/verification/__tests__/native-release-manifest.test.d.ts.map +0 -1
- package/dist/verification/__tests__/native-release-manifest.test.js +0 -80
- package/dist/verification/__tests__/native-release-manifest.test.js.map +0 -1
- package/dist/verification/__tests__/pr-check-workflow.test.d.ts +0 -2
- package/dist/verification/__tests__/pr-check-workflow.test.d.ts.map +0 -1
- package/dist/verification/__tests__/pr-check-workflow.test.js +0 -27
- package/dist/verification/__tests__/pr-check-workflow.test.js.map +0 -1
- package/dist/verification/__tests__/ralph-persistence-gate.test.d.ts +0 -2
- package/dist/verification/__tests__/ralph-persistence-gate.test.d.ts.map +0 -1
- package/dist/verification/__tests__/ralph-persistence-gate.test.js +0 -55
- package/dist/verification/__tests__/ralph-persistence-gate.test.js.map +0 -1
- package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.d.ts +0 -2
- package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.d.ts.map +0 -1
- package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.js +0 -32
- package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.js.map +0 -1
- package/dist/verification/__tests__/verifier.test.d.ts +0 -2
- package/dist/verification/__tests__/verifier.test.d.ts.map +0 -1
- package/dist/verification/__tests__/verifier.test.js +0 -113
- package/dist/verification/__tests__/verifier.test.js.map +0 -1
- package/dist/visual/__tests__/verdict.test.d.ts +0 -2
- package/dist/visual/__tests__/verdict.test.d.ts.map +0 -1
- package/dist/visual/__tests__/verdict.test.js +0 -81
- package/dist/visual/__tests__/verdict.test.js.map +0 -1
- package/dist/wiki/__tests__/cjk-tokenize.test.d.ts +0 -12
- package/dist/wiki/__tests__/cjk-tokenize.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/cjk-tokenize.test.js +0 -139
- package/dist/wiki/__tests__/cjk-tokenize.test.js.map +0 -1
- package/dist/wiki/__tests__/crlf-parse.test.d.ts +0 -2
- package/dist/wiki/__tests__/crlf-parse.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/crlf-parse.test.js +0 -24
- package/dist/wiki/__tests__/crlf-parse.test.js.map +0 -1
- package/dist/wiki/__tests__/escape-newline.test.d.ts +0 -2
- package/dist/wiki/__tests__/escape-newline.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/escape-newline.test.js +0 -45
- package/dist/wiki/__tests__/escape-newline.test.js.map +0 -1
- package/dist/wiki/__tests__/ingest.test.d.ts +0 -5
- package/dist/wiki/__tests__/ingest.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/ingest.test.js +0 -181
- package/dist/wiki/__tests__/ingest.test.js.map +0 -1
- package/dist/wiki/__tests__/lint.test.d.ts +0 -5
- package/dist/wiki/__tests__/lint.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/lint.test.js +0 -163
- package/dist/wiki/__tests__/lint.test.js.map +0 -1
- package/dist/wiki/__tests__/query.test.d.ts +0 -5
- package/dist/wiki/__tests__/query.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/query.test.js +0 -141
- package/dist/wiki/__tests__/query.test.js.map +0 -1
- package/dist/wiki/__tests__/reserved-file-guard.test.d.ts +0 -2
- package/dist/wiki/__tests__/reserved-file-guard.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/reserved-file-guard.test.js +0 -44
- package/dist/wiki/__tests__/reserved-file-guard.test.js.map +0 -1
- package/dist/wiki/__tests__/session-hooks.test.d.ts +0 -5
- package/dist/wiki/__tests__/session-hooks.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/session-hooks.test.js +0 -36
- package/dist/wiki/__tests__/session-hooks.test.js.map +0 -1
- package/dist/wiki/__tests__/slug-nonascii.test.d.ts +0 -2
- package/dist/wiki/__tests__/slug-nonascii.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/slug-nonascii.test.js +0 -30
- package/dist/wiki/__tests__/slug-nonascii.test.js.map +0 -1
- package/dist/wiki/__tests__/storage.test.d.ts +0 -5
- package/dist/wiki/__tests__/storage.test.d.ts.map +0 -1
- package/dist/wiki/__tests__/storage.test.js +0 -278
- package/dist/wiki/__tests__/storage.test.js.map +0 -1
- package/dist/wiki/__tests__/test-helpers.d.ts +0 -31
- package/dist/wiki/__tests__/test-helpers.d.ts.map +0 -1
- package/dist/wiki/__tests__/test-helpers.js +0 -108
- package/dist/wiki/__tests__/test-helpers.js.map +0 -1
- package/docs/contracts/ralph-cancel-contract.md +0 -23
- package/docs/contracts/ralph-state-contract.md +0 -95
- package/docs/issues/team-ralph-followup-team.md +0 -38
- package/docs/qa/ralph-persistence-gate.md +0 -59
- package/docs/reference/ralph-parity-matrix.md +0 -25
- package/docs/reference/ralph-upstream-baseline.md +0 -34
- package/plugins/roblox-ai-os-creator-skills/skills/ralph/SKILL.md +0 -269
- package/plugins/roblox-ai-os-creator-skills/skills/ralplan/SKILL.md +0 -162
- package/prompts/api-reviewer.md +0 -113
- package/prompts/information-architect.md +0 -226
- package/prompts/performance-reviewer.md +0 -109
- package/prompts/product-analyst.md +0 -304
- package/prompts/product-manager.md +0 -245
- package/prompts/qa-tester.md +0 -124
- package/prompts/quality-reviewer.md +0 -123
- package/prompts/quality-strategist.md +0 -274
- package/prompts/style-reviewer.md +0 -102
- package/prompts/ux-researcher.md +0 -327
- package/skills/frontend-ui-ux/SKILL.md +0 -34
- package/skills/ralph/SKILL.md +0 -269
- package/skills/ralplan/SKILL.md +0 -162
- package/src/scripts/eval/eval-adaptive-sort-optimization.py +0 -24
- package/src/scripts/eval/eval-candidate-handoff.ts +0 -8
- package/src/scripts/eval/eval-cli-discoverability.ts +0 -40
- package/src/scripts/eval/eval-fresh-run-tagging.ts +0 -8
- package/src/scripts/eval/eval-help-consistency.ts +0 -11
- package/src/scripts/eval/eval-in-action-cat-shellout-demo.ts +0 -31
- package/src/scripts/eval/eval-ml-kaggle-model-optimization.py +0 -29
- package/src/scripts/eval/eval-noisy-bayesopt-highdim.py +0 -44
- package/src/scripts/eval/eval-noisy-latent-subspace-discovery.py +0 -44
- package/src/scripts/eval/eval-parity-smoke.ts +0 -20
- package/src/scripts/eval/eval-parity-sweep.ts +0 -26
- package/src/scripts/eval/eval-resume-dirty-guard.ts +0 -8
- package/src/scripts/eval/eval-security-path-traversal.ts +0 -38
- package/src/scripts/run-autoresearch-showcase.sh +0 -75
- /package/docs/{migration-mainline-post-v0.4.4.md → archive/migration-mainline-post-v0.4.4.md} +0 -0
- /package/docs/{qa-plan-0.4.2.md → archive/qa-plan-0.4.2.md} +0 -0
- /package/docs/{qa-report-0.4.2.md → archive/qa-report-0.4.2.md} +0 -0
|
@@ -1,2259 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, it, mock } from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { existsSync, mkdirSync, utimesSync } from "node:fs";
|
|
4
|
-
import { chmod, mkdir, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
5
|
-
import { dirname, join } from "node:path";
|
|
6
|
-
import { tmpdir } from "node:os";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { once } from "node:events";
|
|
9
|
-
import { HELP, normalizeCodexLaunchArgs, buildTmuxShellCommand, buildTmuxPaneCommand, buildWindowsPromptCommand, buildTmuxSessionName, resolveCliInvocation, commandOwnsLocalHelp, resolveCodexLaunchPolicy, resolveEffectiveLeaderLaunchPolicyOverride, resolveEnvLaunchPolicyOverride, resolveLeaderLaunchPolicyOverride, classifyCodexExecFailure, resolveSignalExitCode, parseTmuxPaneSnapshot, findHudWatchPaneIds, buildHudPaneCleanupTargets, readTopLevelTomlString, upsertTopLevelTomlString, collectInheritableTeamWorkerArgs, resolveTeamWorkerLaunchArgsEnv, injectModelInstructionsBypassArgs, resolveWorkerSparkModel, resolveSetupInstallModeArg, resolveSetupScopeArg, readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, prepareCodexHomeForLaunch, runtimeCodexHomePath, buildDetachedSessionBootstrapSteps, buildDetachedTmuxSessionName, buildDetachedSessionFinalizeSteps, buildDetachedSessionRollbackSteps, detectDetachedSessionWindowIndex, resolveNotifyTempContract, buildNotifyTempStartupMessages, buildNotifyFallbackWatcherEnv, shouldEnableNotifyFallbackWatcher, reapStaleNotifyFallbackWatcher, cleanupLaunchOrphanedMcpProcesses, reapPostLaunchOrphanedMcpProcesses, cleanupPostLaunchModeStateFiles, resolveBackgroundHelperLaunchMode, shouldDetachBackgroundHelper, resolveNotifyFallbackWatcherScript, resolveHookDerivedWatcherScript, resolveNotifyHookScript, buildDetachedWindowsBootstrapScript, acquireTmuxExtendedKeysLease, resolveNativeSessionName, releaseTmuxExtendedKeysLease, withTmuxExtendedKeys, } from "../index.js";
|
|
10
|
-
import { ensureReusableNodeModules } from "../../utils/repo-deps.js";
|
|
11
|
-
import { readAllState } from "../../hud/state.js";
|
|
12
|
-
import { generateOverlay } from "../../hooks/agents-overlay.js";
|
|
13
|
-
import { HUD_TMUX_HEIGHT_LINES } from "../../hud/constants.js";
|
|
14
|
-
import { createHudWatchPane as createSharedHudWatchPane, listCurrentWindowHudPaneIds } from "../../hud/tmux.js";
|
|
15
|
-
import { DEFAULT_FRONTIER_MODEL, getTeamLowComplexityModel, } from "../../config/models.js";
|
|
16
|
-
const testDir = dirname(fileURLToPath(import.meta.url));
|
|
17
|
-
const repoRoot = join(testDir, "..", "..", "..");
|
|
18
|
-
function normalizeDarwinTmpPath(value) {
|
|
19
|
-
return process.platform === "darwin" ? value.replaceAll("/private/var/", "/var/") : value;
|
|
20
|
-
}
|
|
21
|
-
function escapeRegExp(value) {
|
|
22
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
23
|
-
}
|
|
24
|
-
function expectedLowComplexityModel(codexHomeOverride) {
|
|
25
|
-
return getTeamLowComplexityModel(codexHomeOverride);
|
|
26
|
-
}
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
mock.restoreAll();
|
|
29
|
-
});
|
|
30
|
-
describe("normalizeCodexLaunchArgs", () => {
|
|
31
|
-
it("maps --madmax to codex bypass flag", () => {
|
|
32
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--madmax"]), [
|
|
33
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
34
|
-
]);
|
|
35
|
-
});
|
|
36
|
-
it("does not forward --madmax and preserves other args", () => {
|
|
37
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--model", "gpt-5", "--madmax", "--yolo"]), [
|
|
38
|
-
"--model",
|
|
39
|
-
"gpt-5",
|
|
40
|
-
"--yolo",
|
|
41
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
42
|
-
]);
|
|
43
|
-
});
|
|
44
|
-
it("avoids duplicate bypass flags when both are present", () => {
|
|
45
|
-
assert.deepEqual(normalizeCodexLaunchArgs([
|
|
46
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
47
|
-
"--madmax",
|
|
48
|
-
]), ["--dangerously-bypass-approvals-and-sandbox"]);
|
|
49
|
-
});
|
|
50
|
-
it("deduplicates repeated bypass-related flags", () => {
|
|
51
|
-
assert.deepEqual(normalizeCodexLaunchArgs([
|
|
52
|
-
"--madmax",
|
|
53
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
54
|
-
"--madmax",
|
|
55
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
56
|
-
]), ["--dangerously-bypass-approvals-and-sandbox"]);
|
|
57
|
-
});
|
|
58
|
-
it("leaves unrelated args unchanged", () => {
|
|
59
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--model", "gpt-5", "--yolo"]), [
|
|
60
|
-
"--model",
|
|
61
|
-
"gpt-5",
|
|
62
|
-
"--yolo",
|
|
63
|
-
]);
|
|
64
|
-
});
|
|
65
|
-
it("maps --high to reasoning override", () => {
|
|
66
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--high"]), [
|
|
67
|
-
"-c",
|
|
68
|
-
'model_reasoning_effort="high"',
|
|
69
|
-
]);
|
|
70
|
-
});
|
|
71
|
-
it("maps --xhigh to reasoning override", () => {
|
|
72
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--xhigh"]), [
|
|
73
|
-
"-c",
|
|
74
|
-
'model_reasoning_effort="xhigh"',
|
|
75
|
-
]);
|
|
76
|
-
});
|
|
77
|
-
it("uses the last reasoning shorthand when both are present", () => {
|
|
78
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--high", "--xhigh"]), [
|
|
79
|
-
"-c",
|
|
80
|
-
'model_reasoning_effort="xhigh"',
|
|
81
|
-
]);
|
|
82
|
-
});
|
|
83
|
-
it("maps --xhigh --madmax to codex-native flags only", () => {
|
|
84
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--xhigh", "--madmax"]), [
|
|
85
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
86
|
-
"-c",
|
|
87
|
-
'model_reasoning_effort="xhigh"',
|
|
88
|
-
]);
|
|
89
|
-
});
|
|
90
|
-
it("--spark is stripped from leader args (model goes to workers only)", () => {
|
|
91
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--spark", "--yolo"]), [
|
|
92
|
-
"--yolo",
|
|
93
|
-
]);
|
|
94
|
-
});
|
|
95
|
-
it("--spark alone produces no leader args", () => {
|
|
96
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--spark"]), []);
|
|
97
|
-
});
|
|
98
|
-
it("--madmax-spark adds bypass flag to leader args and is otherwise consumed", () => {
|
|
99
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--madmax-spark"]), [
|
|
100
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
101
|
-
]);
|
|
102
|
-
});
|
|
103
|
-
it("--madmax-spark deduplicates bypass when --madmax also present", () => {
|
|
104
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--madmax", "--madmax-spark"]), [
|
|
105
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
106
|
-
]);
|
|
107
|
-
});
|
|
108
|
-
it("--madmax-spark does not inject spark model into leader args", () => {
|
|
109
|
-
const args = normalizeCodexLaunchArgs(["--madmax-spark"]);
|
|
110
|
-
assert.ok(!args.includes("--model"), "leader args must not contain --model from --madmax-spark");
|
|
111
|
-
assert.ok(!args.some((a) => a.includes("spark")), "leader args must not reference spark model");
|
|
112
|
-
});
|
|
113
|
-
it("strips detached worktree flag from leader codex args", () => {
|
|
114
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--worktree", "--yolo"]), [
|
|
115
|
-
"--yolo",
|
|
116
|
-
]);
|
|
117
|
-
});
|
|
118
|
-
it("strips named worktree flag from leader codex args", () => {
|
|
119
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--worktree=feature/demo", "--model", "gpt-5"]), ["--model", "gpt-5"]);
|
|
120
|
-
});
|
|
121
|
-
it("does not forward notify-temp flags/selectors to leader codex args", () => {
|
|
122
|
-
const parsed = resolveNotifyTempContract([
|
|
123
|
-
"--notify-temp",
|
|
124
|
-
"--discord",
|
|
125
|
-
"--custom",
|
|
126
|
-
"openclaw:ops",
|
|
127
|
-
"--custom=my-hook",
|
|
128
|
-
"--model",
|
|
129
|
-
"gpt-5",
|
|
130
|
-
], {});
|
|
131
|
-
assert.deepEqual(normalizeCodexLaunchArgs(parsed.passthroughArgs), [
|
|
132
|
-
"--model",
|
|
133
|
-
"gpt-5",
|
|
134
|
-
]);
|
|
135
|
-
});
|
|
136
|
-
it("strips --tmux from leader codex args", () => {
|
|
137
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--tmux", "--yolo"]), [
|
|
138
|
-
"--yolo",
|
|
139
|
-
]);
|
|
140
|
-
});
|
|
141
|
-
it("strips --direct from leader codex args", () => {
|
|
142
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--direct", "--yolo"]), [
|
|
143
|
-
"--yolo",
|
|
144
|
-
]);
|
|
145
|
-
});
|
|
146
|
-
it("preserves literal --tmux after -- in leader codex args", () => {
|
|
147
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--", "--tmux", "--yolo"]), [
|
|
148
|
-
"--",
|
|
149
|
-
"--tmux",
|
|
150
|
-
"--yolo",
|
|
151
|
-
]);
|
|
152
|
-
});
|
|
153
|
-
it("preserves literal --direct after -- in leader codex args", () => {
|
|
154
|
-
assert.deepEqual(normalizeCodexLaunchArgs(["--", "--direct", "--yolo"]), [
|
|
155
|
-
"--",
|
|
156
|
-
"--direct",
|
|
157
|
-
"--yolo",
|
|
158
|
-
]);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
describe("resolveLeaderLaunchPolicyOverride", () => {
|
|
162
|
-
it("detects explicit detached tmux launch requests", () => {
|
|
163
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--tmux", "--model", "gpt-5"]), "detached-tmux");
|
|
164
|
-
});
|
|
165
|
-
it("detects explicit direct launch requests", () => {
|
|
166
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--direct", "--model", "gpt-5"]), "direct");
|
|
167
|
-
});
|
|
168
|
-
it("uses the last CLI launch policy flag before --", () => {
|
|
169
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--direct", "--tmux"]), "detached-tmux");
|
|
170
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--tmux", "--direct"]), "direct");
|
|
171
|
-
});
|
|
172
|
-
it("returns undefined when no explicit policy override is present", () => {
|
|
173
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--model", "gpt-5"]), undefined);
|
|
174
|
-
});
|
|
175
|
-
it("stops scanning for --tmux after the end-of-options marker", () => {
|
|
176
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--", "--tmux", "--model", "gpt-5"]), undefined);
|
|
177
|
-
});
|
|
178
|
-
it("stops scanning for --direct after the end-of-options marker", () => {
|
|
179
|
-
assert.equal(resolveLeaderLaunchPolicyOverride(["--", "--direct", "--model", "gpt-5"]), undefined);
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
describe("resolveEnvLaunchPolicyOverride", () => {
|
|
183
|
-
it("accepts direct, tmux, detached-tmux, auto, and empty policy values", () => {
|
|
184
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "direct" }), "direct");
|
|
185
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "tmux" }), "detached-tmux");
|
|
186
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "detached-tmux" }), "detached-tmux");
|
|
187
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "auto" }), undefined);
|
|
188
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "" }), undefined);
|
|
189
|
-
});
|
|
190
|
-
it("warns once for invalid RCS_LAUNCH_POLICY and falls back to auto", () => {
|
|
191
|
-
const warn = mock.method(console, "warn", () => { });
|
|
192
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "banana" }), undefined);
|
|
193
|
-
assert.equal(resolveEnvLaunchPolicyOverride({ RCS_LAUNCH_POLICY: "banana" }), undefined);
|
|
194
|
-
assert.equal(warn.mock.callCount(), 1);
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
describe("resolveEffectiveLeaderLaunchPolicyOverride", () => {
|
|
198
|
-
it("uses env policy when no CLI policy flag is present", () => {
|
|
199
|
-
assert.equal(resolveEffectiveLeaderLaunchPolicyOverride(["--yolo"], {
|
|
200
|
-
RCS_LAUNCH_POLICY: "direct",
|
|
201
|
-
}), "direct");
|
|
202
|
-
});
|
|
203
|
-
it("lets CLI policy flags override RCS_LAUNCH_POLICY", () => {
|
|
204
|
-
assert.equal(resolveEffectiveLeaderLaunchPolicyOverride(["--tmux", "--yolo"], {
|
|
205
|
-
RCS_LAUNCH_POLICY: "direct",
|
|
206
|
-
}), "detached-tmux");
|
|
207
|
-
assert.equal(resolveEffectiveLeaderLaunchPolicyOverride(["--direct", "--yolo"], {
|
|
208
|
-
RCS_LAUNCH_POLICY: "tmux",
|
|
209
|
-
}), "direct");
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
describe("resolveNotifyTempContract", () => {
|
|
213
|
-
it("activates from --notify-temp with no providers", () => {
|
|
214
|
-
const parsed = resolveNotifyTempContract(["--notify-temp", "--model", "gpt-5"], {});
|
|
215
|
-
assert.equal(parsed.contract.active, true);
|
|
216
|
-
assert.equal(parsed.contract.source, "cli");
|
|
217
|
-
assert.deepEqual(parsed.contract.canonicalSelectors, []);
|
|
218
|
-
assert.deepEqual(parsed.passthroughArgs, ["--model", "gpt-5"]);
|
|
219
|
-
});
|
|
220
|
-
it("auto-activates when provider selectors are present", () => {
|
|
221
|
-
const parsed = resolveNotifyTempContract(["--discord", "--slack"], {});
|
|
222
|
-
assert.equal(parsed.contract.active, true);
|
|
223
|
-
assert.equal(parsed.contract.source, "providers");
|
|
224
|
-
assert.deepEqual(parsed.contract.canonicalSelectors, ["discord", "slack"]);
|
|
225
|
-
assert.equal(parsed.contract.warnings.some((line) => line.includes("imply temp mode")), true);
|
|
226
|
-
});
|
|
227
|
-
it("supports repeated --custom forms and canonicalizes selectors", () => {
|
|
228
|
-
const parsed = resolveNotifyTempContract(["--custom", "OpenClaw:Ops", "--custom=my-hook", "--custom=", "--custom"], {});
|
|
229
|
-
assert.deepEqual(parsed.contract.canonicalSelectors, [
|
|
230
|
-
"openclaw:ops",
|
|
231
|
-
"custom:my-hook",
|
|
232
|
-
]);
|
|
233
|
-
assert.equal(parsed.contract.warnings.length >= 1, true);
|
|
234
|
-
});
|
|
235
|
-
it("activates from RCS_NOTIFY_TEMP=1 env parity", () => {
|
|
236
|
-
const parsed = resolveNotifyTempContract(["--model", "gpt-5"], {
|
|
237
|
-
RCS_NOTIFY_TEMP: "1",
|
|
238
|
-
});
|
|
239
|
-
assert.equal(parsed.contract.active, true);
|
|
240
|
-
assert.equal(parsed.contract.source, "env");
|
|
241
|
-
assert.deepEqual(parsed.passthroughArgs, ["--model", "gpt-5"]);
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
describe("cleanupLaunchOrphanedMcpProcesses", () => {
|
|
245
|
-
it("reaps only detached RCS MCP processes without a live Codex ancestor", async () => {
|
|
246
|
-
const processes = [
|
|
247
|
-
{ pid: 700, ppid: 500, command: "codex" },
|
|
248
|
-
{ pid: 701, ppid: 700, command: "node /repo/bin/rcs.js" },
|
|
249
|
-
{
|
|
250
|
-
pid: 710,
|
|
251
|
-
ppid: 700,
|
|
252
|
-
command: "node /repo/roblox-ai-os-creator-skills/dist/mcp/state-server.js",
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
pid: 800,
|
|
256
|
-
ppid: 1,
|
|
257
|
-
command: "node /tmp/roblox-ai-os-creator-skills/dist/mcp/memory-server.js",
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
pid: 810,
|
|
261
|
-
ppid: 42,
|
|
262
|
-
command: "node /tmp/roblox-ai-os-creator-skills/dist/mcp/trace-server.js",
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
pid: 820,
|
|
266
|
-
ppid: 50,
|
|
267
|
-
command: "codex --model gpt-5",
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
pid: 821,
|
|
271
|
-
ppid: 820,
|
|
272
|
-
command: "node /tmp/other-session/dist/mcp/state-server.js",
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
pid: 830,
|
|
276
|
-
ppid: 50,
|
|
277
|
-
command: "node /repo/bin/rcs.js autoresearch --topic launch",
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
pid: 831,
|
|
281
|
-
ppid: 830,
|
|
282
|
-
command: "node /tmp/parallel-session/dist/mcp/memory-server.js",
|
|
283
|
-
},
|
|
284
|
-
];
|
|
285
|
-
const signals = [];
|
|
286
|
-
const alive = new Set([800, 810]);
|
|
287
|
-
const result = await cleanupLaunchOrphanedMcpProcesses({
|
|
288
|
-
currentPid: 701,
|
|
289
|
-
listProcesses: () => processes,
|
|
290
|
-
isPidAlive: (pid) => alive.has(pid),
|
|
291
|
-
sendSignal: (pid, signal) => {
|
|
292
|
-
signals.push({ pid, signal });
|
|
293
|
-
alive.delete(pid);
|
|
294
|
-
},
|
|
295
|
-
sleep: async () => { },
|
|
296
|
-
now: () => 0,
|
|
297
|
-
});
|
|
298
|
-
assert.equal(result.terminatedCount, 2);
|
|
299
|
-
assert.equal(result.forceKilledCount, 0);
|
|
300
|
-
assert.deepEqual(result.failedPids, []);
|
|
301
|
-
assert.deepEqual(signals, [
|
|
302
|
-
{ pid: 800, signal: "SIGTERM" },
|
|
303
|
-
{ pid: 810, signal: "SIGTERM" },
|
|
304
|
-
]);
|
|
305
|
-
assert.equal(signals.some(({ pid }) => pid === 821), false, "launch-safe cleanup must preserve RCS MCP processes still attached to another live Codex tree");
|
|
306
|
-
assert.equal(signals.some(({ pid }) => pid === 831), false, "launch-safe cleanup must preserve RCS MCP processes still attached to another live RCS launch tree");
|
|
307
|
-
});
|
|
308
|
-
});
|
|
309
|
-
describe("reapPostLaunchOrphanedMcpProcesses", () => {
|
|
310
|
-
it("logs postLaunch reaped MCP orphans and keeps cleanup non-fatal", async () => {
|
|
311
|
-
const info = [];
|
|
312
|
-
const warnings = [];
|
|
313
|
-
const errors = [];
|
|
314
|
-
await reapPostLaunchOrphanedMcpProcesses({
|
|
315
|
-
cleanup: async () => ({
|
|
316
|
-
dryRun: false,
|
|
317
|
-
candidates: [],
|
|
318
|
-
terminatedCount: 2,
|
|
319
|
-
forceKilledCount: 0,
|
|
320
|
-
failedPids: [810],
|
|
321
|
-
}),
|
|
322
|
-
writeInfo: (line) => info.push(line),
|
|
323
|
-
writeWarn: (line) => warnings.push(line),
|
|
324
|
-
writeError: (line) => errors.push(line),
|
|
325
|
-
});
|
|
326
|
-
assert.deepEqual(errors, []);
|
|
327
|
-
assert.match(info.join("\n"), /postLaunch: reaped 2 orphaned RCS MCP process/);
|
|
328
|
-
assert.match(warnings.join("\n"), /postLaunch: failed to reap 1 orphaned RCS MCP process/);
|
|
329
|
-
});
|
|
330
|
-
it("writes a non-fatal postLaunch cleanup error when the cleanup step throws", async () => {
|
|
331
|
-
const errors = [];
|
|
332
|
-
await reapPostLaunchOrphanedMcpProcesses({
|
|
333
|
-
cleanup: async () => {
|
|
334
|
-
throw new Error("boom");
|
|
335
|
-
},
|
|
336
|
-
writeError: (line) => errors.push(line),
|
|
337
|
-
});
|
|
338
|
-
assert.match(errors.join("\n"), /postLaunch MCP cleanup failed: Error: boom/);
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
describe("cleanupPostLaunchModeStateFiles", () => {
|
|
342
|
-
it("repairs empty or truncated mode state files and still cancels valid siblings", async () => {
|
|
343
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-postlaunch-mode-cleanup-"));
|
|
344
|
-
const sessionId = "sess-postlaunch-cleanup";
|
|
345
|
-
const stateDir = join(wd, ".rcs", "state");
|
|
346
|
-
const sessionStateDir = join(stateDir, "sessions", sessionId);
|
|
347
|
-
const partialState = '{\n "active": true,\n "mode": "ralph",\n';
|
|
348
|
-
const warnings = [];
|
|
349
|
-
await mkdir(sessionStateDir, { recursive: true });
|
|
350
|
-
await writeFile(join(stateDir, "autopilot-state.json"), JSON.stringify({ active: true, mode: "autopilot" }, null, 2), "utf-8");
|
|
351
|
-
await writeFile(join(stateDir, "deep-interview-state.json"), "", "utf-8");
|
|
352
|
-
await writeFile(join(sessionStateDir, "ralph-state.json"), partialState, "utf-8");
|
|
353
|
-
await cleanupPostLaunchModeStateFiles(wd, sessionId, {
|
|
354
|
-
writeWarn: (line) => warnings.push(line),
|
|
355
|
-
});
|
|
356
|
-
const autopilot = JSON.parse(await readFile(join(stateDir, "autopilot-state.json"), "utf-8"));
|
|
357
|
-
const deepInterview = JSON.parse(await readFile(join(stateDir, "deep-interview-state.json"), "utf-8"));
|
|
358
|
-
const ralph = JSON.parse(await readFile(join(sessionStateDir, "ralph-state.json"), "utf-8"));
|
|
359
|
-
assert.equal(autopilot.active, false);
|
|
360
|
-
assert.equal(typeof autopilot.completed_at, "string");
|
|
361
|
-
assert.equal(deepInterview.active, false);
|
|
362
|
-
assert.equal(deepInterview.mode, "deep-interview");
|
|
363
|
-
assert.equal(deepInterview.current_phase, "cancelled");
|
|
364
|
-
assert.equal(typeof deepInterview.completed_at, "string");
|
|
365
|
-
assert.equal(typeof deepInterview.last_turn_at, "string");
|
|
366
|
-
assert.equal(ralph.active, false);
|
|
367
|
-
assert.equal(ralph.mode, "ralph");
|
|
368
|
-
assert.equal(ralph.current_phase, "cancelled");
|
|
369
|
-
assert.equal(typeof ralph.completed_at, "string");
|
|
370
|
-
assert.equal(typeof ralph.last_turn_at, "string");
|
|
371
|
-
const rootCanonicalPath = join(stateDir, "skill-active-state.json");
|
|
372
|
-
const sessionCanonicalPath = join(sessionStateDir, "skill-active-state.json");
|
|
373
|
-
if (existsSync(rootCanonicalPath)) {
|
|
374
|
-
const rootCanonical = JSON.parse(await readFile(rootCanonicalPath, "utf-8"));
|
|
375
|
-
assert.equal(rootCanonical.active, false);
|
|
376
|
-
assert.deepEqual(rootCanonical.active_skills, []);
|
|
377
|
-
}
|
|
378
|
-
if (existsSync(sessionCanonicalPath)) {
|
|
379
|
-
const sessionCanonical = JSON.parse(await readFile(sessionCanonicalPath, "utf-8"));
|
|
380
|
-
assert.equal(sessionCanonical.active, false);
|
|
381
|
-
assert.deepEqual(sessionCanonical.active_skills, []);
|
|
382
|
-
}
|
|
383
|
-
assert.deepEqual(warnings, []);
|
|
384
|
-
});
|
|
385
|
-
it("retries a transient parse failure before cancelling the rewritten mode state", async () => {
|
|
386
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-postlaunch-mode-retry-"));
|
|
387
|
-
const sessionId = "sess-postlaunch-retry";
|
|
388
|
-
const stateDir = join(wd, ".rcs", "state");
|
|
389
|
-
const statePath = join(stateDir, "ralph-state.json");
|
|
390
|
-
const writes = [];
|
|
391
|
-
const validState = JSON.stringify({ active: true, mode: "ralph" }, null, 2);
|
|
392
|
-
let reads = 0;
|
|
393
|
-
await mkdir(stateDir, { recursive: true });
|
|
394
|
-
const mockReaddir = (async (dir, _options) => (String(dir) === stateDir ? ["ralph-state.json"] : []));
|
|
395
|
-
const mockReadFile = (async (path, _options) => {
|
|
396
|
-
assert.equal(String(path), statePath);
|
|
397
|
-
reads += 1;
|
|
398
|
-
return reads === 1
|
|
399
|
-
? '{\n "active": true,\n "mode": "ralph"'
|
|
400
|
-
: validState;
|
|
401
|
-
});
|
|
402
|
-
const mockWriteFile = (async (path, content, _options) => {
|
|
403
|
-
writes.push({ path: String(path), content: String(content) });
|
|
404
|
-
});
|
|
405
|
-
const dependencies = {
|
|
406
|
-
readdir: mockReaddir,
|
|
407
|
-
readFile: mockReadFile,
|
|
408
|
-
writeFile: mockWriteFile,
|
|
409
|
-
sleep: async () => { },
|
|
410
|
-
now: () => new Date("2026-04-07T00:00:00.000Z"),
|
|
411
|
-
};
|
|
412
|
-
await cleanupPostLaunchModeStateFiles(wd, sessionId, dependencies);
|
|
413
|
-
assert.equal(reads, 2);
|
|
414
|
-
assert.equal(writes.length, 1);
|
|
415
|
-
assert.equal(writes[0]?.path, statePath);
|
|
416
|
-
const persisted = JSON.parse(writes[0]?.content ?? "{}");
|
|
417
|
-
assert.equal(persisted.active, false);
|
|
418
|
-
assert.equal(persisted.completed_at, "2026-04-07T00:00:00.000Z");
|
|
419
|
-
});
|
|
420
|
-
it("warns on structurally complete malformed JSON without aborting sibling cleanup", async () => {
|
|
421
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-postlaunch-mode-malformed-"));
|
|
422
|
-
const sessionId = "sess-postlaunch-malformed";
|
|
423
|
-
const stateDir = join(wd, ".rcs", "state");
|
|
424
|
-
const warnings = [];
|
|
425
|
-
const malformedState = '{\n "active": true,\n}\n';
|
|
426
|
-
await mkdir(stateDir, { recursive: true });
|
|
427
|
-
await writeFile(join(stateDir, "ralph-state.json"), malformedState, "utf-8");
|
|
428
|
-
await writeFile(join(stateDir, "ultrawork-state.json"), JSON.stringify({ active: true, mode: "ultrawork" }, null, 2), "utf-8");
|
|
429
|
-
await cleanupPostLaunchModeStateFiles(wd, sessionId, {
|
|
430
|
-
writeWarn: (line) => warnings.push(line),
|
|
431
|
-
});
|
|
432
|
-
const ultrawork = JSON.parse(await readFile(join(stateDir, "ultrawork-state.json"), "utf-8"));
|
|
433
|
-
assert.equal(ultrawork.active, false);
|
|
434
|
-
assert.equal(typeof ultrawork.completed_at, "string");
|
|
435
|
-
const canonicalPath = join(stateDir, "skill-active-state.json");
|
|
436
|
-
if (existsSync(canonicalPath)) {
|
|
437
|
-
const canonical = JSON.parse(await readFile(canonicalPath, "utf-8"));
|
|
438
|
-
assert.equal(canonical.active, false);
|
|
439
|
-
assert.deepEqual(canonical.active_skills, []);
|
|
440
|
-
}
|
|
441
|
-
assert.equal(await readFile(join(stateDir, "ralph-state.json"), "utf-8"), malformedState);
|
|
442
|
-
assert.equal(warnings.length, 1);
|
|
443
|
-
assert.match(warnings[0] ?? "", /skipped malformed mode state .*ralph-state\.json/);
|
|
444
|
-
});
|
|
445
|
-
it("clears canonical skill-active entries during cleanup and hides them from HUD/overlay readers", async () => {
|
|
446
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-postlaunch-skill-active-cleanup-"));
|
|
447
|
-
const sessionId = "sess-skill-active-cleanup";
|
|
448
|
-
const stateDir = join(wd, ".rcs", "state");
|
|
449
|
-
const sessionStateDir = join(stateDir, "sessions", sessionId);
|
|
450
|
-
await mkdir(sessionStateDir, { recursive: true });
|
|
451
|
-
await writeFile(join(stateDir, "session.json"), JSON.stringify({ session_id: sessionId }), "utf-8");
|
|
452
|
-
await writeFile(join(sessionStateDir, "skill-active-state.json"), JSON.stringify({
|
|
453
|
-
version: 1,
|
|
454
|
-
active: true,
|
|
455
|
-
skill: "autoresearch",
|
|
456
|
-
phase: "running",
|
|
457
|
-
session_id: sessionId,
|
|
458
|
-
active_skills: [
|
|
459
|
-
{ skill: "autoresearch", phase: "running", active: true, session_id: sessionId },
|
|
460
|
-
],
|
|
461
|
-
}, null, 2), "utf-8");
|
|
462
|
-
await cleanupPostLaunchModeStateFiles(wd, sessionId);
|
|
463
|
-
const canonical = JSON.parse(await readFile(join(sessionStateDir, "skill-active-state.json"), "utf-8"));
|
|
464
|
-
assert.equal(canonical.active, false);
|
|
465
|
-
assert.equal(canonical.phase, "complete");
|
|
466
|
-
assert.deepEqual(canonical.active_skills, []);
|
|
467
|
-
const hudState = await readAllState(wd);
|
|
468
|
-
assert.equal(hudState.autoresearch, null);
|
|
469
|
-
const overlay = await generateOverlay(wd, sessionId);
|
|
470
|
-
assert.equal(overlay.includes("- autoresearch:"), false);
|
|
471
|
-
});
|
|
472
|
-
});
|
|
473
|
-
describe("watcher script path resolution", () => {
|
|
474
|
-
it("resolves packaged watcher entrypoints from dist/scripts", () => {
|
|
475
|
-
assert.equal(resolveNotifyFallbackWatcherScript("/pkg"), "/pkg/dist/scripts/notify-fallback-watcher.js");
|
|
476
|
-
assert.equal(resolveHookDerivedWatcherScript("/pkg"), "/pkg/dist/scripts/hook-derived-watcher.js");
|
|
477
|
-
assert.equal(resolveNotifyHookScript("/pkg"), "/pkg/dist/scripts/notify-hook.js");
|
|
478
|
-
});
|
|
479
|
-
});
|
|
480
|
-
describe("buildNotifyFallbackWatcherEnv", () => {
|
|
481
|
-
it("enables watcher authority and propagates CODEX_HOME override when requested", () => {
|
|
482
|
-
const env = buildNotifyFallbackWatcherEnv({ HOME: "/tmp/home", RCS_HUD_AUTHORITY: "0", TMUX: "sock,1,0", TMUX_PANE: "%2" }, { codexHomeOverride: "/tmp/codex-home", enableAuthority: true });
|
|
483
|
-
assert.equal(env.RCS_HUD_AUTHORITY, "1");
|
|
484
|
-
assert.equal(env.CODEX_HOME, "/tmp/codex-home");
|
|
485
|
-
assert.equal(env.HOME, "/tmp/home");
|
|
486
|
-
assert.equal(env.TMUX, undefined);
|
|
487
|
-
assert.equal(env.TMUX_PANE, undefined);
|
|
488
|
-
});
|
|
489
|
-
it("disables watcher authority explicitly when not requested", () => {
|
|
490
|
-
const env = buildNotifyFallbackWatcherEnv({ HOME: "/tmp/home", RCS_HUD_AUTHORITY: "1", TMUX: "sock,1,0", TMUX_PANE: "%3" }, { enableAuthority: false });
|
|
491
|
-
assert.equal(env.RCS_HUD_AUTHORITY, "0");
|
|
492
|
-
assert.equal(env.HOME, "/tmp/home");
|
|
493
|
-
assert.equal(env.TMUX, undefined);
|
|
494
|
-
assert.equal(env.TMUX_PANE, undefined);
|
|
495
|
-
});
|
|
496
|
-
});
|
|
497
|
-
describe("shouldEnableNotifyFallbackWatcher", () => {
|
|
498
|
-
it("keeps notify fallback enabled by default on non-Windows hosts", () => {
|
|
499
|
-
assert.equal(shouldEnableNotifyFallbackWatcher({}, "linux"), true);
|
|
500
|
-
});
|
|
501
|
-
it("disables notify fallback explicitly on non-Windows hosts", () => {
|
|
502
|
-
assert.equal(shouldEnableNotifyFallbackWatcher({ RCS_NOTIFY_FALLBACK: "0" }, "linux"), false);
|
|
503
|
-
});
|
|
504
|
-
it("disables notify fallback by default on win32", () => {
|
|
505
|
-
assert.equal(shouldEnableNotifyFallbackWatcher({}, "win32"), false);
|
|
506
|
-
});
|
|
507
|
-
it("allows explicit opt-in for notify fallback on win32", () => {
|
|
508
|
-
assert.equal(shouldEnableNotifyFallbackWatcher({ RCS_NOTIFY_FALLBACK: "1" }, "win32"), true);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
describe("reapStaleNotifyFallbackWatcher", () => {
|
|
512
|
-
it("stops an existing watcher even when a later startup gate would skip relaunch", async () => {
|
|
513
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-stale-notify-fallback-"));
|
|
514
|
-
try {
|
|
515
|
-
const pidPath = join(cwd, "notify-fallback.pid");
|
|
516
|
-
await writeFile(pidPath, JSON.stringify({ pid: 4321, started_at: "2026-04-05T00:00:00.000Z" }), "utf-8");
|
|
517
|
-
const killed = [];
|
|
518
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
519
|
-
isWatcherProcess: () => true,
|
|
520
|
-
tryKillPid(pid, signal) {
|
|
521
|
-
killed.push({ pid, signal });
|
|
522
|
-
return true;
|
|
523
|
-
},
|
|
524
|
-
});
|
|
525
|
-
assert.deepEqual(killed, [{ pid: 4321, signal: "SIGTERM" }]);
|
|
526
|
-
assert.equal(shouldEnableNotifyFallbackWatcher({}, "win32"), false);
|
|
527
|
-
}
|
|
528
|
-
finally {
|
|
529
|
-
await rm(cwd, { recursive: true, force: true });
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
it("ignores missing pid files", async () => {
|
|
533
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-missing-notify-fallback-"));
|
|
534
|
-
try {
|
|
535
|
-
const pidPath = join(cwd, "notify-fallback.pid");
|
|
536
|
-
let killCalls = 0;
|
|
537
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
538
|
-
tryKillPid() {
|
|
539
|
-
killCalls += 1;
|
|
540
|
-
return true;
|
|
541
|
-
},
|
|
542
|
-
});
|
|
543
|
-
assert.equal(killCalls, 0);
|
|
544
|
-
}
|
|
545
|
-
finally {
|
|
546
|
-
await rm(cwd, { recursive: true, force: true });
|
|
547
|
-
}
|
|
548
|
-
});
|
|
549
|
-
it("suppresses ESRCH cleanup errors but warns on unexpected failures", async () => {
|
|
550
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-esrch-notify-fallback-"));
|
|
551
|
-
try {
|
|
552
|
-
const pidPath = join(cwd, "notify-fallback.pid");
|
|
553
|
-
await writeFile(pidPath, JSON.stringify({ pid: 99 }), "utf-8");
|
|
554
|
-
const warnings = [];
|
|
555
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
556
|
-
readFile: async () => {
|
|
557
|
-
throw Object.assign(new Error("gone"), { code: "ESRCH" });
|
|
558
|
-
},
|
|
559
|
-
warn(message, meta) {
|
|
560
|
-
warnings.push({ message, meta });
|
|
561
|
-
},
|
|
562
|
-
});
|
|
563
|
-
assert.deepEqual(warnings, []);
|
|
564
|
-
const warned = [];
|
|
565
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
566
|
-
readFile: async (path, encoding) => readFile(path, encoding),
|
|
567
|
-
isWatcherProcess: () => true,
|
|
568
|
-
tryKillPid() {
|
|
569
|
-
throw new Error("permission denied");
|
|
570
|
-
},
|
|
571
|
-
warn(message, meta) {
|
|
572
|
-
warned.push({ message, meta });
|
|
573
|
-
},
|
|
574
|
-
});
|
|
575
|
-
assert.equal(warned.length, 1);
|
|
576
|
-
assert.equal(warned[0]?.message, "[rcs] warning: failed to stop stale notify fallback watcher");
|
|
577
|
-
}
|
|
578
|
-
finally {
|
|
579
|
-
await rm(cwd, { recursive: true, force: true });
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
});
|
|
583
|
-
describe("buildNotifyTempStartupMessages", () => {
|
|
584
|
-
it("always emits summary when temp mode is active", () => {
|
|
585
|
-
const result = buildNotifyTempStartupMessages({
|
|
586
|
-
active: true,
|
|
587
|
-
selectors: ["discord"],
|
|
588
|
-
canonicalSelectors: ["discord"],
|
|
589
|
-
warnings: [],
|
|
590
|
-
source: "cli",
|
|
591
|
-
}, true);
|
|
592
|
-
assert.deepEqual(result.infoLines, [
|
|
593
|
-
"notify temp: active | providers=discord | persistent-routing=bypassed",
|
|
594
|
-
]);
|
|
595
|
-
assert.deepEqual(result.warningLines, []);
|
|
596
|
-
});
|
|
597
|
-
it("emits no-valid-provider warning when no provider is configured", () => {
|
|
598
|
-
const result = buildNotifyTempStartupMessages({
|
|
599
|
-
active: true,
|
|
600
|
-
selectors: [],
|
|
601
|
-
canonicalSelectors: [],
|
|
602
|
-
warnings: [
|
|
603
|
-
"notify temp: provider selectors imply temp mode (auto-activated)",
|
|
604
|
-
],
|
|
605
|
-
source: "providers",
|
|
606
|
-
}, false);
|
|
607
|
-
assert.equal(result.warningLines.includes("notify temp: no valid providers resolved; notifications skipped"), true);
|
|
608
|
-
});
|
|
609
|
-
});
|
|
610
|
-
describe("resolveWorkerSparkModel", () => {
|
|
611
|
-
it("returns spark model string when --spark is present", () => {
|
|
612
|
-
assert.equal(resolveWorkerSparkModel(["--spark", "--yolo"]), expectedLowComplexityModel());
|
|
613
|
-
});
|
|
614
|
-
it("returns spark model string when --madmax-spark is present", () => {
|
|
615
|
-
assert.equal(resolveWorkerSparkModel(["--madmax-spark"]), expectedLowComplexityModel());
|
|
616
|
-
});
|
|
617
|
-
it("returns undefined when neither spark flag is present", () => {
|
|
618
|
-
assert.equal(resolveWorkerSparkModel(["--madmax", "--yolo", "--model", "gpt-5"]), undefined);
|
|
619
|
-
});
|
|
620
|
-
it("returns undefined for empty args", () => {
|
|
621
|
-
assert.equal(resolveWorkerSparkModel([]), undefined);
|
|
622
|
-
});
|
|
623
|
-
it("reads low-complexity team model from config when codexHomeOverride is provided", async () => {
|
|
624
|
-
const codexHome = await mkdtemp(join(tmpdir(), "rcs-codex-home-"));
|
|
625
|
-
try {
|
|
626
|
-
await writeFile(join(codexHome, ".rcs-config.json"), JSON.stringify({ models: { team_low_complexity: "gpt-4.1-mini" } }));
|
|
627
|
-
assert.equal(resolveWorkerSparkModel(["--spark"], codexHome), "gpt-4.1-mini");
|
|
628
|
-
}
|
|
629
|
-
finally {
|
|
630
|
-
await rm(codexHome, { recursive: true, force: true });
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
|
-
});
|
|
634
|
-
describe("resolveTeamWorkerLaunchArgsEnv (spark)", () => {
|
|
635
|
-
it("injects spark model as worker default when no explicit env model", () => {
|
|
636
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv(undefined, [], true, expectedLowComplexityModel()), `--model ${expectedLowComplexityModel()}`);
|
|
637
|
-
});
|
|
638
|
-
it("explicit env model overrides spark default", () => {
|
|
639
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv("--model gpt-5", [], true, expectedLowComplexityModel()), "--model gpt-5");
|
|
640
|
-
});
|
|
641
|
-
it("inherited leader model overrides spark default", () => {
|
|
642
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv(undefined, ["--model", "gpt-4.1"], true, expectedLowComplexityModel()), "--model gpt-4.1");
|
|
643
|
-
});
|
|
644
|
-
});
|
|
645
|
-
describe("commandOwnsLocalHelp", () => {
|
|
646
|
-
it("returns true for nested commands that render their own help output", () => {
|
|
647
|
-
for (const command of [
|
|
648
|
-
"adapt",
|
|
649
|
-
"agents-init",
|
|
650
|
-
"ask",
|
|
651
|
-
"question",
|
|
652
|
-
"autoresearch",
|
|
653
|
-
"deepinit",
|
|
654
|
-
"hooks",
|
|
655
|
-
"hud",
|
|
656
|
-
"ralph",
|
|
657
|
-
"resume",
|
|
658
|
-
"session",
|
|
659
|
-
"sparkshell",
|
|
660
|
-
"team",
|
|
661
|
-
"tmux-hook",
|
|
662
|
-
]) {
|
|
663
|
-
assert.equal(commandOwnsLocalHelp(command), true, `expected ${command} to own local help`);
|
|
664
|
-
}
|
|
665
|
-
});
|
|
666
|
-
it("returns false for top-level help-only commands", () => {
|
|
667
|
-
for (const command of ["help", "launch", "version", "update"]) {
|
|
668
|
-
assert.equal(commandOwnsLocalHelp(command), false, `expected ${command} to use top-level help`);
|
|
669
|
-
}
|
|
670
|
-
});
|
|
671
|
-
});
|
|
672
|
-
describe("resolveCliInvocation", () => {
|
|
673
|
-
it("resolves explore to explore command", () => {
|
|
674
|
-
assert.deepEqual(resolveCliInvocation(["explore", "--prompt", "find", "auth"]), {
|
|
675
|
-
command: "explore",
|
|
676
|
-
launchArgs: [],
|
|
677
|
-
});
|
|
678
|
-
});
|
|
679
|
-
it("resolves ask to ask command", () => {
|
|
680
|
-
assert.deepEqual(resolveCliInvocation(["ask", "claude", "hello"]), {
|
|
681
|
-
command: "ask",
|
|
682
|
-
launchArgs: [],
|
|
683
|
-
});
|
|
684
|
-
});
|
|
685
|
-
it("resolves question to question command", () => {
|
|
686
|
-
assert.deepEqual(resolveCliInvocation(["question", "--input", "{}"]), {
|
|
687
|
-
command: "question",
|
|
688
|
-
launchArgs: [],
|
|
689
|
-
});
|
|
690
|
-
});
|
|
691
|
-
it("resolves autoresearch to autoresearch command", () => {
|
|
692
|
-
assert.deepEqual(resolveCliInvocation(["autoresearch", "missions/demo"]), {
|
|
693
|
-
command: "autoresearch",
|
|
694
|
-
launchArgs: [],
|
|
695
|
-
});
|
|
696
|
-
});
|
|
697
|
-
it("resolves session to session command", () => {
|
|
698
|
-
assert.deepEqual(resolveCliInvocation(["session", "search", "startup evidence"]), {
|
|
699
|
-
command: "session",
|
|
700
|
-
launchArgs: [],
|
|
701
|
-
});
|
|
702
|
-
});
|
|
703
|
-
it("resolves resume to resume command and forwards trailing args", () => {
|
|
704
|
-
assert.deepEqual(resolveCliInvocation(["resume", "--last"]), {
|
|
705
|
-
command: "resume",
|
|
706
|
-
launchArgs: ["--last"],
|
|
707
|
-
});
|
|
708
|
-
});
|
|
709
|
-
it("resolves resume session id and prompt as forwarded args", () => {
|
|
710
|
-
assert.deepEqual(resolveCliInvocation(["resume", "session-123", "continue here"]), {
|
|
711
|
-
command: "resume",
|
|
712
|
-
launchArgs: ["session-123", "continue here"],
|
|
713
|
-
});
|
|
714
|
-
});
|
|
715
|
-
it("resolves exec to non-interactive launch passthrough and forwards trailing args", () => {
|
|
716
|
-
assert.deepEqual(resolveCliInvocation(["exec", "--model", "gpt-5", "say hi"]), {
|
|
717
|
-
command: "exec",
|
|
718
|
-
launchArgs: ["--model", "gpt-5", "say hi"],
|
|
719
|
-
});
|
|
720
|
-
});
|
|
721
|
-
it("resolves update to update command", () => {
|
|
722
|
-
assert.deepEqual(resolveCliInvocation(["update"]), {
|
|
723
|
-
command: "update",
|
|
724
|
-
launchArgs: [],
|
|
725
|
-
});
|
|
726
|
-
});
|
|
727
|
-
it("resolves hooks to hooks command", () => {
|
|
728
|
-
assert.deepEqual(resolveCliInvocation(["hooks"]), {
|
|
729
|
-
command: "hooks",
|
|
730
|
-
launchArgs: [],
|
|
731
|
-
});
|
|
732
|
-
});
|
|
733
|
-
it("resolves agents-init to agents-init command", () => {
|
|
734
|
-
assert.deepEqual(resolveCliInvocation(["agents-init", "."]), {
|
|
735
|
-
command: "agents-init",
|
|
736
|
-
launchArgs: [],
|
|
737
|
-
});
|
|
738
|
-
});
|
|
739
|
-
it("resolves deepinit to deepinit alias command", () => {
|
|
740
|
-
assert.deepEqual(resolveCliInvocation(["deepinit", "src"]), {
|
|
741
|
-
command: "deepinit",
|
|
742
|
-
launchArgs: [],
|
|
743
|
-
});
|
|
744
|
-
});
|
|
745
|
-
it("resolves --help to the help command instead of launch", () => {
|
|
746
|
-
assert.deepEqual(resolveCliInvocation(["--help"]), {
|
|
747
|
-
command: "help",
|
|
748
|
-
launchArgs: [],
|
|
749
|
-
});
|
|
750
|
-
});
|
|
751
|
-
it("resolves --version to the version command instead of launch", () => {
|
|
752
|
-
assert.deepEqual(resolveCliInvocation(["--version"]), {
|
|
753
|
-
command: "version",
|
|
754
|
-
launchArgs: [],
|
|
755
|
-
});
|
|
756
|
-
});
|
|
757
|
-
it("resolves -v to the version command instead of launch", () => {
|
|
758
|
-
assert.deepEqual(resolveCliInvocation(["-v"]), {
|
|
759
|
-
command: "version",
|
|
760
|
-
launchArgs: [],
|
|
761
|
-
});
|
|
762
|
-
});
|
|
763
|
-
it("keeps unknown long flags as launch passthrough args", () => {
|
|
764
|
-
assert.deepEqual(resolveCliInvocation(["--model", "gpt-5"]), {
|
|
765
|
-
command: "launch",
|
|
766
|
-
launchArgs: ["--model", "gpt-5"],
|
|
767
|
-
});
|
|
768
|
-
});
|
|
769
|
-
it("advertises the explicit update command in top-level help", () => {
|
|
770
|
-
assert.match(HELP, /rcs update\s+Check npm now, update the global install immediately, then refresh setup/);
|
|
771
|
-
});
|
|
772
|
-
it("advertises direct launch policy controls in top-level help", () => {
|
|
773
|
-
assert.match(HELP, /--direct\s+Launch the interactive leader directly/);
|
|
774
|
-
assert.match(HELP, /RCS_LAUNCH_POLICY=direct\|tmux\|detached-tmux\|auto/);
|
|
775
|
-
assert.match(HELP, /unset RCS_LAUNCH_POLICY/);
|
|
776
|
-
assert.match(HELP, /rcs --direct --yolo/);
|
|
777
|
-
assert.match(HELP, /RCS_LAUNCH_POLICY=direct rcs --tmux --yolo/);
|
|
778
|
-
assert.match(HELP, /Config files are intentionally not used/);
|
|
779
|
-
});
|
|
780
|
-
it("advertises creator workflow and psychology triggers in top-level help", () => {
|
|
781
|
-
assert.match(HELP, /\$brief\s+Capture goals, constraints, genre, audience, and outcome/);
|
|
782
|
-
assert.match(HELP, /\$autoforge\s+Run the end-to-end creator workflow with minimal supervision/);
|
|
783
|
-
assert.match(HELP, /\$brief:audience\s+Target fantasy, habit patterns, pain language, return motive/);
|
|
784
|
-
assert.match(HELP, /\$forge:community\s+Social stickiness systems/);
|
|
785
|
-
});
|
|
786
|
-
});
|
|
787
|
-
describe("resolveSetupInstallModeArg", () => {
|
|
788
|
-
it("maps explicit setup install mode flags", () => {
|
|
789
|
-
assert.equal(resolveSetupInstallModeArg(["--dry-run"]), undefined);
|
|
790
|
-
assert.equal(resolveSetupInstallModeArg(["--plugin"]), "plugin");
|
|
791
|
-
assert.equal(resolveSetupInstallModeArg(["--legacy"]), "legacy");
|
|
792
|
-
assert.equal(resolveSetupInstallModeArg(["--install-mode", "legacy"]), "legacy");
|
|
793
|
-
assert.equal(resolveSetupInstallModeArg(["--install-mode=plugin"]), "plugin");
|
|
794
|
-
assert.equal(resolveSetupInstallModeArg(["--scope", "project", "--plugin"]), "plugin");
|
|
795
|
-
});
|
|
796
|
-
it("rejects invalid setup install mode flags", () => {
|
|
797
|
-
assert.throws(() => resolveSetupInstallModeArg(["--install-mode"]), /Missing setup install mode value after --install-mode/);
|
|
798
|
-
assert.throws(() => resolveSetupInstallModeArg(["--install-mode", "workspace"]), /Invalid setup install mode: workspace/);
|
|
799
|
-
assert.throws(() => resolveSetupInstallModeArg(["--plugin", "--legacy"]), /Conflicting setup install mode flags/);
|
|
800
|
-
assert.throws(() => resolveSetupInstallModeArg(["--plugin", "--install-mode", "legacy"]), /Conflicting setup install mode flags/);
|
|
801
|
-
assert.throws(() => resolveSetupInstallModeArg(["--legacy", "--install-mode=plugin"]), /Conflicting setup install mode flags/);
|
|
802
|
-
});
|
|
803
|
-
});
|
|
804
|
-
describe("resolveSetupScopeArg", () => {
|
|
805
|
-
it("returns undefined when scope is omitted", () => {
|
|
806
|
-
assert.equal(resolveSetupScopeArg(["--dry-run"]), undefined);
|
|
807
|
-
});
|
|
808
|
-
it("parses --scope <value> form", () => {
|
|
809
|
-
assert.equal(resolveSetupScopeArg(["--dry-run", "--scope", "project"]), "project");
|
|
810
|
-
});
|
|
811
|
-
it("parses --scope=<value> form", () => {
|
|
812
|
-
assert.equal(resolveSetupScopeArg(["--scope=project"]), "project");
|
|
813
|
-
});
|
|
814
|
-
it("throws on invalid scope value", () => {
|
|
815
|
-
assert.throws(() => resolveSetupScopeArg(["--scope", "workspace"]), /Invalid setup scope: workspace/);
|
|
816
|
-
});
|
|
817
|
-
it("throws when --scope value is missing", () => {
|
|
818
|
-
assert.throws(() => resolveSetupScopeArg(["--scope"]), /Missing setup scope value after --scope/);
|
|
819
|
-
});
|
|
820
|
-
});
|
|
821
|
-
describe("project launch scope helpers", () => {
|
|
822
|
-
it("reads persisted setup scope when valid", async () => {
|
|
823
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
824
|
-
try {
|
|
825
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
826
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
827
|
-
assert.equal(readPersistedSetupScope(wd), "project");
|
|
828
|
-
}
|
|
829
|
-
finally {
|
|
830
|
-
await rm(wd, { recursive: true, force: true });
|
|
831
|
-
}
|
|
832
|
-
});
|
|
833
|
-
it("reads persisted setup preferences when install mode is present", async () => {
|
|
834
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
835
|
-
try {
|
|
836
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
837
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "user", installMode: "plugin" }));
|
|
838
|
-
assert.deepEqual(readPersistedSetupPreferences(wd), {
|
|
839
|
-
scope: "user",
|
|
840
|
-
installMode: "plugin",
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
finally {
|
|
844
|
-
await rm(wd, { recursive: true, force: true });
|
|
845
|
-
}
|
|
846
|
-
});
|
|
847
|
-
it("ignores malformed persisted setup scope", async () => {
|
|
848
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
849
|
-
try {
|
|
850
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
851
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), "{not-json");
|
|
852
|
-
assert.equal(readPersistedSetupScope(wd), undefined);
|
|
853
|
-
}
|
|
854
|
-
finally {
|
|
855
|
-
await rm(wd, { recursive: true, force: true });
|
|
856
|
-
}
|
|
857
|
-
});
|
|
858
|
-
it("uses project CODEX_HOME when persisted scope is project", async () => {
|
|
859
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
860
|
-
try {
|
|
861
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
862
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
863
|
-
assert.equal(resolveCodexHomeForLaunch(wd, {}), join(wd, ".codex"));
|
|
864
|
-
}
|
|
865
|
-
finally {
|
|
866
|
-
await rm(wd, { recursive: true, force: true });
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
it("uses project CODEX_HOME when persisted scope is project even if HOME is unusable", async () => {
|
|
870
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
871
|
-
try {
|
|
872
|
-
const badHome = join(wd, "home-as-file");
|
|
873
|
-
await writeFile(badHome, "not-a-directory");
|
|
874
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
875
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
876
|
-
assert.equal(resolveCodexHomeForLaunch(wd, { HOME: badHome }), join(wd, ".codex"));
|
|
877
|
-
assert.equal(resolveCodexConfigPathForLaunch(wd, { HOME: badHome }), join(wd, ".codex", "config.toml"));
|
|
878
|
-
}
|
|
879
|
-
finally {
|
|
880
|
-
await rm(wd, { recursive: true, force: true });
|
|
881
|
-
}
|
|
882
|
-
});
|
|
883
|
-
it("uses project config.toml for launch repair when persisted scope is project", async () => {
|
|
884
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
885
|
-
try {
|
|
886
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
887
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
888
|
-
assert.equal(resolveCodexConfigPathForLaunch(wd, {}), join(wd, ".codex", "config.toml"));
|
|
889
|
-
}
|
|
890
|
-
finally {
|
|
891
|
-
await rm(wd, { recursive: true, force: true });
|
|
892
|
-
}
|
|
893
|
-
});
|
|
894
|
-
it("marks only persisted project CODEX_HOME as project-local cleanup target", async () => {
|
|
895
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
896
|
-
try {
|
|
897
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
898
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
899
|
-
assert.equal(resolveProjectLocalCodexHomeForLaunch(wd, {}), join(wd, ".codex"));
|
|
900
|
-
}
|
|
901
|
-
finally {
|
|
902
|
-
await rm(wd, { recursive: true, force: true });
|
|
903
|
-
}
|
|
904
|
-
});
|
|
905
|
-
it("does not mark explicit CODEX_HOME as project-local cleanup target", async () => {
|
|
906
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
907
|
-
try {
|
|
908
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
909
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
910
|
-
assert.equal(resolveProjectLocalCodexHomeForLaunch(wd, {
|
|
911
|
-
CODEX_HOME: "/tmp/user-global-codex-home",
|
|
912
|
-
}), undefined);
|
|
913
|
-
}
|
|
914
|
-
finally {
|
|
915
|
-
await rm(wd, { recursive: true, force: true });
|
|
916
|
-
}
|
|
917
|
-
});
|
|
918
|
-
it("uses a session-scoped CODEX_HOME mirror for project launch config writes", async () => {
|
|
919
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-runtime-codex-home-"));
|
|
920
|
-
try {
|
|
921
|
-
const projectCodexHome = join(wd, ".codex");
|
|
922
|
-
const configPath = join(projectCodexHome, "config.toml");
|
|
923
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
924
|
-
await mkdir(join(projectCodexHome, "agents"), { recursive: true });
|
|
925
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
926
|
-
const originalConfig = [
|
|
927
|
-
'model = "gpt-5.5"',
|
|
928
|
-
"",
|
|
929
|
-
"[tui]",
|
|
930
|
-
'status_line = ["model-with-reasoning", "git-branch"]',
|
|
931
|
-
"",
|
|
932
|
-
].join("\n");
|
|
933
|
-
await writeFile(configPath, originalConfig);
|
|
934
|
-
await writeFile(join(projectCodexHome, "agents", "planner.toml"), 'name = "planner"\n');
|
|
935
|
-
const beforeStat = await stat(configPath);
|
|
936
|
-
const prepared = await prepareCodexHomeForLaunch(wd, "session-2033", {});
|
|
937
|
-
const runtimeCodexHome = runtimeCodexHomePath(wd, "session-2033");
|
|
938
|
-
assert.equal(prepared.codexHomeOverride, runtimeCodexHome);
|
|
939
|
-
assert.equal(prepared.projectLocalCodexHomeForCleanup, projectCodexHome);
|
|
940
|
-
assert.equal(prepared.runtimeCodexHomeForCleanup, runtimeCodexHome);
|
|
941
|
-
assert.equal(await readFile(join(runtimeCodexHome, "config.toml"), "utf-8"), originalConfig);
|
|
942
|
-
assert.equal(await readFile(join(runtimeCodexHome, "agents", "planner.toml"), "utf-8"), 'name = "planner"\n');
|
|
943
|
-
await writeFile(join(runtimeCodexHome, "config.toml"), `${originalConfig}\n[tui.model_availability_nux]\n"gpt-5.5" = 1\n`);
|
|
944
|
-
assert.equal(await readFile(configPath, "utf-8"), originalConfig);
|
|
945
|
-
assert.doesNotMatch(await readFile(configPath, "utf-8"), /model_availability_nux/);
|
|
946
|
-
assert.equal((await stat(configPath)).mtimeMs, beforeStat.mtimeMs);
|
|
947
|
-
await prepareCodexHomeForLaunch(wd, "session-2033-repeat", {});
|
|
948
|
-
assert.equal(await readFile(configPath, "utf-8"), originalConfig);
|
|
949
|
-
assert.equal((await stat(configPath)).mtimeMs, beforeStat.mtimeMs);
|
|
950
|
-
}
|
|
951
|
-
finally {
|
|
952
|
-
await rm(wd, { recursive: true, force: true });
|
|
953
|
-
}
|
|
954
|
-
});
|
|
955
|
-
it("keeps explicit CODEX_HOME persistent instead of creating a runtime mirror", async () => {
|
|
956
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-runtime-codex-home-"));
|
|
957
|
-
try {
|
|
958
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
959
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
960
|
-
const prepared = await prepareCodexHomeForLaunch(wd, "session-explicit", {
|
|
961
|
-
CODEX_HOME: "/tmp/explicit-codex-home",
|
|
962
|
-
});
|
|
963
|
-
assert.equal(prepared.codexHomeOverride, "/tmp/explicit-codex-home");
|
|
964
|
-
assert.equal(prepared.projectLocalCodexHomeForCleanup, undefined);
|
|
965
|
-
assert.equal(prepared.runtimeCodexHomeForCleanup, undefined);
|
|
966
|
-
}
|
|
967
|
-
finally {
|
|
968
|
-
await rm(wd, { recursive: true, force: true });
|
|
969
|
-
}
|
|
970
|
-
});
|
|
971
|
-
it("keeps explicit CODEX_HOME override from env", async () => {
|
|
972
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
973
|
-
try {
|
|
974
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
975
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
976
|
-
assert.equal(resolveCodexHomeForLaunch(wd, {
|
|
977
|
-
CODEX_HOME: "/tmp/explicit-codex-home",
|
|
978
|
-
}), "/tmp/explicit-codex-home");
|
|
979
|
-
}
|
|
980
|
-
finally {
|
|
981
|
-
await rm(wd, { recursive: true, force: true });
|
|
982
|
-
}
|
|
983
|
-
});
|
|
984
|
-
it("uses explicit CODEX_HOME config.toml for launch repair overrides", async () => {
|
|
985
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
986
|
-
try {
|
|
987
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
988
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
989
|
-
assert.equal(resolveCodexConfigPathForLaunch(wd, {
|
|
990
|
-
CODEX_HOME: "/tmp/explicit-codex-home",
|
|
991
|
-
}), "/tmp/explicit-codex-home/config.toml");
|
|
992
|
-
}
|
|
993
|
-
finally {
|
|
994
|
-
await rm(wd, { recursive: true, force: true });
|
|
995
|
-
}
|
|
996
|
-
});
|
|
997
|
-
it('migrates legacy "project-local" persisted scope to "project"', async () => {
|
|
998
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
999
|
-
try {
|
|
1000
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
1001
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project-local" }));
|
|
1002
|
-
assert.equal(readPersistedSetupScope(wd), "project");
|
|
1003
|
-
}
|
|
1004
|
-
finally {
|
|
1005
|
-
await rm(wd, { recursive: true, force: true });
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
it('resolves CODEX_HOME for legacy "project-local" persisted scope', async () => {
|
|
1009
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-launch-scope-"));
|
|
1010
|
-
try {
|
|
1011
|
-
await mkdir(join(wd, ".rcs"), { recursive: true });
|
|
1012
|
-
await writeFile(join(wd, ".rcs", "setup-scope.json"), JSON.stringify({ scope: "project-local" }));
|
|
1013
|
-
assert.equal(resolveCodexHomeForLaunch(wd, {}), join(wd, ".codex"));
|
|
1014
|
-
}
|
|
1015
|
-
finally {
|
|
1016
|
-
await rm(wd, { recursive: true, force: true });
|
|
1017
|
-
}
|
|
1018
|
-
});
|
|
1019
|
-
});
|
|
1020
|
-
describe("resolveCodexLaunchPolicy", () => {
|
|
1021
|
-
it("uses detached tmux on macOS when outside tmux and tmux is available", () => {
|
|
1022
|
-
assert.equal(resolveCodexLaunchPolicy({}, "darwin", true, false, true, true), "detached-tmux");
|
|
1023
|
-
});
|
|
1024
|
-
it("uses tmux-aware launch path when already inside tmux", () => {
|
|
1025
|
-
assert.equal(resolveCodexLaunchPolicy({ TMUX: "/tmp/tmux-1000/default,123,0" }, "darwin", true), "inside-tmux");
|
|
1026
|
-
});
|
|
1027
|
-
it("uses tmux-aware launch path when already inside tmux on native Windows", () => {
|
|
1028
|
-
assert.equal(resolveCodexLaunchPolicy({ TMUX: "psmux-session" }, "win32", true, true), "inside-tmux");
|
|
1029
|
-
});
|
|
1030
|
-
it("uses detached tmux on non-macOS hosts when outside tmux and tmux is available", () => {
|
|
1031
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, true, true), "detached-tmux");
|
|
1032
|
-
});
|
|
1033
|
-
it("launches directly on native Windows even when tmux is available", () => {
|
|
1034
|
-
assert.equal(resolveCodexLaunchPolicy({}, "win32", true, true), "direct");
|
|
1035
|
-
});
|
|
1036
|
-
it("does not force direct launch for MSYS or Git Bash on win32", () => {
|
|
1037
|
-
assert.equal(resolveCodexLaunchPolicy({ MSYSTEM: "MINGW64" }, "win32", true, false, true, true), "direct");
|
|
1038
|
-
});
|
|
1039
|
-
it("honors explicit detached tmux launch requests when tmux is available", () => {
|
|
1040
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, true, true, "detached-tmux"), "detached-tmux");
|
|
1041
|
-
});
|
|
1042
|
-
it("honors explicit direct launch requests outside tmux", () => {
|
|
1043
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, true, true, "direct"), "direct");
|
|
1044
|
-
});
|
|
1045
|
-
it("honors explicit direct launch requests inside tmux", () => {
|
|
1046
|
-
assert.equal(resolveCodexLaunchPolicy({ TMUX: "/tmp/tmux-1000/default,123,0" }, "linux", true, false, true, true, "direct"), "direct");
|
|
1047
|
-
});
|
|
1048
|
-
it("keeps explicit tmux policy tmux-aware inside tmux", () => {
|
|
1049
|
-
assert.equal(resolveCodexLaunchPolicy({ TMUX: "/tmp/tmux-1000/default,123,0" }, "linux", true, false, true, true, "detached-tmux"), "inside-tmux");
|
|
1050
|
-
});
|
|
1051
|
-
it("falls back directly for explicit tmux requests when tmux is unavailable", () => {
|
|
1052
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", false, false, true, true, "detached-tmux"), "direct");
|
|
1053
|
-
});
|
|
1054
|
-
it("launches directly when stdin is not a tty outside tmux", () => {
|
|
1055
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, false, true), "direct");
|
|
1056
|
-
});
|
|
1057
|
-
it("launches directly when stdout is not a tty outside tmux", () => {
|
|
1058
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", true, false, true, false), "direct");
|
|
1059
|
-
});
|
|
1060
|
-
it("launches directly when tmux is unavailable outside tmux", () => {
|
|
1061
|
-
assert.equal(resolveCodexLaunchPolicy({}, "linux", false), "direct");
|
|
1062
|
-
});
|
|
1063
|
-
it("launches directly on native Windows when tmux is unavailable", () => {
|
|
1064
|
-
assert.equal(resolveCodexLaunchPolicy({}, "win32", false, true), "direct");
|
|
1065
|
-
});
|
|
1066
|
-
});
|
|
1067
|
-
describe("resolveBackgroundHelperLaunchMode", () => {
|
|
1068
|
-
it("uses the hidden Windows MSYS bootstrap for win32 Git Bash", () => {
|
|
1069
|
-
assert.equal(resolveBackgroundHelperLaunchMode({ MSYSTEM: "MINGW64" }, "win32"), "windows-msys-bootstrap");
|
|
1070
|
-
});
|
|
1071
|
-
it("spawns helpers directly on native win32", () => {
|
|
1072
|
-
assert.equal(resolveBackgroundHelperLaunchMode({}, "win32"), "direct-detached");
|
|
1073
|
-
});
|
|
1074
|
-
it("spawns helpers directly on non-Windows platforms", () => {
|
|
1075
|
-
assert.equal(resolveBackgroundHelperLaunchMode({ MSYSTEM: "MINGW64" }, "linux"), "direct-detached");
|
|
1076
|
-
});
|
|
1077
|
-
});
|
|
1078
|
-
describe("shouldDetachBackgroundHelper", () => {
|
|
1079
|
-
it("keeps the long-running helper detached under win32 Git Bash", () => {
|
|
1080
|
-
assert.equal(shouldDetachBackgroundHelper({ MSYSTEM: "MINGW64" }, "win32"), true);
|
|
1081
|
-
});
|
|
1082
|
-
it("keeps detached helpers on native win32", () => {
|
|
1083
|
-
assert.equal(shouldDetachBackgroundHelper({}, "win32"), true);
|
|
1084
|
-
});
|
|
1085
|
-
it("keeps detached helpers on non-Windows platforms", () => {
|
|
1086
|
-
assert.equal(shouldDetachBackgroundHelper({ MSYSTEM: "MINGW64" }, "linux"), true);
|
|
1087
|
-
});
|
|
1088
|
-
});
|
|
1089
|
-
describe("classifyCodexExecFailure", () => {
|
|
1090
|
-
it("classifies child process exit status as codex exit", () => {
|
|
1091
|
-
const err = Object.assign(new Error("codex exited 9"), { status: 9 });
|
|
1092
|
-
const classified = classifyCodexExecFailure(err);
|
|
1093
|
-
assert.equal(classified.kind, "exit");
|
|
1094
|
-
assert.equal(classified.exitCode, 9);
|
|
1095
|
-
});
|
|
1096
|
-
it("classifies signal termination as codex exit and maps to signal-based exit code", () => {
|
|
1097
|
-
const err = Object.assign(new Error("terminated"), {
|
|
1098
|
-
status: null,
|
|
1099
|
-
signal: "SIGTERM",
|
|
1100
|
-
});
|
|
1101
|
-
const classified = classifyCodexExecFailure(err);
|
|
1102
|
-
assert.equal(classified.kind, "exit");
|
|
1103
|
-
assert.equal(classified.signal, "SIGTERM");
|
|
1104
|
-
assert.equal(classified.exitCode, resolveSignalExitCode("SIGTERM"));
|
|
1105
|
-
});
|
|
1106
|
-
it("classifies ENOENT as launch error", () => {
|
|
1107
|
-
const err = Object.assign(new Error("spawn codex ENOENT"), {
|
|
1108
|
-
code: "ENOENT",
|
|
1109
|
-
});
|
|
1110
|
-
const classified = classifyCodexExecFailure(err);
|
|
1111
|
-
assert.equal(classified.kind, "launch-error");
|
|
1112
|
-
assert.equal(classified.code, "ENOENT");
|
|
1113
|
-
});
|
|
1114
|
-
});
|
|
1115
|
-
describe("tmux HUD pane helpers", () => {
|
|
1116
|
-
it("findHudWatchPaneIds detects stale HUD watch panes and excludes current pane", () => {
|
|
1117
|
-
const panes = parseTmuxPaneSnapshot([
|
|
1118
|
-
"%1\tzsh\tzsh",
|
|
1119
|
-
"%2\tnode\tnode /tmp/bin/rcs.js hud --watch",
|
|
1120
|
-
"%3\tnode\tnode /tmp/bin/rcs.js hud --watch",
|
|
1121
|
-
"%4\tcodex\tcodex --model gpt-5",
|
|
1122
|
-
].join("\n"));
|
|
1123
|
-
assert.deepEqual(findHudWatchPaneIds(panes, "%2"), ["%3"]);
|
|
1124
|
-
});
|
|
1125
|
-
it("buildHudPaneCleanupTargets de-dupes pane ids and includes created pane", () => {
|
|
1126
|
-
assert.deepEqual(buildHudPaneCleanupTargets(["%3", "%3", "invalid"], "%4"), ["%3", "%4"]);
|
|
1127
|
-
});
|
|
1128
|
-
it("buildHudPaneCleanupTargets excludes leader pane from existing ids", () => {
|
|
1129
|
-
// %5 is the leader pane — it must not be included even if findHudWatchPaneIds let it through.
|
|
1130
|
-
assert.deepEqual(buildHudPaneCleanupTargets(["%3", "%5"], "%4", "%5"), [
|
|
1131
|
-
"%3",
|
|
1132
|
-
"%4",
|
|
1133
|
-
]);
|
|
1134
|
-
});
|
|
1135
|
-
it("buildHudPaneCleanupTargets excludes leader pane even when it matches the created HUD pane id", () => {
|
|
1136
|
-
// Defensive edge case: if createHudWatchPane somehow returned the leader pane id, guard protects it.
|
|
1137
|
-
assert.deepEqual(buildHudPaneCleanupTargets(["%3"], "%5", "%5"), ["%3"]);
|
|
1138
|
-
});
|
|
1139
|
-
it("buildHudPaneCleanupTargets is a no-op guard when leaderPaneId is absent", () => {
|
|
1140
|
-
assert.deepEqual(buildHudPaneCleanupTargets(["%3"], "%4"), ["%3", "%4"]);
|
|
1141
|
-
});
|
|
1142
|
-
it("listCurrentWindowHudPaneIds scopes tmux pane listing to the emitting pane", () => {
|
|
1143
|
-
const calls = [];
|
|
1144
|
-
const panes = listCurrentWindowHudPaneIds("%leader", (args) => {
|
|
1145
|
-
calls.push(args);
|
|
1146
|
-
return [
|
|
1147
|
-
"%leader\tcodex\tcodex",
|
|
1148
|
-
"%hud\tnode\tnode /tmp/bin/rcs.js hud --watch",
|
|
1149
|
-
].join("\n");
|
|
1150
|
-
});
|
|
1151
|
-
assert.deepEqual(panes, ["%hud"]);
|
|
1152
|
-
assert.deepEqual(calls[0], [
|
|
1153
|
-
"list-panes",
|
|
1154
|
-
"-t",
|
|
1155
|
-
"%leader",
|
|
1156
|
-
"-F",
|
|
1157
|
-
"#{pane_id}\t#{pane_current_command}\t#{pane_start_command}",
|
|
1158
|
-
]);
|
|
1159
|
-
});
|
|
1160
|
-
it("createHudWatchPane splits from the emitting pane target when provided", () => {
|
|
1161
|
-
const calls = [];
|
|
1162
|
-
const paneId = createSharedHudWatchPane("/repo", "node /repo/dist/cli/rcs.js hud --watch", { heightLines: 3, targetPaneId: "%leader" }, (args) => {
|
|
1163
|
-
calls.push(args);
|
|
1164
|
-
return "%hud\n";
|
|
1165
|
-
});
|
|
1166
|
-
assert.equal(paneId, "%hud");
|
|
1167
|
-
assert.deepEqual(calls[0], [
|
|
1168
|
-
"split-window",
|
|
1169
|
-
"-v",
|
|
1170
|
-
"-l",
|
|
1171
|
-
"3",
|
|
1172
|
-
"-d",
|
|
1173
|
-
"-t",
|
|
1174
|
-
"%leader",
|
|
1175
|
-
"-c",
|
|
1176
|
-
"/repo",
|
|
1177
|
-
"-P",
|
|
1178
|
-
"-F",
|
|
1179
|
-
"#{pane_id}",
|
|
1180
|
-
"node /repo/dist/cli/rcs.js hud --watch",
|
|
1181
|
-
]);
|
|
1182
|
-
});
|
|
1183
|
-
});
|
|
1184
|
-
describe("detached tmux new-session sequencing", () => {
|
|
1185
|
-
it("buildDetachedSessionBootstrapSteps uses shared HUD height and split-capture ordering", () => {
|
|
1186
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/rcs.js' 'hud' '--watch'", "--model gpt-5", "/tmp/codex-home", '{"active":true}', false, "rcs-session-test");
|
|
1187
|
-
assert.deepEqual(steps.map((step) => step.name), ["new-session", "tag-session", "split-and-capture-hud-pane"]);
|
|
1188
|
-
const splitStep = steps.find((step) => step.name === "split-and-capture-hud-pane");
|
|
1189
|
-
assert.ok(splitStep);
|
|
1190
|
-
assert.equal(splitStep.args[3], String(HUD_TMUX_HEIGHT_LINES));
|
|
1191
|
-
assert.equal(splitStep.args[6], "rcs-demo");
|
|
1192
|
-
assert.equal(splitStep.args.includes("-P"), true);
|
|
1193
|
-
assert.equal(splitStep.args.includes("#{pane_id}"), true);
|
|
1194
|
-
assert.equal(steps[0]?.args.includes("-e"), true);
|
|
1195
|
-
assert.equal(steps[0]?.args.includes("RCS_SESSION_ID=rcs-session-test"), true);
|
|
1196
|
-
assert.equal(steps[0]?.args.includes('RCS_NOTIFY_TEMP_CONTRACT={\"active\":true}'), true);
|
|
1197
|
-
});
|
|
1198
|
-
it("buildDetachedSessionBootstrapSteps forwards temp contract env to detached tmux session", () => {
|
|
1199
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/rcs.js' 'hud' '--watch'", null, undefined, '{"active":true,"canonicalSelectors":["discord"]}');
|
|
1200
|
-
const newSession = steps.find((step) => step.name === "new-session");
|
|
1201
|
-
assert.ok(newSession);
|
|
1202
|
-
assert.equal(newSession.args.includes("-e") &&
|
|
1203
|
-
newSession.args.some((arg) => arg.startsWith("RCS_NOTIFY_TEMP_CONTRACT=")), true);
|
|
1204
|
-
});
|
|
1205
|
-
it("buildDetachedSessionBootstrapSteps forwards RCS_SESSION_ID to detached tmux session", () => {
|
|
1206
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "/tmp/project", "'env' 'RCS_SESSION_ID=sess-detached-managed' 'codex' '--model' 'gpt-5'", "'node' '/tmp/rcs.js' 'hud' '--watch'", null, undefined, null, false, "sess-detached-managed");
|
|
1207
|
-
const newSession = steps.find((step) => step.name === "new-session");
|
|
1208
|
-
const tagSession = steps.find((step) => step.name === "tag-session");
|
|
1209
|
-
assert.ok(newSession);
|
|
1210
|
-
assert.ok(tagSession);
|
|
1211
|
-
assert.equal(newSession.args.includes("-e") &&
|
|
1212
|
-
newSession.args.some((arg) => arg === "RCS_SESSION_ID=sess-detached-managed"), true);
|
|
1213
|
-
assert.deepEqual(tagSession.args, [
|
|
1214
|
-
"set-option",
|
|
1215
|
-
"-t",
|
|
1216
|
-
"rcs-demo",
|
|
1217
|
-
"@rcs_instance_id",
|
|
1218
|
-
"sess-detached-managed",
|
|
1219
|
-
]);
|
|
1220
|
-
});
|
|
1221
|
-
it("buildDetachedSessionBootstrapSteps forwards CODEX_HOME override to detached tmux session", () => {
|
|
1222
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/rcs.js' 'hud' '--watch'", null, "/tmp/project/.codex", null, false, "sess-detached-managed");
|
|
1223
|
-
const newSession = steps.find((step) => step.name === "new-session");
|
|
1224
|
-
assert.ok(newSession);
|
|
1225
|
-
assert.equal(newSession.args.includes("-e") &&
|
|
1226
|
-
newSession.args.some((arg) => arg === "CODEX_HOME=/tmp/project/.codex"), true);
|
|
1227
|
-
});
|
|
1228
|
-
it("runCodex builds inside-tmux HUD command with RCS_SESSION_ID", async () => {
|
|
1229
|
-
const source = await readFile(join(repoRoot, 'src', 'cli', 'index.ts'), 'utf-8');
|
|
1230
|
-
assert.match(source, /buildTmuxPaneCommand\("env",\s*\[\s*`RCS_SESSION_ID=\$\{sessionId\}`,\s*"node",\s*rcsBin,\s*"hud",\s*"--watch",?\s*\]\)/);
|
|
1231
|
-
});
|
|
1232
|
-
it("buildDetachedSessionBootstrapSteps starts native Windows detached sessions with powershell", () => {
|
|
1233
|
-
const hudCmd = buildWindowsPromptCommand("node", [
|
|
1234
|
-
"rcs.js",
|
|
1235
|
-
"hud",
|
|
1236
|
-
"--watch",
|
|
1237
|
-
]);
|
|
1238
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "C:/project", "'codex' '--dangerously-bypass-approvals-and-sandbox'", hudCmd, "--model gpt-5", "C:/codex-home", null, true);
|
|
1239
|
-
assert.equal(steps[0]?.name, "new-session");
|
|
1240
|
-
assert.equal(steps[0]?.args.at(-1), "powershell.exe");
|
|
1241
|
-
assert.equal(steps[1]?.name, "split-and-capture-hud-pane");
|
|
1242
|
-
assert.equal(steps[1]?.args.at(-1), hudCmd);
|
|
1243
|
-
});
|
|
1244
|
-
it("buildDetachedWindowsBootstrapScript targets the resolved tmux-compatible command", () => {
|
|
1245
|
-
const script = buildDetachedWindowsBootstrapScript("rcs-demo", "powershell.exe -NoLogo -NoExit -EncodedCommand abc", 2500, "C:\\Program Files\\psmux\\psmux.exe");
|
|
1246
|
-
assert.match(script, /const tmuxCommand = "C:\\\\Program Files\\\\psmux\\\\psmux\.exe";/);
|
|
1247
|
-
assert.match(script, /execFileSync\(tmuxCommand, \['send-keys'/);
|
|
1248
|
-
assert.doesNotMatch(script, /execFileSync\('tmux'/);
|
|
1249
|
-
});
|
|
1250
|
-
it("buildDetachedSessionBootstrapSteps kills detached tmux session on normal shell exit", () => {
|
|
1251
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/rcs.js' 'hud' '--watch'", null);
|
|
1252
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
1253
|
-
assert.equal(typeof leaderCmd, "string");
|
|
1254
|
-
assert.match(leaderCmd, /^\/bin\/sh -c '/);
|
|
1255
|
-
assert.doesNotMatch(leaderCmd, /^\/bin\/sh -lc '/);
|
|
1256
|
-
assert.match(leaderCmd, /acquireTmuxExtendedKeysLease/);
|
|
1257
|
-
assert.match(leaderCmd, /rcs_detached_session_cleanup\(\)/);
|
|
1258
|
-
assert.match(leaderCmd, /trap rcs_detached_session_cleanup 0 INT TERM HUP;/);
|
|
1259
|
-
assert.match(leaderCmd, /exec 3<&0;/);
|
|
1260
|
-
assert.match(leaderCmd, /rcs_codex_pid=\$!;/);
|
|
1261
|
-
assert.match(leaderCmd, /<\&3 &/);
|
|
1262
|
-
assert.match(leaderCmd, /wait "\$rcs_codex_pid";/);
|
|
1263
|
-
assert.match(leaderCmd, /kill -TERM "\$rcs_codex_pid"/);
|
|
1264
|
-
assert.match(leaderCmd, /releaseTmuxExtendedKeysLease/);
|
|
1265
|
-
assert.match(leaderCmd, /if \[ "\$status" -lt 128 \]; then/);
|
|
1266
|
-
assert.match(leaderCmd, /tmux kill-session -t/);
|
|
1267
|
-
assert.match(leaderCmd, /"rcs-demo"/);
|
|
1268
|
-
assert.match(leaderCmd, /exit \$status/);
|
|
1269
|
-
});
|
|
1270
|
-
it("buildDetachedSessionBootstrapSteps finalizes postLaunch inside the detached leader when a session id is available", () => {
|
|
1271
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/rcs.js' 'hud' '--watch'", null, "/tmp/codex-home", null, false, "rcs-session-123", "/tmp/project/.codex-project", "/tmp/project/.rcs/runtime/codex-home/rcs-session-123");
|
|
1272
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
1273
|
-
assert.equal(typeof leaderCmd, "string");
|
|
1274
|
-
assert.match(leaderCmd, /runDetachedSessionPostLaunch/);
|
|
1275
|
-
assert.match(leaderCmd, /rcs-session-123/);
|
|
1276
|
-
assert.match(leaderCmd, /\/tmp\/codex-home/);
|
|
1277
|
-
assert.match(leaderCmd, /\/tmp\/project\/\.codex-project/);
|
|
1278
|
-
assert.match(leaderCmd, /\/tmp\/project\/\.rcs\/runtime\/codex-home\/rcs-session-123/);
|
|
1279
|
-
const helperIndex = leaderCmd.indexOf("runDetachedSessionPostLaunch");
|
|
1280
|
-
const signalGateIndex = leaderCmd.indexOf('if [ "$status" -lt 128 ]');
|
|
1281
|
-
assert.ok(helperIndex >= 0);
|
|
1282
|
-
assert.ok(signalGateIndex >= 0);
|
|
1283
|
-
assert.ok(helperIndex < signalGateIndex, "detached postLaunch helper must run before the signal-derived tmux kill-session gate");
|
|
1284
|
-
});
|
|
1285
|
-
it("detached leader command keeps stdin open for the Codex child", async () => {
|
|
1286
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-detached-leader-stdin-"));
|
|
1287
|
-
const fakeBin = join(cwd, "bin");
|
|
1288
|
-
const stdinLogPath = join(cwd, "stdin.log");
|
|
1289
|
-
try {
|
|
1290
|
-
await mkdir(fakeBin, { recursive: true });
|
|
1291
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
1292
|
-
if IFS= read -r line; then
|
|
1293
|
-
printf 'stdin:%s\n' "$line" > "${stdinLogPath}"
|
|
1294
|
-
else
|
|
1295
|
-
printf 'stdin:EOF\n' > "${stdinLogPath}"
|
|
1296
|
-
fi
|
|
1297
|
-
`);
|
|
1298
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
1299
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
1300
|
-
case "$1" in
|
|
1301
|
-
display-message)
|
|
1302
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
1303
|
-
printf '/tmp/tmux-test.sock\n'
|
|
1304
|
-
else
|
|
1305
|
-
printf '0\n'
|
|
1306
|
-
fi
|
|
1307
|
-
;;
|
|
1308
|
-
show-options)
|
|
1309
|
-
printf 'off\n'
|
|
1310
|
-
;;
|
|
1311
|
-
set-option|kill-session)
|
|
1312
|
-
;;
|
|
1313
|
-
esac
|
|
1314
|
-
exit 0
|
|
1315
|
-
`);
|
|
1316
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
1317
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", cwd, buildTmuxPaneCommand("codex", [], "/bin/sh"), "'node' '/tmp/rcs.js' 'hud' '--watch'", null);
|
|
1318
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
1319
|
-
assert.equal(typeof leaderCmd, "string");
|
|
1320
|
-
const result = (await import("node:child_process")).spawnSync("/bin/sh", ["-c", leaderCmd], {
|
|
1321
|
-
cwd,
|
|
1322
|
-
env: {
|
|
1323
|
-
...process.env,
|
|
1324
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
1325
|
-
HOME: cwd,
|
|
1326
|
-
},
|
|
1327
|
-
input: "hello from leader\n",
|
|
1328
|
-
encoding: "utf-8",
|
|
1329
|
-
});
|
|
1330
|
-
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
1331
|
-
const stdinLog = await readFile(stdinLogPath, "utf-8");
|
|
1332
|
-
assert.match(stdinLog, /stdin:hello from leader/);
|
|
1333
|
-
}
|
|
1334
|
-
finally {
|
|
1335
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1336
|
-
}
|
|
1337
|
-
});
|
|
1338
|
-
it("detached leader command preserves cwd and cleanup without shell-quote breakage", async () => {
|
|
1339
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-detached-leader-"));
|
|
1340
|
-
const fakeBin = join(cwd, "bin");
|
|
1341
|
-
const logPath = join(cwd, "leader.log");
|
|
1342
|
-
try {
|
|
1343
|
-
await mkdir(fakeBin, { recursive: true });
|
|
1344
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
1345
|
-
printf 'codex:%s\\n' "$*" >> "${logPath}"
|
|
1346
|
-
printf 'codex-pwd:%s\\n' "$(pwd)" >> "${logPath}"
|
|
1347
|
-
exit 0
|
|
1348
|
-
`);
|
|
1349
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
1350
|
-
await writeFile(join(cwd, ".profile"), "cd ..\n");
|
|
1351
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
1352
|
-
printf 'tmux:%s\\n' "$*" >> "${logPath}"
|
|
1353
|
-
case "$1" in
|
|
1354
|
-
display-message)
|
|
1355
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
1356
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
1357
|
-
else
|
|
1358
|
-
printf '0\\n'
|
|
1359
|
-
fi
|
|
1360
|
-
;;
|
|
1361
|
-
show-options)
|
|
1362
|
-
printf 'off\\n'
|
|
1363
|
-
;;
|
|
1364
|
-
set-option|kill-session)
|
|
1365
|
-
;;
|
|
1366
|
-
esac
|
|
1367
|
-
exit 0
|
|
1368
|
-
`);
|
|
1369
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
1370
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", cwd, buildTmuxPaneCommand("codex", ["--dangerously-bypass-approvals-and-sandbox"], "/bin/sh"), "'node' '/tmp/rcs.js' 'hud' '--watch'", null);
|
|
1371
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
1372
|
-
assert.equal(typeof leaderCmd, "string");
|
|
1373
|
-
(await import("node:child_process")).execFileSync("/bin/sh", ["-c", leaderCmd], {
|
|
1374
|
-
cwd,
|
|
1375
|
-
env: {
|
|
1376
|
-
...process.env,
|
|
1377
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
1378
|
-
HOME: cwd,
|
|
1379
|
-
},
|
|
1380
|
-
stdio: "ignore",
|
|
1381
|
-
});
|
|
1382
|
-
const log = await readFile(logPath, "utf-8");
|
|
1383
|
-
assert.match(log, /codex:--dangerously-bypass-approvals-and-sandbox/);
|
|
1384
|
-
assert.match(normalizeDarwinTmpPath(log), new RegExp(`codex-pwd:${escapeRegExp(normalizeDarwinTmpPath(cwd))}`));
|
|
1385
|
-
assert.match(log, /tmux:display-message -p #\{socket_path\}/);
|
|
1386
|
-
if (/tmux:show-options -sv extended-keys/.test(log)) {
|
|
1387
|
-
assert.match(log, /tmux:set-option -sq extended-keys always/);
|
|
1388
|
-
assert.match(log, /tmux:set-option -sq extended-keys off/);
|
|
1389
|
-
}
|
|
1390
|
-
assert.match(log, /tmux:kill-session -t rcs-demo/);
|
|
1391
|
-
}
|
|
1392
|
-
finally {
|
|
1393
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1394
|
-
}
|
|
1395
|
-
});
|
|
1396
|
-
it("detached leader command preserves the detached tmux session on signal-derived exits", async () => {
|
|
1397
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-detached-leader-signal-"));
|
|
1398
|
-
const fakeBin = join(cwd, "bin");
|
|
1399
|
-
const logPath = join(cwd, "leader.log");
|
|
1400
|
-
try {
|
|
1401
|
-
await mkdir(fakeBin, { recursive: true });
|
|
1402
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
1403
|
-
printf 'codex:%s\\n' "$*" >> "${logPath}"
|
|
1404
|
-
exit 143
|
|
1405
|
-
`);
|
|
1406
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
1407
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
1408
|
-
printf 'tmux:%s\\n' "$*" >> "${logPath}"
|
|
1409
|
-
case "$1" in
|
|
1410
|
-
display-message)
|
|
1411
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
1412
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
1413
|
-
else
|
|
1414
|
-
printf '0\\n'
|
|
1415
|
-
fi
|
|
1416
|
-
;;
|
|
1417
|
-
show-options)
|
|
1418
|
-
printf 'off\\n'
|
|
1419
|
-
;;
|
|
1420
|
-
set-option|kill-session)
|
|
1421
|
-
;;
|
|
1422
|
-
esac
|
|
1423
|
-
exit 0
|
|
1424
|
-
`);
|
|
1425
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
1426
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", cwd, buildTmuxPaneCommand("codex", ["--dangerously-bypass-approvals-and-sandbox"], "/bin/sh"), "'node' '/tmp/rcs.js' 'hud' '--watch'", null);
|
|
1427
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
1428
|
-
assert.equal(typeof leaderCmd, "string");
|
|
1429
|
-
const result = (await import("node:child_process")).spawnSync("/bin/sh", ["-c", leaderCmd], {
|
|
1430
|
-
cwd,
|
|
1431
|
-
env: {
|
|
1432
|
-
...process.env,
|
|
1433
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
1434
|
-
HOME: cwd,
|
|
1435
|
-
},
|
|
1436
|
-
encoding: "utf-8",
|
|
1437
|
-
});
|
|
1438
|
-
assert.equal(result.status, 143);
|
|
1439
|
-
const log = await readFile(logPath, "utf-8");
|
|
1440
|
-
assert.match(log, /codex:--dangerously-bypass-approvals-and-sandbox/);
|
|
1441
|
-
assert.match(log, /tmux:display-message -p #\{socket_path\}/);
|
|
1442
|
-
if (/tmux:show-options -sv extended-keys/.test(log)) {
|
|
1443
|
-
assert.match(log, /tmux:set-option -sq extended-keys always/);
|
|
1444
|
-
assert.match(log, /tmux:set-option -sq extended-keys off/);
|
|
1445
|
-
}
|
|
1446
|
-
assert.doesNotMatch(log, /tmux:kill-session -t rcs-demo/);
|
|
1447
|
-
}
|
|
1448
|
-
finally {
|
|
1449
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1450
|
-
}
|
|
1451
|
-
});
|
|
1452
|
-
it("detached leader command terminates codex child on external SIGHUP", async () => {
|
|
1453
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-detached-leader-hup-"));
|
|
1454
|
-
const fakeBin = join(cwd, "bin");
|
|
1455
|
-
const pidFile = join(cwd, "codex.pid");
|
|
1456
|
-
try {
|
|
1457
|
-
await mkdir(fakeBin, { recursive: true });
|
|
1458
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
1459
|
-
echo $$ > "${pidFile}"
|
|
1460
|
-
trap '' HUP
|
|
1461
|
-
while true; do sleep 1; done
|
|
1462
|
-
`);
|
|
1463
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
1464
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
1465
|
-
case "$1" in
|
|
1466
|
-
display-message)
|
|
1467
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
1468
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
1469
|
-
else
|
|
1470
|
-
printf '0\\n'
|
|
1471
|
-
fi
|
|
1472
|
-
;;
|
|
1473
|
-
show-options) printf 'off\\n' ;;
|
|
1474
|
-
set-option|kill-session) ;;
|
|
1475
|
-
esac
|
|
1476
|
-
exit 0
|
|
1477
|
-
`);
|
|
1478
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
1479
|
-
const steps = buildDetachedSessionBootstrapSteps("rcs-demo", cwd, buildTmuxPaneCommand("codex", [], "/bin/sh"), "'node' '/tmp/rcs.js' 'hud' '--watch'", null);
|
|
1480
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
1481
|
-
assert.equal(typeof leaderCmd, "string");
|
|
1482
|
-
const { spawn } = await import("node:child_process");
|
|
1483
|
-
const child = spawn("/bin/sh", ["-c", `exec ${leaderCmd}`], {
|
|
1484
|
-
cwd,
|
|
1485
|
-
env: {
|
|
1486
|
-
...process.env,
|
|
1487
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
1488
|
-
HOME: cwd,
|
|
1489
|
-
},
|
|
1490
|
-
stdio: "ignore",
|
|
1491
|
-
detached: true,
|
|
1492
|
-
});
|
|
1493
|
-
try {
|
|
1494
|
-
for (let i = 0; i < 50; i += 1) {
|
|
1495
|
-
if (existsSync(pidFile))
|
|
1496
|
-
break;
|
|
1497
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1498
|
-
}
|
|
1499
|
-
assert.ok(existsSync(pidFile), "codex pid file not written");
|
|
1500
|
-
const codexPid = Number.parseInt((await readFile(pidFile, "utf-8")).trim(), 10);
|
|
1501
|
-
assert.ok(codexPid > 0, "codex pid must be positive");
|
|
1502
|
-
assert.doesNotThrow(() => process.kill(codexPid, 0), "codex must be alive before signal");
|
|
1503
|
-
const leaderExit = once(child, "exit");
|
|
1504
|
-
process.kill(child.pid, "SIGHUP");
|
|
1505
|
-
await Promise.race([
|
|
1506
|
-
leaderExit,
|
|
1507
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("leader did not exit after SIGHUP")), 3000)),
|
|
1508
|
-
]);
|
|
1509
|
-
assert.throws(() => process.kill(codexPid, 0), (err) => typeof err === "object" &&
|
|
1510
|
-
err !== null &&
|
|
1511
|
-
"code" in err &&
|
|
1512
|
-
err.code === "ESRCH", "codex child must be terminated after leader SIGHUP");
|
|
1513
|
-
}
|
|
1514
|
-
finally {
|
|
1515
|
-
try {
|
|
1516
|
-
process.kill(child.pid, "SIGKILL");
|
|
1517
|
-
}
|
|
1518
|
-
catch {
|
|
1519
|
-
/* already dead */
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
finally {
|
|
1524
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1525
|
-
}
|
|
1526
|
-
});
|
|
1527
|
-
it("withTmuxExtendedKeys enables tmux extended keys during codex launch and restores them afterwards", async () => {
|
|
1528
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-lease-wrapper-"));
|
|
1529
|
-
const calls = [];
|
|
1530
|
-
const result = withTmuxExtendedKeys(cwd, () => {
|
|
1531
|
-
calls.push(["run"]);
|
|
1532
|
-
return "ok";
|
|
1533
|
-
}, (_file, args) => {
|
|
1534
|
-
calls.push([...args]);
|
|
1535
|
-
if (args[0] === "show-options")
|
|
1536
|
-
return "off\n";
|
|
1537
|
-
return "";
|
|
1538
|
-
});
|
|
1539
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1540
|
-
assert.equal(result, "ok");
|
|
1541
|
-
assert.deepEqual(calls, [
|
|
1542
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1543
|
-
["show-options", "-sv", "extended-keys"],
|
|
1544
|
-
["set-option", "-sq", "extended-keys", "always"],
|
|
1545
|
-
["run"],
|
|
1546
|
-
["set-option", "-sq", "extended-keys", "off"],
|
|
1547
|
-
]);
|
|
1548
|
-
});
|
|
1549
|
-
it("acquireTmuxExtendedKeysLease can bind lease liveness to a long-lived owner pid", async () => {
|
|
1550
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-lease-owner-pid-"));
|
|
1551
|
-
try {
|
|
1552
|
-
const execStub = (_file, args) => {
|
|
1553
|
-
if (args[0] === "display-message")
|
|
1554
|
-
return "/tmp/tmux-owner-pid.sock\n";
|
|
1555
|
-
if (args[0] === "show-options")
|
|
1556
|
-
return "off\n";
|
|
1557
|
-
return "";
|
|
1558
|
-
};
|
|
1559
|
-
const lease = acquireTmuxExtendedKeysLease(cwd, execStub, 12345);
|
|
1560
|
-
assert.match(lease ?? "", /^\/tmp\/tmux-owner-pid\.sock\t12345-/);
|
|
1561
|
-
if (lease)
|
|
1562
|
-
releaseTmuxExtendedKeysLease(cwd, lease, execStub);
|
|
1563
|
-
}
|
|
1564
|
-
finally {
|
|
1565
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1566
|
-
}
|
|
1567
|
-
});
|
|
1568
|
-
it("overlapping tmux extended-keys leases restore only after the last holder exits", async () => {
|
|
1569
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-lease-overlap-"));
|
|
1570
|
-
const calls = [];
|
|
1571
|
-
const execStub = (_file, args) => {
|
|
1572
|
-
calls.push([...args]);
|
|
1573
|
-
if (args[0] === "display-message")
|
|
1574
|
-
return "/tmp/tmux-test.sock\n";
|
|
1575
|
-
if (args[0] === "show-options")
|
|
1576
|
-
return "off\n";
|
|
1577
|
-
return "";
|
|
1578
|
-
};
|
|
1579
|
-
const leaseA = acquireTmuxExtendedKeysLease(cwd, execStub);
|
|
1580
|
-
const leaseB = acquireTmuxExtendedKeysLease(cwd, execStub);
|
|
1581
|
-
assert.equal(typeof leaseA, "string");
|
|
1582
|
-
assert.equal(typeof leaseB, "string");
|
|
1583
|
-
releaseTmuxExtendedKeysLease(cwd, leaseA, execStub);
|
|
1584
|
-
const leaseDir = join(cwd, ".rcs", "state", "tmux-extended-keys");
|
|
1585
|
-
const leaseFilesAfterFirstRelease = await readFile(join(leaseDir, "tmp-tmux-test-sock.json"), "utf-8");
|
|
1586
|
-
assert.match(leaseFilesAfterFirstRelease, /holders/);
|
|
1587
|
-
releaseTmuxExtendedKeysLease(cwd, leaseB, execStub);
|
|
1588
|
-
await assert.rejects(readFile(join(leaseDir, "tmp-tmux-test-sock.json"), "utf-8"), /ENOENT/);
|
|
1589
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1590
|
-
assert.deepEqual(calls, [
|
|
1591
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1592
|
-
["show-options", "-sv", "extended-keys"],
|
|
1593
|
-
["set-option", "-sq", "extended-keys", "always"],
|
|
1594
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1595
|
-
["set-option", "-sq", "extended-keys", "off"],
|
|
1596
|
-
]);
|
|
1597
|
-
});
|
|
1598
|
-
it("withTmuxExtendedKeys degrades cleanly when tmux option probing fails", async () => {
|
|
1599
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-lease-fail-"));
|
|
1600
|
-
const calls = [];
|
|
1601
|
-
const result = withTmuxExtendedKeys(cwd, () => {
|
|
1602
|
-
calls.push(["run"]);
|
|
1603
|
-
return "ok";
|
|
1604
|
-
}, (_file, args) => {
|
|
1605
|
-
calls.push([...args]);
|
|
1606
|
-
if (args[0] === "show-options")
|
|
1607
|
-
throw new Error("tmux unavailable");
|
|
1608
|
-
return "";
|
|
1609
|
-
});
|
|
1610
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1611
|
-
assert.equal(result, "ok");
|
|
1612
|
-
assert.deepEqual(calls, [
|
|
1613
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1614
|
-
["show-options", "-sv", "extended-keys"],
|
|
1615
|
-
["run"],
|
|
1616
|
-
]);
|
|
1617
|
-
});
|
|
1618
|
-
it("withTmuxExtendedKeys ignores tmux versions without the extended-keys option", async () => {
|
|
1619
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-lease-unsupported-"));
|
|
1620
|
-
const calls = [];
|
|
1621
|
-
const stderrWrite = mock.method(process.stderr, "write", () => true);
|
|
1622
|
-
try {
|
|
1623
|
-
const result = withTmuxExtendedKeys(cwd, () => {
|
|
1624
|
-
calls.push(["run"]);
|
|
1625
|
-
return "ok";
|
|
1626
|
-
}, (_file, args) => {
|
|
1627
|
-
calls.push([...args]);
|
|
1628
|
-
if (args[0] === "display-message")
|
|
1629
|
-
return "/tmp/tmux-3-0.sock\n";
|
|
1630
|
-
if (args[0] === "show-options") {
|
|
1631
|
-
throw Object.assign(new Error("Command failed: tmux show-options -sv extended-keys"), {
|
|
1632
|
-
status: 1,
|
|
1633
|
-
stderr: Buffer.from("invalid option: extended-keys\n"),
|
|
1634
|
-
stdout: Buffer.from(""),
|
|
1635
|
-
});
|
|
1636
|
-
}
|
|
1637
|
-
return "";
|
|
1638
|
-
});
|
|
1639
|
-
assert.equal(result, "ok");
|
|
1640
|
-
assert.deepEqual(calls, [
|
|
1641
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1642
|
-
["show-options", "-sv", "extended-keys"],
|
|
1643
|
-
["run"],
|
|
1644
|
-
]);
|
|
1645
|
-
assert.equal(stderrWrite.mock.callCount(), 0);
|
|
1646
|
-
}
|
|
1647
|
-
finally {
|
|
1648
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1649
|
-
}
|
|
1650
|
-
});
|
|
1651
|
-
it("acquireTmuxExtendedKeysLease returns no lease when extended-keys is unsupported", async () => {
|
|
1652
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-acquire-unsupported-"));
|
|
1653
|
-
const calls = [];
|
|
1654
|
-
const stderrWrite = mock.method(process.stderr, "write", () => true);
|
|
1655
|
-
try {
|
|
1656
|
-
const lease = acquireTmuxExtendedKeysLease(cwd, (_file, args) => {
|
|
1657
|
-
calls.push([...args]);
|
|
1658
|
-
if (args[0] === "display-message")
|
|
1659
|
-
return "/tmp/tmux-3-0.sock\n";
|
|
1660
|
-
if (args[0] === "show-options") {
|
|
1661
|
-
throw Object.assign(new Error("Command failed: tmux show-options -sv extended-keys"), {
|
|
1662
|
-
status: 1,
|
|
1663
|
-
stderr: Buffer.from("invalid option: extended-keys\n"),
|
|
1664
|
-
stdout: Buffer.from(""),
|
|
1665
|
-
});
|
|
1666
|
-
}
|
|
1667
|
-
return "";
|
|
1668
|
-
});
|
|
1669
|
-
assert.equal(lease, null);
|
|
1670
|
-
assert.deepEqual(calls, [
|
|
1671
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1672
|
-
["show-options", "-sv", "extended-keys"],
|
|
1673
|
-
]);
|
|
1674
|
-
assert.equal(stderrWrite.mock.callCount(), 0);
|
|
1675
|
-
}
|
|
1676
|
-
finally {
|
|
1677
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1678
|
-
}
|
|
1679
|
-
});
|
|
1680
|
-
it("reapStaleNotifyFallbackWatcher skips kill when process identity does not match a watcher", async () => {
|
|
1681
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-reap-pid-identity-"));
|
|
1682
|
-
const pidPath = join(cwd, "watcher.pid");
|
|
1683
|
-
await writeFile(pidPath, JSON.stringify({ pid: 99999, started_at: new Date().toISOString() }));
|
|
1684
|
-
const killed = [];
|
|
1685
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
1686
|
-
isWatcherProcess: () => false,
|
|
1687
|
-
tryKillPid: (pid) => { killed.push(pid); return true; },
|
|
1688
|
-
});
|
|
1689
|
-
assert.equal(killed.length, 0, "should not kill a process that is not a watcher");
|
|
1690
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1691
|
-
});
|
|
1692
|
-
it("reapStaleNotifyFallbackWatcher sends SIGTERM only after confirming watcher identity", async () => {
|
|
1693
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-reap-pid-confirmed-"));
|
|
1694
|
-
const pidPath = join(cwd, "watcher.pid");
|
|
1695
|
-
await writeFile(pidPath, JSON.stringify({ pid: 12345, started_at: new Date().toISOString() }));
|
|
1696
|
-
const killed = [];
|
|
1697
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
1698
|
-
isWatcherProcess: () => true,
|
|
1699
|
-
tryKillPid: (pid) => { killed.push(pid); return true; },
|
|
1700
|
-
});
|
|
1701
|
-
assert.deepEqual(killed, [12345], "should SIGTERM the verified watcher process");
|
|
1702
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1703
|
-
});
|
|
1704
|
-
it("reuses legacy plain-text PID parsing without widening stale reap semantics across PID reuse", async () => {
|
|
1705
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-reap-legacy-pid-"));
|
|
1706
|
-
try {
|
|
1707
|
-
const pidPath = join(cwd, "watcher.pid");
|
|
1708
|
-
await writeFile(pidPath, "12345\n", "utf-8");
|
|
1709
|
-
const observed = [];
|
|
1710
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
1711
|
-
isWatcherProcess(pid) {
|
|
1712
|
-
observed.push(pid);
|
|
1713
|
-
return false;
|
|
1714
|
-
},
|
|
1715
|
-
tryKillPid: (pid) => {
|
|
1716
|
-
observed.push(pid);
|
|
1717
|
-
return true;
|
|
1718
|
-
},
|
|
1719
|
-
});
|
|
1720
|
-
assert.deepEqual(observed, [12345], "legacy plain-text PID files should still identity-check reused PIDs before any kill");
|
|
1721
|
-
}
|
|
1722
|
-
finally {
|
|
1723
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1724
|
-
}
|
|
1725
|
-
});
|
|
1726
|
-
it("reaps watcher-record PIDs only after the record path confirms watcher identity across PID reuse", async () => {
|
|
1727
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-reap-record-pid-"));
|
|
1728
|
-
try {
|
|
1729
|
-
const pidPath = join(cwd, "watcher.pid");
|
|
1730
|
-
await writeFile(pidPath, JSON.stringify({ pid: 54321, started_at: "2026-04-05T00:00:00.000Z" }), "utf-8");
|
|
1731
|
-
const observed = [];
|
|
1732
|
-
await reapStaleNotifyFallbackWatcher(pidPath, {
|
|
1733
|
-
isWatcherProcess(pid) {
|
|
1734
|
-
observed.push({ step: "identity", pid });
|
|
1735
|
-
return true;
|
|
1736
|
-
},
|
|
1737
|
-
tryKillPid(pid) {
|
|
1738
|
-
observed.push({ step: "kill", pid });
|
|
1739
|
-
return true;
|
|
1740
|
-
},
|
|
1741
|
-
});
|
|
1742
|
-
assert.deepEqual(observed, [
|
|
1743
|
-
{ step: "identity", pid: 54321 },
|
|
1744
|
-
{ step: "kill", pid: 54321 },
|
|
1745
|
-
]);
|
|
1746
|
-
}
|
|
1747
|
-
finally {
|
|
1748
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1749
|
-
}
|
|
1750
|
-
});
|
|
1751
|
-
it("acquireTmuxExtendedKeysLease recovers from a stale lock left by a crashed process", async () => {
|
|
1752
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-stale-lock-"));
|
|
1753
|
-
const leaseDir = join(cwd, ".rcs", "state", "tmux-extended-keys");
|
|
1754
|
-
const lockDir = join(leaseDir, "tmp-stale-sock.lock");
|
|
1755
|
-
mkdirSync(lockDir, { recursive: true });
|
|
1756
|
-
const staleTime = new Date(Date.now() - 60_000);
|
|
1757
|
-
utimesSync(lockDir, staleTime, staleTime);
|
|
1758
|
-
const calls = [];
|
|
1759
|
-
const execStub = (_file, args) => {
|
|
1760
|
-
calls.push([...args]);
|
|
1761
|
-
if (args[0] === "display-message")
|
|
1762
|
-
return "/tmp/stale-sock";
|
|
1763
|
-
return "";
|
|
1764
|
-
};
|
|
1765
|
-
const lease = acquireTmuxExtendedKeysLease(cwd, execStub);
|
|
1766
|
-
assert.equal(typeof lease, "string", "lease should succeed after stale lock recovery");
|
|
1767
|
-
assert.ok(!existsSync(lockDir), "stale lock directory should be removed");
|
|
1768
|
-
if (lease)
|
|
1769
|
-
releaseTmuxExtendedKeysLease(cwd, lease, execStub);
|
|
1770
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1771
|
-
});
|
|
1772
|
-
it("acquireTmuxExtendedKeysLease reaps dead holders and restores before taking a new lease", async () => {
|
|
1773
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-dead-holder-acquire-"));
|
|
1774
|
-
try {
|
|
1775
|
-
const leaseDir = join(cwd, ".rcs", "state", "tmux-extended-keys");
|
|
1776
|
-
const leasePath = join(leaseDir, "tmp-stale-holder-sock.json");
|
|
1777
|
-
await mkdir(leaseDir, { recursive: true });
|
|
1778
|
-
await writeFile(leasePath, JSON.stringify({
|
|
1779
|
-
originalMode: "off",
|
|
1780
|
-
holders: ["2147483647-stale-holder"],
|
|
1781
|
-
}), "utf-8");
|
|
1782
|
-
const calls = [];
|
|
1783
|
-
const execStub = (_file, args) => {
|
|
1784
|
-
calls.push([...args]);
|
|
1785
|
-
if (args[0] === "display-message")
|
|
1786
|
-
return "/tmp/stale-holder.sock\n";
|
|
1787
|
-
if (args[0] === "show-options")
|
|
1788
|
-
return "off\n";
|
|
1789
|
-
return "";
|
|
1790
|
-
};
|
|
1791
|
-
const lease = acquireTmuxExtendedKeysLease(cwd, execStub);
|
|
1792
|
-
assert.equal(typeof lease, "string");
|
|
1793
|
-
const persisted = JSON.parse(await readFile(leasePath, "utf-8"));
|
|
1794
|
-
assert.equal(persisted.holders.length, 1);
|
|
1795
|
-
const holder = persisted.holders[0];
|
|
1796
|
-
const holderId = typeof holder === "string" ? holder : holder?.id ?? "";
|
|
1797
|
-
assert.match(holderId, new RegExp(`^${process.pid}-`));
|
|
1798
|
-
assert.equal(typeof holder === "object" ? holder.pid : process.pid, process.pid);
|
|
1799
|
-
assert.doesNotMatch(JSON.stringify(persisted), /2147483647-stale-holder/);
|
|
1800
|
-
if (lease)
|
|
1801
|
-
releaseTmuxExtendedKeysLease(cwd, lease, execStub);
|
|
1802
|
-
assert.deepEqual(calls, [
|
|
1803
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1804
|
-
["set-option", "-sq", "extended-keys", "off"],
|
|
1805
|
-
["show-options", "-sv", "extended-keys"],
|
|
1806
|
-
["set-option", "-sq", "extended-keys", "always"],
|
|
1807
|
-
["set-option", "-sq", "extended-keys", "off"],
|
|
1808
|
-
]);
|
|
1809
|
-
}
|
|
1810
|
-
finally {
|
|
1811
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1812
|
-
}
|
|
1813
|
-
});
|
|
1814
|
-
it("releaseTmuxExtendedKeysLease preserves live legacy string holders", async () => {
|
|
1815
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-live-legacy-holder-"));
|
|
1816
|
-
try {
|
|
1817
|
-
const leaseDir = join(cwd, ".rcs", "state", "tmux-extended-keys");
|
|
1818
|
-
const leasePath = join(leaseDir, "tmp-live-legacy-sock.json");
|
|
1819
|
-
const legacyHolder = `${process.pid}-legacy-holder`;
|
|
1820
|
-
await mkdir(leaseDir, { recursive: true });
|
|
1821
|
-
await writeFile(leasePath, JSON.stringify({
|
|
1822
|
-
originalMode: "off",
|
|
1823
|
-
holders: [legacyHolder],
|
|
1824
|
-
}), "utf-8");
|
|
1825
|
-
const calls = [];
|
|
1826
|
-
const execStub = (_file, args) => {
|
|
1827
|
-
calls.push([...args]);
|
|
1828
|
-
return "";
|
|
1829
|
-
};
|
|
1830
|
-
releaseTmuxExtendedKeysLease(cwd, "/tmp/live-legacy.sock\tmissing-holder", execStub);
|
|
1831
|
-
const persisted = JSON.parse(await readFile(leasePath, "utf-8"));
|
|
1832
|
-
assert.deepEqual(persisted.holders, [legacyHolder]);
|
|
1833
|
-
assert.deepEqual(calls, [], "live legacy string holders should not be restored away");
|
|
1834
|
-
}
|
|
1835
|
-
finally {
|
|
1836
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1837
|
-
}
|
|
1838
|
-
});
|
|
1839
|
-
it("acquireTmuxExtendedKeysLease reaps Linux PID-reuse identity mismatches", async () => {
|
|
1840
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-pid-reuse-holder-"));
|
|
1841
|
-
try {
|
|
1842
|
-
const leaseDir = join(cwd, ".rcs", "state", "tmux-extended-keys");
|
|
1843
|
-
const leasePath = join(leaseDir, "tmp-pid-reuse-sock.json");
|
|
1844
|
-
await mkdir(leaseDir, { recursive: true });
|
|
1845
|
-
await writeFile(leasePath, JSON.stringify({
|
|
1846
|
-
originalMode: "off",
|
|
1847
|
-
holders: [{
|
|
1848
|
-
id: `${process.pid}-reused-holder`,
|
|
1849
|
-
pid: process.pid,
|
|
1850
|
-
platform: "linux",
|
|
1851
|
-
linuxStartTicks: -1,
|
|
1852
|
-
}],
|
|
1853
|
-
}), "utf-8");
|
|
1854
|
-
const calls = [];
|
|
1855
|
-
const execStub = (_file, args) => {
|
|
1856
|
-
calls.push([...args]);
|
|
1857
|
-
if (args[0] === "display-message")
|
|
1858
|
-
return "/tmp/pid-reuse.sock\n";
|
|
1859
|
-
if (args[0] === "show-options")
|
|
1860
|
-
return "off\n";
|
|
1861
|
-
return "";
|
|
1862
|
-
};
|
|
1863
|
-
const lease = acquireTmuxExtendedKeysLease(cwd, execStub);
|
|
1864
|
-
assert.equal(typeof lease, "string");
|
|
1865
|
-
const persisted = JSON.parse(await readFile(leasePath, "utf-8"));
|
|
1866
|
-
const holderIds = persisted.holders.map((holder) => typeof holder === "string" ? holder : holder.id ?? "");
|
|
1867
|
-
if (process.platform === "linux") {
|
|
1868
|
-
assert.equal(persisted.holders.length, 1);
|
|
1869
|
-
assert.match(holderIds[0] ?? "", new RegExp(`^${process.pid}-`));
|
|
1870
|
-
assert.doesNotMatch(JSON.stringify(persisted), /reused-holder/);
|
|
1871
|
-
assert.deepEqual(calls, [
|
|
1872
|
-
["display-message", "-p", "#{socket_path}"],
|
|
1873
|
-
["set-option", "-sq", "extended-keys", "off"],
|
|
1874
|
-
["show-options", "-sv", "extended-keys"],
|
|
1875
|
-
["set-option", "-sq", "extended-keys", "always"],
|
|
1876
|
-
]);
|
|
1877
|
-
}
|
|
1878
|
-
else {
|
|
1879
|
-
assert.ok(holderIds.includes(`${process.pid}-reused-holder`));
|
|
1880
|
-
}
|
|
1881
|
-
if (lease)
|
|
1882
|
-
releaseTmuxExtendedKeysLease(cwd, lease, execStub);
|
|
1883
|
-
}
|
|
1884
|
-
finally {
|
|
1885
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1886
|
-
}
|
|
1887
|
-
});
|
|
1888
|
-
it("releaseTmuxExtendedKeysLease restores when all remaining holders are dead", async () => {
|
|
1889
|
-
const cwd = await mkdtemp(join(tmpdir(), "rcs-tmux-dead-holder-release-"));
|
|
1890
|
-
try {
|
|
1891
|
-
const leaseDir = join(cwd, ".rcs", "state", "tmux-extended-keys");
|
|
1892
|
-
const leasePath = join(leaseDir, "tmp-dead-release-sock.json");
|
|
1893
|
-
await mkdir(leaseDir, { recursive: true });
|
|
1894
|
-
await writeFile(leasePath, JSON.stringify({
|
|
1895
|
-
originalMode: "off",
|
|
1896
|
-
holders: ["2147483647-stale-holder"],
|
|
1897
|
-
}), "utf-8");
|
|
1898
|
-
const calls = [];
|
|
1899
|
-
const execStub = (_file, args) => {
|
|
1900
|
-
calls.push([...args]);
|
|
1901
|
-
return "";
|
|
1902
|
-
};
|
|
1903
|
-
releaseTmuxExtendedKeysLease(cwd, "/tmp/dead-release.sock\tmissing-holder", execStub);
|
|
1904
|
-
assert.ok(!existsSync(leasePath), "stale-only lease file should be removed");
|
|
1905
|
-
assert.deepEqual(calls, [["set-option", "-sq", "extended-keys", "off"]]);
|
|
1906
|
-
}
|
|
1907
|
-
finally {
|
|
1908
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1909
|
-
}
|
|
1910
|
-
});
|
|
1911
|
-
it("buildDetachedSessionFinalizeSteps keeps schedule after split-capture and before attach", () => {
|
|
1912
|
-
const steps = buildDetachedSessionFinalizeSteps("rcs-demo", "%12", "3", true);
|
|
1913
|
-
const names = steps.map((step) => step.name);
|
|
1914
|
-
const attachedIndex = names.indexOf("register-client-attached-reconcile");
|
|
1915
|
-
const scheduleIndex = names.indexOf("schedule-delayed-resize");
|
|
1916
|
-
const attachIndex = names.indexOf("attach-session");
|
|
1917
|
-
assert.equal(attachedIndex >= 0, true);
|
|
1918
|
-
assert.equal(scheduleIndex > attachedIndex, true);
|
|
1919
|
-
assert.equal(scheduleIndex >= 0, true);
|
|
1920
|
-
assert.equal(attachIndex > scheduleIndex, true);
|
|
1921
|
-
assert.equal(names.includes("register-resize-hook"), true);
|
|
1922
|
-
assert.equal(names.includes("reconcile-hud-resize"), true);
|
|
1923
|
-
});
|
|
1924
|
-
it("buildDetachedSessionFinalizeSteps uses quiet best-effort tmux resize commands", () => {
|
|
1925
|
-
const steps = buildDetachedSessionFinalizeSteps("rcs-demo", "%12", "3", false);
|
|
1926
|
-
const registerHook = steps.find((step) => step.name === "register-resize-hook");
|
|
1927
|
-
const schedule = steps.find((step) => step.name === "schedule-delayed-resize");
|
|
1928
|
-
const reconcile = steps.find((step) => step.name === "reconcile-hud-resize");
|
|
1929
|
-
assert.match(registerHook?.args[4] ?? "", />\/dev\/null 2>&1 \|\| true/);
|
|
1930
|
-
assert.match(registerHook?.args[4] ?? "", new RegExp(`-y ${HUD_TMUX_HEIGHT_LINES}\\b`));
|
|
1931
|
-
assert.match(schedule?.args[2] ?? "", />\/dev\/null 2>&1 \|\| true/);
|
|
1932
|
-
assert.match(schedule?.args[2] ?? "", new RegExp(`-y ${HUD_TMUX_HEIGHT_LINES}\\b`));
|
|
1933
|
-
assert.match((reconcile?.args ?? []).join(" "), />\/dev\/null 2>&1 \|\| true/);
|
|
1934
|
-
assert.match((reconcile?.args ?? []).join(" "), new RegExp(`-y ${HUD_TMUX_HEIGHT_LINES}\\b`));
|
|
1935
|
-
});
|
|
1936
|
-
it("buildDetachedSessionFinalizeSteps skips detached resize hooks on native Windows", () => {
|
|
1937
|
-
const steps = buildDetachedSessionFinalizeSteps("rcs-demo", "%12", "3", true, true);
|
|
1938
|
-
assert.deepEqual(steps.map((step) => step.name), ["set-mouse", "sanitize-copy-mode-style", "attach-session"]);
|
|
1939
|
-
});
|
|
1940
|
-
it("buildDetachedSessionFinalizeSteps sanitizes copy-mode styling before attach when mouse mode is enabled", () => {
|
|
1941
|
-
const steps = buildDetachedSessionFinalizeSteps("rcs-demo", "%12", "3", true);
|
|
1942
|
-
assert.equal(steps.findIndex((step) => step.name === "sanitize-copy-mode-style")
|
|
1943
|
-
> steps.findIndex((step) => step.name === "set-mouse"), true);
|
|
1944
|
-
assert.equal(steps.findIndex((step) => step.name === "attach-session")
|
|
1945
|
-
> steps.findIndex((step) => step.name === "sanitize-copy-mode-style"), true);
|
|
1946
|
-
});
|
|
1947
|
-
it("buildDetachedSessionFinalizeSteps never appends server-global terminal-overrides", () => {
|
|
1948
|
-
const steps = buildDetachedSessionFinalizeSteps("rcs-demo", "%12", "3", true);
|
|
1949
|
-
assert.equal(steps.some((step) => step.name === "set-wsl-xt"), false);
|
|
1950
|
-
assert.equal(steps.some((step) => step.args.includes("terminal-overrides")), false);
|
|
1951
|
-
});
|
|
1952
|
-
it("buildDetachedSessionRollbackSteps unregisters hooks before killing session", () => {
|
|
1953
|
-
const steps = buildDetachedSessionRollbackSteps("rcs-demo", "rcs-demo:0", "rcs_resize_launch_demo_0_12", "rcs_attached_launch_demo_0_12");
|
|
1954
|
-
assert.deepEqual(steps.map((step) => step.name), [
|
|
1955
|
-
"unregister-client-attached-reconcile",
|
|
1956
|
-
"unregister-resize-hook",
|
|
1957
|
-
"kill-session",
|
|
1958
|
-
]);
|
|
1959
|
-
assert.equal(steps[0]?.args[0], "set-hook");
|
|
1960
|
-
assert.equal(steps[0]?.args[1], "-u");
|
|
1961
|
-
assert.equal(steps[0]?.args[2], "-t");
|
|
1962
|
-
assert.equal(steps[0]?.args[3], "rcs-demo:0");
|
|
1963
|
-
assert.match(steps[0]?.args[4] ?? "", /^client-attached\[\d+\]$/);
|
|
1964
|
-
assert.match(steps[1]?.args[4] ?? "", /^client-resized\[\d+\]$/);
|
|
1965
|
-
assert.deepEqual(steps[2]?.args, ["kill-session", "-t", "rcs-demo"]);
|
|
1966
|
-
});
|
|
1967
|
-
it("buildDetachedSessionRollbackSteps only kills session when no hook metadata exists", () => {
|
|
1968
|
-
const steps = buildDetachedSessionRollbackSteps("rcs-demo", null, null, null);
|
|
1969
|
-
assert.deepEqual(steps.map((step) => step.name), ["kill-session"]);
|
|
1970
|
-
});
|
|
1971
|
-
});
|
|
1972
|
-
describe("buildTmuxShellCommand", () => {
|
|
1973
|
-
it("preserves quoted config values for tmux shell-command execution", () => {
|
|
1974
|
-
assert.equal(buildTmuxShellCommand("codex", [
|
|
1975
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
1976
|
-
"-c",
|
|
1977
|
-
'model_reasoning_effort="xhigh"',
|
|
1978
|
-
]), `'codex' '--dangerously-bypass-approvals-and-sandbox' '-c' 'model_reasoning_effort="xhigh"'`);
|
|
1979
|
-
});
|
|
1980
|
-
});
|
|
1981
|
-
describe("buildTmuxPaneCommand", () => {
|
|
1982
|
-
it("wraps command with zsh profile sourcing while preserving tmux cwd", () => {
|
|
1983
|
-
const result = buildTmuxPaneCommand("codex", ["--model", "gpt-5"], "/usr/bin/zsh");
|
|
1984
|
-
assert.ok(result.startsWith("'/usr/bin/zsh' -c "), "should start with zsh non-login shell to preserve tmux cwd");
|
|
1985
|
-
assert.ok(!result.includes(" -lc "), "should not use a login shell");
|
|
1986
|
-
assert.ok(result.includes("source ~/.zshrc"), "should source .zshrc");
|
|
1987
|
-
assert.ok(result.includes("exec "), "should exec the command");
|
|
1988
|
-
});
|
|
1989
|
-
it("keeps Homebrew zsh instead of downgrading to /bin/sh", () => {
|
|
1990
|
-
const result = buildTmuxPaneCommand("codex", ["--model", "gpt-5"], "/opt/homebrew/bin/zsh");
|
|
1991
|
-
assert.ok(result.startsWith("'/opt/homebrew/bin/zsh' -c "), "should preserve Homebrew zsh when SHELL points to it");
|
|
1992
|
-
assert.ok(!result.startsWith("'/bin/sh' -c "), "should not fall back to /bin/sh for supported Homebrew zsh");
|
|
1993
|
-
assert.ok(result.includes("source ~/.zshrc"), "should source .zshrc");
|
|
1994
|
-
});
|
|
1995
|
-
it("keeps MacPorts zsh instead of downgrading to /bin/sh", () => {
|
|
1996
|
-
const result = buildTmuxPaneCommand("codex", ["--model", "gpt-5"], "/opt/local/bin/zsh");
|
|
1997
|
-
assert.ok(result.startsWith("'/opt/local/bin/zsh' -c "), "should preserve MacPorts zsh when SHELL points to it");
|
|
1998
|
-
assert.ok(!result.startsWith("'/bin/sh' -c "), "should not fall back to /bin/sh for supported MacPorts zsh");
|
|
1999
|
-
assert.ok(result.includes("source ~/.zshrc"), "should source .zshrc");
|
|
2000
|
-
});
|
|
2001
|
-
it("wraps command with bash profile sourcing while preserving tmux cwd", () => {
|
|
2002
|
-
const result = buildTmuxPaneCommand("codex", [], "/bin/bash");
|
|
2003
|
-
assert.ok(result.startsWith("'/bin/bash' -c "), "should start with bash non-login shell to preserve tmux cwd");
|
|
2004
|
-
assert.ok(!result.includes(" -lc "), "should not use a login shell");
|
|
2005
|
-
assert.ok(result.includes("source ~/.bashrc"), "should source .bashrc");
|
|
2006
|
-
assert.ok(result.includes("exec "), "should exec the command");
|
|
2007
|
-
});
|
|
2008
|
-
it("skips rc sourcing for unknown shells without using a login shell", () => {
|
|
2009
|
-
const result = buildTmuxPaneCommand("codex", [], "/bin/fish");
|
|
2010
|
-
assert.ok(result.startsWith("'/bin/fish' -c "), "should start with fish non-login shell");
|
|
2011
|
-
assert.ok(!result.includes(" -lc "), "should not use a login shell");
|
|
2012
|
-
assert.ok(!result.includes("source"), "should not source any rc file");
|
|
2013
|
-
assert.ok(result.includes("exec "), "should exec the command");
|
|
2014
|
-
});
|
|
2015
|
-
it("falls back to /bin/sh without using a login shell when shell path is empty", () => {
|
|
2016
|
-
const result = buildTmuxPaneCommand("codex", [], "");
|
|
2017
|
-
assert.ok(result.startsWith("'/bin/sh' -c "), "should fall back to /bin/sh");
|
|
2018
|
-
assert.ok(!result.includes(" -lc "), "should not use a login shell");
|
|
2019
|
-
});
|
|
2020
|
-
});
|
|
2021
|
-
describe("buildWindowsPromptCommand", () => {
|
|
2022
|
-
it("encodes detached Windows commands for safe PowerShell prompt injection", () => {
|
|
2023
|
-
const result = buildWindowsPromptCommand("codex", [
|
|
2024
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
2025
|
-
"-c",
|
|
2026
|
-
'model_reasoning_effort="high"',
|
|
2027
|
-
"it's",
|
|
2028
|
-
]);
|
|
2029
|
-
const prefix = "powershell.exe -NoLogo -NoExit -EncodedCommand ";
|
|
2030
|
-
assert.ok(result.startsWith(prefix));
|
|
2031
|
-
const payload = result.slice(prefix.length);
|
|
2032
|
-
const decoded = Buffer.from(payload, "base64").toString("utf16le");
|
|
2033
|
-
assert.equal(decoded, "$ErrorActionPreference = 'Stop'; & { & 'codex' '--dangerously-bypass-approvals-and-sandbox' '-c' 'model_reasoning_effort=\"high\"' 'it''s' }");
|
|
2034
|
-
});
|
|
2035
|
-
});
|
|
2036
|
-
describe("buildTmuxSessionName", () => {
|
|
2037
|
-
it("uses detached fallback quietly outside git repos", () => {
|
|
2038
|
-
const name = buildTmuxSessionName("/tmp/My Repo", "rcs-1770992424158-abc123");
|
|
2039
|
-
assert.equal(name, "rcs-my-repo-detached-1770992424158-abc123");
|
|
2040
|
-
});
|
|
2041
|
-
it("sanitizes invalid characters", () => {
|
|
2042
|
-
const name = buildTmuxSessionName("/tmp/@#$", "rcs-+++");
|
|
2043
|
-
assert.match(name, /^rcs-(unknown|[a-z0-9-]+)-[a-z0-9-]+-(unknown|[a-z0-9-]+)$/);
|
|
2044
|
-
assert.equal(name.includes("_"), false);
|
|
2045
|
-
assert.equal(name.includes(" "), false);
|
|
2046
|
-
});
|
|
2047
|
-
it("includes repo name when cwd is inside .rcs-worktrees", () => {
|
|
2048
|
-
const name = buildTmuxSessionName("/home/user/my-repo.rcs-worktrees/launch-feature-x", "rcs-123-abc");
|
|
2049
|
-
assert.match(name, /^rcs-my-repo-launch-feature-x-/);
|
|
2050
|
-
});
|
|
2051
|
-
it("includes repo name for detached worktree paths", () => {
|
|
2052
|
-
const name = buildTmuxSessionName("/projects/cool-project.rcs-worktrees/launch-detached", "rcs-456-def");
|
|
2053
|
-
assert.match(name, /^rcs-cool-project-launch-detached-/);
|
|
2054
|
-
});
|
|
2055
|
-
it("includes repo name when cwd is inside .rcs/worktrees", () => {
|
|
2056
|
-
const name = buildTmuxSessionName("/home/user/my-repo/.rcs/worktrees/autoresearch-demo", "rcs-789-ghi");
|
|
2057
|
-
assert.match(name, /^rcs-my-repo-autoresearch-demo-/);
|
|
2058
|
-
});
|
|
2059
|
-
});
|
|
2060
|
-
describe("buildDetachedTmuxSessionName", () => {
|
|
2061
|
-
it("reuses the RCS session id for the detached tmux session name", () => {
|
|
2062
|
-
const sessionName = buildDetachedTmuxSessionName("/tmp/My Repo", "rcs-1770992424158-abc123");
|
|
2063
|
-
assert.equal(sessionName, "rcs-my-repo-detached-1770992424158-abc123");
|
|
2064
|
-
});
|
|
2065
|
-
});
|
|
2066
|
-
describe("native Windows psmux-compatible tmux resolution", () => {
|
|
2067
|
-
it("resolveNativeSessionName uses the shared tmux-aware resolver for current session lookup", async () => {
|
|
2068
|
-
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
|
|
2069
|
-
const originalPath = process.env.PATH;
|
|
2070
|
-
const originalPathext = process.env.PATHEXT;
|
|
2071
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-psmux-native-session-"));
|
|
2072
|
-
const fakeBin = join(wd, "bin");
|
|
2073
|
-
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
|
|
2074
|
-
try {
|
|
2075
|
-
await mkdir(fakeBin, { recursive: true });
|
|
2076
|
-
await writeFile(join(fakeBin, "psmux.exe"), `#!/bin/sh
|
|
2077
|
-
if [ "$1" = "display-message" ] && [ "$2" = "-p" ] && [ "$3" = "-t" ] && [ "$4" = "%7" ] && [ "$5" = "#S" ]; then
|
|
2078
|
-
printf 'psmux-session\\n'
|
|
2079
|
-
exit 0
|
|
2080
|
-
fi
|
|
2081
|
-
printf 'unexpected:%s\\n' "$*" >&2
|
|
2082
|
-
exit 1
|
|
2083
|
-
`);
|
|
2084
|
-
await chmod(join(fakeBin, "psmux.exe"), 0o755);
|
|
2085
|
-
process.env.PATH = fakeBin;
|
|
2086
|
-
process.env.PATHEXT = ".EXE";
|
|
2087
|
-
const sessionName = resolveNativeSessionName("/tmp/repo", "rcs-abc123", {
|
|
2088
|
-
...process.env,
|
|
2089
|
-
TMUX: "1",
|
|
2090
|
-
TMUX_PANE: "%7",
|
|
2091
|
-
});
|
|
2092
|
-
assert.equal(sessionName, "psmux-session");
|
|
2093
|
-
}
|
|
2094
|
-
finally {
|
|
2095
|
-
process.env.PATH = originalPath;
|
|
2096
|
-
process.env.PATHEXT = originalPathext;
|
|
2097
|
-
if (originalPlatform)
|
|
2098
|
-
Object.defineProperty(process, "platform", originalPlatform);
|
|
2099
|
-
await rm(wd, { recursive: true, force: true });
|
|
2100
|
-
}
|
|
2101
|
-
});
|
|
2102
|
-
it("detectDetachedSessionWindowIndex uses the shared tmux-aware resolver on native Windows", async () => {
|
|
2103
|
-
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
|
|
2104
|
-
const originalPath = process.env.PATH;
|
|
2105
|
-
const originalPathext = process.env.PATHEXT;
|
|
2106
|
-
const wd = await mkdtemp(join(tmpdir(), "rcs-psmux-window-index-"));
|
|
2107
|
-
const fakeBin = join(wd, "bin");
|
|
2108
|
-
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
|
|
2109
|
-
try {
|
|
2110
|
-
await mkdir(fakeBin, { recursive: true });
|
|
2111
|
-
await writeFile(join(fakeBin, "psmux.exe"), `#!/bin/sh
|
|
2112
|
-
if [ "$1" = "display-message" ] && [ "$2" = "-p" ] && [ "$3" = "-t" ] && [ "$4" = "rcs-demo" ] && [ "$5" = "#{window_index}" ]; then
|
|
2113
|
-
printf '3\\n'
|
|
2114
|
-
exit 0
|
|
2115
|
-
fi
|
|
2116
|
-
printf 'unexpected:%s\\n' "$*" >&2
|
|
2117
|
-
exit 1
|
|
2118
|
-
`);
|
|
2119
|
-
await chmod(join(fakeBin, "psmux.exe"), 0o755);
|
|
2120
|
-
process.env.PATH = fakeBin;
|
|
2121
|
-
process.env.PATHEXT = ".EXE";
|
|
2122
|
-
const windowIndex = detectDetachedSessionWindowIndex("rcs-demo");
|
|
2123
|
-
assert.ok(windowIndex === "3" || windowIndex === null);
|
|
2124
|
-
}
|
|
2125
|
-
finally {
|
|
2126
|
-
process.env.PATH = originalPath;
|
|
2127
|
-
process.env.PATHEXT = originalPathext;
|
|
2128
|
-
if (originalPlatform)
|
|
2129
|
-
Object.defineProperty(process, "platform", originalPlatform);
|
|
2130
|
-
await rm(wd, { recursive: true, force: true });
|
|
2131
|
-
}
|
|
2132
|
-
});
|
|
2133
|
-
});
|
|
2134
|
-
describe("worktree dependency bootstrap helpers", () => {
|
|
2135
|
-
it("returns an explicit warning when reusable worktree dependencies are unavailable", () => {
|
|
2136
|
-
const result = ensureReusableNodeModules("/tmp/non-worktree", {
|
|
2137
|
-
gitRunner: () => ({ status: 1, stdout: "", stderr: "not a worktree" }),
|
|
2138
|
-
});
|
|
2139
|
-
assert.equal(result.strategy, "missing");
|
|
2140
|
-
assert.match(String(result.warning || ""), /No reusable parent-repo node_modules was found/);
|
|
2141
|
-
});
|
|
2142
|
-
});
|
|
2143
|
-
describe("team worker launch arg inheritance helpers", () => {
|
|
2144
|
-
it("collectInheritableTeamWorkerArgs extracts bypass, reasoning, and model overrides", () => {
|
|
2145
|
-
assert.deepEqual(collectInheritableTeamWorkerArgs([
|
|
2146
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
2147
|
-
"-c",
|
|
2148
|
-
'model_reasoning_effort="xhigh"',
|
|
2149
|
-
"--model",
|
|
2150
|
-
"gpt-5",
|
|
2151
|
-
]), [
|
|
2152
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
2153
|
-
"-c",
|
|
2154
|
-
'model_reasoning_effort="xhigh"',
|
|
2155
|
-
"--model",
|
|
2156
|
-
"gpt-5",
|
|
2157
|
-
]);
|
|
2158
|
-
});
|
|
2159
|
-
it("collectInheritableTeamWorkerArgs supports --model=<value> syntax", () => {
|
|
2160
|
-
assert.deepEqual(collectInheritableTeamWorkerArgs(["--model=gpt-5.3-codex"]), ["--model", "gpt-5.3-codex"]);
|
|
2161
|
-
});
|
|
2162
|
-
it("collectInheritableTeamWorkerArgs preserves only safe model_provider config overrides", () => {
|
|
2163
|
-
assert.deepEqual(collectInheritableTeamWorkerArgs([
|
|
2164
|
-
"-c",
|
|
2165
|
-
'sandbox_mode="danger-full-access"',
|
|
2166
|
-
"-c",
|
|
2167
|
-
'model_provider="cheapRouter"',
|
|
2168
|
-
"--model",
|
|
2169
|
-
"gpt-5.5",
|
|
2170
|
-
]), ["-c", 'model_provider="cheapRouter"', "--model", "gpt-5.5"]);
|
|
2171
|
-
});
|
|
2172
|
-
it("resolveTeamWorkerLaunchArgsEnv merges and normalizes with de-dupe + last reasoning/model wins", () => {
|
|
2173
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv('--dangerously-bypass-approvals-and-sandbox -c model_reasoning_effort="high" --model old-a --no-alt-screen --model=old-b', [
|
|
2174
|
-
"-c",
|
|
2175
|
-
'model_reasoning_effort="xhigh"',
|
|
2176
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
2177
|
-
"--model",
|
|
2178
|
-
"gpt-5",
|
|
2179
|
-
], true), '--no-alt-screen --dangerously-bypass-approvals-and-sandbox -c model_reasoning_effort="xhigh" --model old-b');
|
|
2180
|
-
});
|
|
2181
|
-
it("resolveTeamWorkerLaunchArgsEnv can opt out of leader inheritance", () => {
|
|
2182
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv("--no-alt-screen", [
|
|
2183
|
-
"--dangerously-bypass-approvals-and-sandbox",
|
|
2184
|
-
"-c",
|
|
2185
|
-
'model_reasoning_effort="xhigh"',
|
|
2186
|
-
], false), "--no-alt-screen");
|
|
2187
|
-
});
|
|
2188
|
-
it("resolveTeamWorkerLaunchArgsEnv uses inherited model when env model is absent", () => {
|
|
2189
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv("--no-alt-screen", ["--model=gpt-5.3-codex"], true), "--no-alt-screen --model gpt-5.3-codex");
|
|
2190
|
-
});
|
|
2191
|
-
it("resolveTeamWorkerLaunchArgsEnv uses frontier default model when env and inherited models are absent", () => {
|
|
2192
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv("--no-alt-screen", ["--dangerously-bypass-approvals-and-sandbox"], true, DEFAULT_FRONTIER_MODEL), `--no-alt-screen --dangerously-bypass-approvals-and-sandbox --model ${DEFAULT_FRONTIER_MODEL}`);
|
|
2193
|
-
});
|
|
2194
|
-
it("resolveTeamWorkerLaunchArgsEnv keeps exactly one final model with precedence env > inherited > default", () => {
|
|
2195
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv("--model env-model --model=env-model-final", ["--model", "inherited-model"], true, "fallback-model"), "--model env-model-final");
|
|
2196
|
-
});
|
|
2197
|
-
it("resolveTeamWorkerLaunchArgsEnv prefers inherited model over default when env model is absent", () => {
|
|
2198
|
-
assert.equal(resolveTeamWorkerLaunchArgsEnv("--no-alt-screen", ["--model", "inherited-model"], true, "fallback-model"), "--no-alt-screen --model inherited-model");
|
|
2199
|
-
});
|
|
2200
|
-
});
|
|
2201
|
-
describe("readTopLevelTomlString", () => {
|
|
2202
|
-
it("reads a top-level string value", () => {
|
|
2203
|
-
const value = readTopLevelTomlString('model_reasoning_effort = "high"\n[mcp_servers.test]\nmodel_reasoning_effort = "low"\n', "model_reasoning_effort");
|
|
2204
|
-
assert.equal(value, "high");
|
|
2205
|
-
});
|
|
2206
|
-
it("ignores table-local values", () => {
|
|
2207
|
-
const value = readTopLevelTomlString('[mcp_servers.test]\nmodel_reasoning_effort = "xhigh"\n', "model_reasoning_effort");
|
|
2208
|
-
assert.equal(value, null);
|
|
2209
|
-
});
|
|
2210
|
-
});
|
|
2211
|
-
describe("injectModelInstructionsBypassArgs", () => {
|
|
2212
|
-
it("appends model_instructions_file override by default", () => {
|
|
2213
|
-
const args = injectModelInstructionsBypassArgs("/tmp/my-project", ["--model", "gpt-5"], {});
|
|
2214
|
-
assert.deepEqual(args, [
|
|
2215
|
-
"--model",
|
|
2216
|
-
"gpt-5",
|
|
2217
|
-
"-c",
|
|
2218
|
-
'model_instructions_file="/tmp/my-project/AGENTS.md"',
|
|
2219
|
-
]);
|
|
2220
|
-
});
|
|
2221
|
-
it("does not append when bypass is disabled via env", () => {
|
|
2222
|
-
const args = injectModelInstructionsBypassArgs("/tmp/my-project", ["--model", "gpt-5"], { RCS_BYPASS_DEFAULT_SYSTEM_PROMPT: "0" });
|
|
2223
|
-
assert.deepEqual(args, ["--model", "gpt-5"]);
|
|
2224
|
-
});
|
|
2225
|
-
it("does not append when model_instructions_file is already set", () => {
|
|
2226
|
-
const args = injectModelInstructionsBypassArgs("/tmp/my-project", ["-c", 'model_instructions_file="/tmp/custom.md"'], {});
|
|
2227
|
-
assert.deepEqual(args, ["-c", 'model_instructions_file="/tmp/custom.md"']);
|
|
2228
|
-
});
|
|
2229
|
-
it("respects RCS_MODEL_INSTRUCTIONS_FILE env override", () => {
|
|
2230
|
-
const args = injectModelInstructionsBypassArgs("/tmp/my-project", [], {
|
|
2231
|
-
RCS_MODEL_INSTRUCTIONS_FILE: "/tmp/alt instructions.md",
|
|
2232
|
-
});
|
|
2233
|
-
assert.deepEqual(args, [
|
|
2234
|
-
"-c",
|
|
2235
|
-
'model_instructions_file="/tmp/alt instructions.md"',
|
|
2236
|
-
]);
|
|
2237
|
-
});
|
|
2238
|
-
it("uses session-scoped default model_instructions_file when provided", () => {
|
|
2239
|
-
const args = injectModelInstructionsBypassArgs("/tmp/my-project", ["--model", "gpt-5"], {}, "/tmp/my-project/.rcs/state/sessions/session-1/AGENTS.md");
|
|
2240
|
-
assert.deepEqual(args, [
|
|
2241
|
-
"--model",
|
|
2242
|
-
"gpt-5",
|
|
2243
|
-
"-c",
|
|
2244
|
-
'model_instructions_file="/tmp/my-project/.rcs/state/sessions/session-1/AGENTS.md"',
|
|
2245
|
-
]);
|
|
2246
|
-
});
|
|
2247
|
-
});
|
|
2248
|
-
describe("upsertTopLevelTomlString", () => {
|
|
2249
|
-
it("replaces an existing top-level key", () => {
|
|
2250
|
-
const updated = upsertTopLevelTomlString('model_reasoning_effort = "low"\n[tui]\nstatus_line = []\n', "model_reasoning_effort", "high");
|
|
2251
|
-
assert.match(updated, /^model_reasoning_effort = "high"$/m);
|
|
2252
|
-
assert.doesNotMatch(updated, /^model_reasoning_effort = "low"$/m);
|
|
2253
|
-
});
|
|
2254
|
-
it("inserts before the first table when key is missing", () => {
|
|
2255
|
-
const updated = upsertTopLevelTomlString("[tui]\nstatus_line = []\n", "model_reasoning_effort", "xhigh");
|
|
2256
|
-
assert.equal(updated, 'model_reasoning_effort = "xhigh"\n[tui]\nstatus_line = []\n');
|
|
2257
|
-
});
|
|
2258
|
-
});
|
|
2259
|
-
//# sourceMappingURL=index.test.js.map
|