oh-my-codex 0.17.3 → 0.18.0
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/Cargo.lock +13 -5
- package/Cargo.toml +2 -1
- package/README.md +1 -0
- package/crates/omx-api/Cargo.toml +19 -0
- package/crates/omx-api/src/lib.rs +2940 -0
- package/crates/omx-api/src/main.rs +10 -0
- package/crates/omx-api/tests/cli.rs +558 -0
- package/crates/omx-explore/src/main.rs +4 -0
- package/crates/omx-sparkshell/src/codex_bridge.rs +437 -123
- package/crates/omx-sparkshell/src/exec.rs +4 -0
- package/crates/omx-sparkshell/src/main.rs +738 -29
- package/crates/omx-sparkshell/src/prompt.rs +25 -3
- package/crates/omx-sparkshell/src/redaction.rs +241 -0
- package/crates/omx-sparkshell/tests/execution.rs +479 -238
- package/dist/cli/__tests__/api.test.d.ts +2 -0
- package/dist/cli/__tests__/api.test.d.ts.map +1 -0
- package/dist/cli/__tests__/api.test.js +175 -0
- package/dist/cli/__tests__/api.test.js.map +1 -0
- package/dist/cli/__tests__/ask.test.js +72 -5
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch-goal.test.js +14 -1
- package/dist/cli/__tests__/autoresearch-goal.test.js.map +1 -1
- package/dist/cli/__tests__/explore.test.js +23 -0
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +123 -5
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +76 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +4 -3
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +138 -0
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js +5 -0
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/version-sync-contract.test.js +4 -0
- package/dist/cli/__tests__/version-sync-contract.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/api.d.ts +26 -0
- package/dist/cli/api.d.ts.map +1 -0
- package/dist/cli/api.js +153 -0
- package/dist/cli/api.js.map +1 -0
- package/dist/cli/explore.d.ts +2 -0
- package/dist/cli/explore.d.ts.map +1 -1
- package/dist/cli/explore.js +43 -1
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +10 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +128 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/native-assets.d.ts +2 -1
- package/dist/cli/native-assets.d.ts.map +1 -1
- package/dist/cli/native-assets.js +1 -0
- package/dist/cli/native-assets.js.map +1 -1
- package/dist/cli/sparkshell.d.ts.map +1 -1
- package/dist/cli/sparkshell.js +20 -3
- package/dist/cli/sparkshell.js.map +1 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +90 -0
- package/dist/config/generator.js.map +1 -1
- package/dist/hooks/__tests__/best-practice-research-skill.test.d.ts +2 -0
- package/dist/hooks/__tests__/best-practice-research-skill.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/best-practice-research-skill.test.js +27 -0
- package/dist/hooks/__tests__/best-practice-research-skill.test.js.map +1 -0
- package/dist/hooks/__tests__/keyword-detector.test.js +11 -0
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +6 -0
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +4 -0
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +1 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +2 -2
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +23 -18
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +7 -6
- package/dist/hud/tmux.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +75 -1
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +3 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +71 -2
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +737 -26
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-dispatcher.test.js +183 -1
- package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +4 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/build-api.d.ts +2 -0
- package/dist/scripts/build-api.d.ts.map +1 -0
- package/dist/scripts/build-api.js +44 -0
- package/dist/scripts/build-api.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +208 -8
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +89 -24
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/notify-dispatcher.js +88 -0
- package/dist/scripts/notify-dispatcher.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +27 -9
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +26 -11
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts +1 -0
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +38 -0
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.js +27 -14
- package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
- package/dist/scripts/run-provider-advisor.js +9 -3
- package/dist/scripts/run-provider-advisor.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +1 -1
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +2 -0
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +2 -2
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +96 -19
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +34 -10
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +85 -10
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js +1 -0
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
- package/package.json +4 -3
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/skills/best-practice-research/SKILL.md +83 -0
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +1 -0
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +1 -1
- package/prompts/researcher.md +15 -10
- package/skills/best-practice-research/SKILL.md +83 -0
- package/skills/deep-interview/SKILL.md +1 -0
- package/skills/ralplan/SKILL.md +1 -1
- package/src/scripts/__tests__/codex-native-hook.test.ts +810 -4
- package/src/scripts/__tests__/notify-dispatcher.test.ts +223 -1
- package/src/scripts/__tests__/smoke-packed-install.test.ts +8 -2
- package/src/scripts/build-api.ts +48 -0
- package/src/scripts/codex-native-hook.ts +262 -10
- package/src/scripts/codex-native-pre-post.ts +103 -24
- package/src/scripts/notify-dispatcher.ts +97 -0
- package/src/scripts/notify-hook/team-dispatch.ts +27 -8
- package/src/scripts/notify-hook/team-leader-nudge.ts +25 -11
- package/src/scripts/notify-hook/team-tmux-guard.ts +42 -0
- package/src/scripts/notify-hook/team-worker-stop.ts +24 -13
- package/src/scripts/run-provider-advisor.ts +11 -3
- package/src/scripts/smoke-packed-install.ts +2 -0
- package/templates/catalog-manifest.json +7 -0
|
@@ -6,7 +6,7 @@ import { PassThrough } from 'node:stream';
|
|
|
6
6
|
import { chmod, mkdir, mkdtemp, readFile, rm, writeFile } from 'fs/promises';
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
import { tmpdir } from 'os';
|
|
9
|
-
import { buildClientAttachedReconcileHookName, assertTeamWorkerCliBinaryAvailable, buildWorkerProcessLaunchSpec, buildReconcileHudResizeArgs, buildRegisterClientAttachedReconcileArgs, buildRegisterResizeHookArgs, buildResizeHookName, buildResizeHookTarget, buildScheduleDelayedHudResizeArgs, buildUnregisterClientAttachedReconcileArgs, buildUnregisterResizeHookArgs, buildWorkerStartupCommand, buildHudPaneTarget, chooseTeamLeaderPaneId, createTeamSession, enableMouseScrolling, isMsysOrGitBash, isNativeWindows, isTmuxAvailable, restoreStandaloneHudPane, translatePathForMsys, isWsl2, isWorkerAlive, killWorker, killWorkerByPaneId, teardownWorkerPanes, listTeamSessions, resolveTeamWorkerCli, resolveTeamWorkerLaunchMode, resolveWorkerCliForSend, resolveTeamWorkerCliPlan, buildWorkerSubmitPlan, sanitizeTeamName, shouldAttemptAdaptiveRetry, sendToWorker, sendToWorkerStdin, sleepFractionalSeconds, translateWorkerLaunchArgsForCli, waitForWorkerReady, waitForWorkerReadyAsync, paneIsBootstrapping, classifyWorkerStartupInjectSafety, checkWorkerStartupInjectSafety, dismissTrustPromptIfPresent, evaluateStartupDirectTriggerSafetyCapture, mitigateCopyModeUnderlineArtifacts, } from '../tmux-session.js';
|
|
9
|
+
import { buildClientAttachedReconcileHookName, assertTeamWorkerCliBinaryAvailable, buildWorkerProcessLaunchSpec, buildReconcileHudResizeArgs, buildRegisterClientAttachedReconcileArgs, buildRegisterResizeHookArgs, buildResizeHookName, buildResizeHookTarget, buildScheduleDelayedHudResizeArgs, buildUnregisterClientAttachedReconcileArgs, buildUnregisterResizeHookArgs, buildWorkerStartupCommand, shouldSourceTeamWorkerShellRc, buildHudPaneTarget, chooseTeamLeaderPaneId, createTeamSession, enableMouseScrolling, isMsysOrGitBash, isNativeWindows, isTmuxAvailable, restoreStandaloneHudPane, translatePathForMsys, isWsl2, isWorkerAlive, killWorker, killWorkerByPaneId, teardownWorkerPanes, listTeamSessions, resolveTeamWorkerCli, resolveTeamWorkerLaunchMode, resolveWorkerCliForSend, resolveTeamWorkerCliPlan, buildWorkerSubmitPlan, sanitizeTeamName, shouldAttemptAdaptiveRetry, sendToWorker, sendToWorkerStdin, sleepFractionalSeconds, translateWorkerLaunchArgsForCli, waitForWorkerReady, waitForWorkerReadyAsync, paneIsBootstrapping, classifyWorkerStartupInjectSafety, checkWorkerStartupInjectSafety, dismissTrustPromptIfPresent, evaluateStartupDirectTriggerSafetyCapture, mitigateCopyModeUnderlineArtifacts, } from '../tmux-session.js';
|
|
10
10
|
import { HUD_RESIZE_RECONCILE_DELAY_SECONDS, HUD_TMUX_TEAM_HEIGHT_LINES } from '../../hud/constants.js';
|
|
11
11
|
import * as tmuxSessionModule from '../tmux-session.js';
|
|
12
12
|
import { OMX_ENTRY_PATH_ENV, OMX_STARTUP_CWD_ENV } from '../../utils/paths.js';
|
|
@@ -133,18 +133,19 @@ describe('HUD resize hook command builders', () => {
|
|
|
133
133
|
assert.equal(buildHudPaneTarget('%41'), '%41');
|
|
134
134
|
assert.equal(buildHudPaneTarget('41'), '%41');
|
|
135
135
|
});
|
|
136
|
-
it('buildRegisterResizeHookArgs uses window target and numeric
|
|
136
|
+
it('buildRegisterResizeHookArgs uses window target and numeric window-resized hook slot', () => {
|
|
137
137
|
const args = buildRegisterResizeHookArgs('my-session:0', 'omx_resize_team_session_0_1', '%1');
|
|
138
138
|
assert.equal(args[0], 'set-hook');
|
|
139
|
-
assert.equal(args[1], '-
|
|
140
|
-
assert.equal(args[2], '
|
|
141
|
-
assert.
|
|
142
|
-
assert.
|
|
139
|
+
assert.equal(args[1], '-w');
|
|
140
|
+
assert.equal(args[2], '-t');
|
|
141
|
+
assert.equal(args[3], 'my-session:0');
|
|
142
|
+
assert.match(args[4] ?? '', /^window-resized\[\d+\]$/);
|
|
143
|
+
assert.equal(args[5], `run-shell -b 'tmux resize-pane -t %1 -y ${HUD_TMUX_TEAM_HEIGHT_LINES} >/dev/null 2>&1 || true; sleep ${HUD_RESIZE_RECONCILE_DELAY_SECONDS}; tmux resize-pane -t %1 -y ${HUD_TMUX_TEAM_HEIGHT_LINES} >/dev/null 2>&1 || true'`);
|
|
143
144
|
});
|
|
144
145
|
it('buildUnregisterResizeHookArgs removes the exact numeric hook slot', () => {
|
|
145
146
|
const registered = buildRegisterResizeHookArgs('my-session:0', 'omx_resize_team_session_0_1', '%1');
|
|
146
147
|
const unregistered = buildUnregisterResizeHookArgs('my-session:0', 'omx_resize_team_session_0_1');
|
|
147
|
-
assert.deepEqual(unregistered, ['set-hook', '-u', '-t', 'my-session:0', registered[
|
|
148
|
+
assert.deepEqual(unregistered, ['set-hook', '-u', '-w', '-t', 'my-session:0', registered[4]]);
|
|
148
149
|
});
|
|
149
150
|
it('buildClientAttachedReconcileHookName normalizes all segments into collision-safe tokens', () => {
|
|
150
151
|
const name = buildClientAttachedReconcileHookName('Team A', 'Session:Main', '0', '%12');
|
|
@@ -169,7 +170,7 @@ describe('HUD resize hook command builders', () => {
|
|
|
169
170
|
const longName = 'omx_resize_' + 'a'.repeat(200);
|
|
170
171
|
const resizeArgs = buildRegisterResizeHookArgs('sess:0', longName, '%1');
|
|
171
172
|
const attachedArgs = buildRegisterClientAttachedReconcileArgs('sess:0', longName, '%1');
|
|
172
|
-
const resizeSlot = resizeArgs[
|
|
173
|
+
const resizeSlot = resizeArgs[4] ?? '';
|
|
173
174
|
const attachedSlot = attachedArgs[3] ?? '';
|
|
174
175
|
const resizeIndex = Number((resizeSlot.match(/\[(\d+)\]/) ?? [])[1]);
|
|
175
176
|
const attachedIndex = Number((attachedSlot.match(/\[(\d+)\]/) ?? [])[1]);
|
|
@@ -182,7 +183,7 @@ describe('HUD resize hook command builders', () => {
|
|
|
182
183
|
const name = 'omx_resize_team_session_0_1';
|
|
183
184
|
const a = buildRegisterResizeHookArgs('s:0', name, '%1');
|
|
184
185
|
const b = buildRegisterResizeHookArgs('s:0', name, '%1');
|
|
185
|
-
assert.equal(a[
|
|
186
|
+
assert.equal(a[4], b[4]);
|
|
186
187
|
const c = buildRegisterClientAttachedReconcileArgs('s:0', name, '%1');
|
|
187
188
|
const d = buildRegisterClientAttachedReconcileArgs('s:0', name, '%1');
|
|
188
189
|
assert.equal(c[3], d[3]);
|
|
@@ -209,8 +210,8 @@ describe('HUD resize hook command builders', () => {
|
|
|
209
210
|
const resizeArgs = buildRegisterResizeHookArgs('my-session:0', 'omx_resize_team_session_0_1', '%1');
|
|
210
211
|
const delayedArgs = buildScheduleDelayedHudResizeArgs('%1');
|
|
211
212
|
const reconcileArgs = buildReconcileHudResizeArgs('%1');
|
|
212
|
-
assert.match(resizeArgs[
|
|
213
|
-
assert.doesNotMatch(resizeArgs[
|
|
213
|
+
assert.match(resizeArgs[5] ?? '', new RegExp(escapeRegExp(tmuxPath)));
|
|
214
|
+
assert.doesNotMatch(resizeArgs[5] ?? '', /^run-shell -b 'tmux resize-pane/);
|
|
214
215
|
assert.match(delayedArgs[2] ?? '', new RegExp(escapeRegExp(tmuxPath)));
|
|
215
216
|
assert.doesNotMatch(delayedArgs[2] ?? '', /sleep \d+; tmux resize-pane/);
|
|
216
217
|
assert.match(reconcileArgs[1] ?? '', new RegExp(escapeRegExp(tmuxPath)));
|
|
@@ -480,6 +481,51 @@ esac
|
|
|
480
481
|
assert.ok(enterCount >= 4, `expected repeated submit nudges before failing closed on stuck queued banner:\n${log}`);
|
|
481
482
|
});
|
|
482
483
|
});
|
|
484
|
+
it('does not confirm delivery while a wrapped hyphenated trigger remains as an unsent draft', async () => {
|
|
485
|
+
const trigger = 'Read .omx/state/team/team-x/workers/worker-1/inbox.md';
|
|
486
|
+
await withMockTmuxFixture('omx-tmux-codex-wrapped-trigger-draft-', (logPath) => `#!/bin/sh
|
|
487
|
+
set -eu
|
|
488
|
+
state_dir="$(dirname "${logPath}")"
|
|
489
|
+
text_sent_file="$state_dir/text-sent"
|
|
490
|
+
printf '%s\n' "$*" >> "${logPath}"
|
|
491
|
+
case "$1" in
|
|
492
|
+
capture-pane)
|
|
493
|
+
if [ -f "$text_sent_file" ]; then
|
|
494
|
+
cat <<'EOF'
|
|
495
|
+
${READY_HELPER_CAPTURE}
|
|
496
|
+
|
|
497
|
+
› Read .omx/state/team/team-x/workers/worker-
|
|
498
|
+
1/inbox.md
|
|
499
|
+
EOF
|
|
500
|
+
else
|
|
501
|
+
cat <<'EOF'
|
|
502
|
+
${READY_HELPER_CAPTURE}
|
|
503
|
+
EOF
|
|
504
|
+
fi
|
|
505
|
+
exit 0
|
|
506
|
+
;;
|
|
507
|
+
send-keys)
|
|
508
|
+
if [ "\${4:-}" = "-l" ] && [ "\${6:-}" = "${trigger}" ]; then
|
|
509
|
+
: > "$text_sent_file"
|
|
510
|
+
fi
|
|
511
|
+
exit 0
|
|
512
|
+
;;
|
|
513
|
+
*)
|
|
514
|
+
exit 0
|
|
515
|
+
;;
|
|
516
|
+
esac
|
|
517
|
+
`, async ({ logPath }) => {
|
|
518
|
+
await assert.rejects(() => sendToWorker('omx-team-x', 1, trigger), /submit_failed/);
|
|
519
|
+
const log = await readFile(logPath, 'utf-8');
|
|
520
|
+
const enterCount = (log.match(/send-keys -t omx-team-x:1 C-m/g) || []).length;
|
|
521
|
+
assert.ok(enterCount >= 4, `expected repeated submit nudges before failing on the still-visible wrapped draft:\n${log}`);
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
});
|
|
525
|
+
describe('sendToWorker adaptive retry matching', () => {
|
|
526
|
+
it('recognizes hyphen-wrapped trigger drafts as still visible', () => {
|
|
527
|
+
assert.equal(shouldAttemptAdaptiveRetry('auto', true, true, `${READY_HELPER_CAPTURE}\n\n› Read .omx/state/team/team-x/workers/worker-\n 1/inbox.md`, 'Read .omx/state/team/team-x/workers/worker-1/inbox.md'), true);
|
|
528
|
+
});
|
|
483
529
|
});
|
|
484
530
|
describe('startup direct trigger safety', () => {
|
|
485
531
|
it('classifies ready panes as safe and blocks trust, bypass, bootstrapping, and active-task captures', () => {
|
|
@@ -781,7 +827,7 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
781
827
|
delete process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
782
828
|
}
|
|
783
829
|
});
|
|
784
|
-
it('uses zsh
|
|
830
|
+
it('uses zsh without sourcing ~/.zshrc by default and keeps non-login exec semantics', () => {
|
|
785
831
|
const prevShell = process.env.SHELL;
|
|
786
832
|
process.env.SHELL = '/bin/zsh';
|
|
787
833
|
const prevBypass = process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
@@ -791,7 +837,7 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
791
837
|
assert.match(cmd, /OMX_TEAM_WORKER=alpha\/worker-2/);
|
|
792
838
|
assert.match(cmd, /'\/bin\/zsh' -c/);
|
|
793
839
|
assert.doesNotMatch(cmd, /'\/bin\/zsh' -lc\b/);
|
|
794
|
-
assert.
|
|
840
|
+
assert.doesNotMatch(cmd, /source ~\/\.zshrc/);
|
|
795
841
|
assert.match(cmd, /exec .*codex/);
|
|
796
842
|
}
|
|
797
843
|
finally {
|
|
@@ -814,7 +860,7 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
814
860
|
const cmd = withMockedExistsSync((candidate) => candidate === '/opt/homebrew/bin/zsh', () => buildWorkerStartupCommand('alpha', 2));
|
|
815
861
|
assert.match(cmd, /'\/opt\/homebrew\/bin\/zsh' -c/);
|
|
816
862
|
assert.doesNotMatch(cmd, /'\/bin\/sh' -c/);
|
|
817
|
-
assert.
|
|
863
|
+
assert.doesNotMatch(cmd, /source ~\/\.zshrc/);
|
|
818
864
|
}
|
|
819
865
|
finally {
|
|
820
866
|
if (typeof prevShell === 'string')
|
|
@@ -836,7 +882,7 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
836
882
|
const cmd = withMockedExistsSync((candidate) => candidate === '/opt/local/bin/zsh', () => buildWorkerStartupCommand('alpha', 2));
|
|
837
883
|
assert.match(cmd, /'\/opt\/local\/bin\/zsh' -c/);
|
|
838
884
|
assert.doesNotMatch(cmd, /'\/bin\/sh' -c/);
|
|
839
|
-
assert.
|
|
885
|
+
assert.doesNotMatch(cmd, /source ~\/\.zshrc/);
|
|
840
886
|
}
|
|
841
887
|
finally {
|
|
842
888
|
if (typeof prevShell === 'string')
|
|
@@ -849,14 +895,14 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
849
895
|
delete process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
850
896
|
}
|
|
851
897
|
});
|
|
852
|
-
it('
|
|
898
|
+
it('prevents issue #2358 bash rc fan-out by default and preserves launch args', () => {
|
|
853
899
|
const prevShell = process.env.SHELL;
|
|
854
900
|
process.env.SHELL = '/bin/bash';
|
|
855
901
|
const prevBypass = process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
856
902
|
process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT = '0';
|
|
857
903
|
try {
|
|
858
904
|
const cmd = buildWorkerStartupCommand('alpha', 1, ['--model', 'gpt-5']);
|
|
859
|
-
assert.
|
|
905
|
+
assert.doesNotMatch(cmd, /source ~\/\.bashrc/);
|
|
860
906
|
assert.match(cmd, /exec .*codex/);
|
|
861
907
|
assert.match(cmd, /--model/);
|
|
862
908
|
assert.match(cmd, /gpt-5/);
|
|
@@ -872,6 +918,37 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
872
918
|
delete process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
873
919
|
}
|
|
874
920
|
});
|
|
921
|
+
it('sources worker shell rc files only when explicitly opted in', () => {
|
|
922
|
+
const prevShell = process.env.SHELL;
|
|
923
|
+
const prevBypass = process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
924
|
+
const prevSourceRc = process.env.OMX_TMUX_SOURCE_SHELL_RC;
|
|
925
|
+
process.env.SHELL = '/bin/bash';
|
|
926
|
+
process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT = '0';
|
|
927
|
+
try {
|
|
928
|
+
delete process.env.OMX_TMUX_SOURCE_SHELL_RC;
|
|
929
|
+
assert.equal(shouldSourceTeamWorkerShellRc(process.env), false);
|
|
930
|
+
assert.doesNotMatch(buildWorkerStartupCommand('alpha', 1, ['--model', 'gpt-5']), /source ~\/\.bashrc/);
|
|
931
|
+
process.env.OMX_TMUX_SOURCE_SHELL_RC = '1';
|
|
932
|
+
assert.equal(shouldSourceTeamWorkerShellRc(process.env), true);
|
|
933
|
+
assert.match(buildWorkerStartupCommand('alpha', 1, ['--model', 'gpt-5']), /source ~\/\.bashrc/);
|
|
934
|
+
delete process.env.OMX_TMUX_SOURCE_SHELL_RC;
|
|
935
|
+
assert.match(buildWorkerStartupCommand('alpha', 1, ['--model', 'gpt-5'], process.cwd(), { OMX_TMUX_SOURCE_SHELL_RC: '1' }), /source ~\/\.bashrc/, 'per-worker explicit opt-in should be honored');
|
|
936
|
+
}
|
|
937
|
+
finally {
|
|
938
|
+
if (typeof prevShell === 'string')
|
|
939
|
+
process.env.SHELL = prevShell;
|
|
940
|
+
else
|
|
941
|
+
delete process.env.SHELL;
|
|
942
|
+
if (typeof prevBypass === 'string')
|
|
943
|
+
process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT = prevBypass;
|
|
944
|
+
else
|
|
945
|
+
delete process.env.OMX_BYPASS_DEFAULT_SYSTEM_PROMPT;
|
|
946
|
+
if (typeof prevSourceRc === 'string')
|
|
947
|
+
process.env.OMX_TMUX_SOURCE_SHELL_RC = prevSourceRc;
|
|
948
|
+
else
|
|
949
|
+
delete process.env.OMX_TMUX_SOURCE_SHELL_RC;
|
|
950
|
+
}
|
|
951
|
+
});
|
|
875
952
|
it('injects canonical team state env vars when provided', () => {
|
|
876
953
|
const prevShell = process.env.SHELL;
|
|
877
954
|
process.env.SHELL = '/bin/bash';
|
|
@@ -1763,7 +1840,7 @@ describe('buildWorkerStartupCommand', () => {
|
|
|
1763
1840
|
try {
|
|
1764
1841
|
const cmd = withMockedExistsSync((candidate) => candidate === '/opt/custom/fish' || candidate === '/bin/bash', () => buildWorkerStartupCommand('alpha', 1, [], process.cwd()));
|
|
1765
1842
|
assert.match(cmd, /\/bin\/bash\b/, 'must fall back to bash when zsh is unavailable');
|
|
1766
|
-
assert.
|
|
1843
|
+
assert.doesNotMatch(cmd, /\.bashrc/, 'must not source bash rc file for bash fallback by default');
|
|
1767
1844
|
assert.doesNotMatch(cmd, /fish/, 'must not launch unsupported fish shell');
|
|
1768
1845
|
}
|
|
1769
1846
|
finally {
|
|
@@ -3090,7 +3167,7 @@ esac
|
|
|
3090
3167
|
assert.equal(session.resizeHookTarget, null);
|
|
3091
3168
|
const tmuxLog = await readFile(logPath, 'utf-8');
|
|
3092
3169
|
assert.match(tmuxLog, new RegExp(`resize-pane -t %3 -y ${HUD_TMUX_TEAM_HEIGHT_LINES}`));
|
|
3093
|
-
assert.doesNotMatch(tmuxLog, /set-hook -t leader:0
|
|
3170
|
+
assert.doesNotMatch(tmuxLog, /set-hook -w -t leader:0 window-resized\[\d+\]/);
|
|
3094
3171
|
assert.doesNotMatch(tmuxLog, /set-hook -t leader:0 client-attached\[\d+\]/);
|
|
3095
3172
|
assert.doesNotMatch(tmuxLog, /run-shell -b sleep \d+; tmux resize-pane -t %3 -y \d+ >/);
|
|
3096
3173
|
assert.doesNotMatch(tmuxLog, /run-shell tmux resize-pane -t %3 -y \d+ >/);
|