oh-my-codex 0.18.7 → 0.18.9
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 +12 -12
- package/Cargo.toml +1 -1
- package/README.md +5 -5
- package/crates/omx-sparkshell/tests/execution.rs +1 -1
- package/dist/agents/__tests__/native-config.test.js +42 -1
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/definitions.d.ts +8 -0
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +1 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/native-config.d.ts +5 -1
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js +17 -2
- package/dist/agents/native-config.js.map +1 -1
- package/dist/autopilot/__tests__/fsm.test.js +3 -0
- package/dist/autopilot/__tests__/fsm.test.js.map +1 -1
- package/dist/autopilot/fsm.js +2 -2
- package/dist/autopilot/fsm.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +4 -2
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +512 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +39 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +98 -6
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +28 -8
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js +26 -9
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +13 -0
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +14 -0
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/resume.test.js +50 -1
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +89 -0
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +65 -0
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/state.test.js +21 -0
- package/dist/cli/__tests__/state.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +2 -2
- package/dist/cli/__tests__/update.test.js +323 -18
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +8 -1
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +21 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +143 -28
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/plugin-marketplace.d.ts +14 -2
- package/dist/cli/plugin-marketplace.d.ts.map +1 -1
- package/dist/cli/plugin-marketplace.js +62 -15
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +3 -1
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +2 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +4 -0
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +3 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +166 -27
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/state.d.ts.map +1 -1
- package/dist/cli/state.js +8 -1
- package/dist/cli/state.js.map +1 -1
- package/dist/cli/tmux-hook.d.ts.map +1 -1
- package/dist/cli/tmux-hook.js +16 -0
- package/dist/cli/tmux-hook.js.map +1 -1
- package/dist/cli/update.d.ts +22 -3
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +312 -26
- package/dist/cli/update.js.map +1 -1
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +5 -9
- package/dist/cli/version.js.map +1 -1
- package/dist/compat/__tests__/doctor-contract.test.js +12 -1
- package/dist/compat/__tests__/doctor-contract.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +1 -0
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/generator.d.ts +2 -2
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +2 -2
- package/dist/config/generator.js.map +1 -1
- package/dist/config/team-mode.d.ts +12 -0
- package/dist/config/team-mode.d.ts.map +1 -0
- package/dist/config/team-mode.js +91 -0
- package/dist/config/team-mode.js.map +1 -0
- package/dist/hooks/__tests__/agents-overlay.test.js +88 -0
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.js +12 -0
- package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +30 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +423 -3
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +189 -0
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +35 -2
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +3 -3
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-guidance-contract.test.js +21 -0
- package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +1 -1
- package/dist/hooks/agents-overlay.d.ts.map +1 -1
- package/dist/hooks/agents-overlay.js +36 -50
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +31 -0
- package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner.js +17 -21
- package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +258 -12
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +6 -0
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts +1 -0
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/authority.test.js +435 -32
- package/dist/hud/__tests__/authority.test.js.map +1 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +2 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +42 -0
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +642 -15
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/render.test.js +61 -0
- package/dist/hud/__tests__/render.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +160 -4
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +180 -21
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/authority.d.ts +5 -0
- package/dist/hud/authority.d.ts.map +1 -1
- package/dist/hud/authority.js +324 -28
- package/dist/hud/authority.js.map +1 -1
- package/dist/hud/index.d.ts +3 -2
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +42 -19
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.d.ts +3 -3
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +128 -19
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +35 -0
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +65 -80
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.d.ts +24 -6
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +136 -38
- package/dist/hud/tmux.js.map +1 -1
- package/dist/hud/types.d.ts +11 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +71 -1
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +32 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +113 -17
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +4 -4
- package/dist/question/__tests__/renderer.test.js +566 -1
- package/dist/question/__tests__/renderer.test.js.map +1 -1
- package/dist/question/renderer.d.ts +9 -1
- package/dist/question/renderer.d.ts.map +1 -1
- package/dist/question/renderer.js +246 -70
- package/dist/question/renderer.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +837 -101
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-state-io.test.js +72 -1
- package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.d.ts +2 -0
- package/dist/scripts/__tests__/notify-tmux-injection.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/notify-tmux-injection.test.js +57 -0
- package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -0
- package/dist/scripts/__tests__/run-test-files.test.js +74 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-agents.test.js +65 -0
- package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +107 -39
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/eval/eval-parity-smoke.js +1 -1
- package/dist/scripts/eval/eval-parity-smoke.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +3 -1
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +3 -10
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +62 -38
- package/dist/scripts/notify-hook/state-io.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 +7 -0
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +7 -0
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +24 -18
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +75 -11
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/run-test-files.js +193 -22
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js +61 -3
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/verify-native-agents.d.ts.map +1 -1
- package/dist/scripts/verify-native-agents.js +58 -1
- package/dist/scripts/verify-native-agents.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +113 -0
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +3 -16
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +25 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +57 -2
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +7 -39
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +10 -14
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +1 -1
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +9 -4
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +195 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-runtime-identity.test.js +4 -2
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +3 -2
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/tmux-session.d.ts +2 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +142 -12
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/utils/__tests__/platform-command.test.js +16 -1
- package/dist/utils/__tests__/platform-command.test.js.map +1 -1
- package/dist/utils/__tests__/version.test.d.ts +2 -0
- package/dist/utils/__tests__/version.test.d.ts.map +1 -0
- package/dist/utils/__tests__/version.test.js +51 -0
- package/dist/utils/__tests__/version.test.js.map +1 -0
- package/dist/utils/paths.d.ts +8 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +16 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-command.d.ts +9 -0
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +15 -0
- package/dist/utils/platform-command.js.map +1 -1
- package/dist/utils/version.d.ts +7 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +67 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/verification/__tests__/ci-rust-gates.test.js +89 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +16 -2
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -1
- package/package.json +11 -10
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +334 -21
- package/plugins/oh-my-codex/hooks/hooks.json +1 -2
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +3 -1
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +7 -7
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +51 -11
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +22 -22
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +9 -0
- package/skills/autopilot/SKILL.md +3 -1
- package/skills/code-review/SKILL.md +7 -7
- package/skills/deep-interview/SKILL.md +51 -11
- package/skills/ralph/SKILL.md +22 -22
- package/skills/ultraqa/SKILL.md +9 -0
- package/src/scripts/__tests__/codex-native-hook.test.ts +946 -98
- package/src/scripts/__tests__/notify-state-io.test.ts +95 -0
- package/src/scripts/__tests__/notify-tmux-injection.test.ts +82 -0
- package/src/scripts/__tests__/run-test-files.test.ts +102 -0
- package/src/scripts/__tests__/verify-native-agents.test.ts +75 -0
- package/src/scripts/codex-native-hook.ts +123 -34
- package/src/scripts/demo-team-e2e.sh +10 -7
- package/src/scripts/eval/eval-parity-smoke.ts +1 -1
- package/src/scripts/notify-hook/auto-nudge.ts +3 -1
- package/src/scripts/notify-hook/ralph-session-resume.ts +2 -8
- package/src/scripts/notify-hook/state-io.ts +75 -37
- package/src/scripts/notify-hook/team-leader-nudge.ts +7 -0
- package/src/scripts/notify-hook/tmux-injection.ts +35 -19
- package/src/scripts/notify-hook.ts +91 -4
- package/src/scripts/prepare-build.js +83 -0
- package/src/scripts/run-test-files.ts +192 -22
- package/src/scripts/sync-plugin-mirror.ts +98 -9
- package/src/scripts/verify-native-agents.ts +65 -1
- package/src/scripts/postinstall-bootstrap.js +0 -23
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, it } from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
3
4
|
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
5
|
import { dirname, join } from 'node:path';
|
|
5
6
|
import { tmpdir } from 'node:os';
|
|
6
|
-
import { isInstallVersionBump, isNewerVersion, maybeCheckAndPromptUpdate, readUserInstallStamp, resolveAutoUpdateMode, resolveInstalledCliEntry, runDeferredGlobalUpdate, runImmediateUpdate, shouldCheckForUpdates, spawnInstalledSetupRefresh, writeUserInstallStamp, } from '../update.js';
|
|
7
|
+
import { isInstallVersionBump, isNewerVersion, maybeCheckAndPromptUpdate, readUserInstallStamp, resolveAutoUpdateMode, resolveGlobalInstallRoot, resolveInstalledCliEntry, formatDeferredSetupCommand, resolveSetupRefreshArgs, runDeferredGlobalUpdate, runGlobalUpdate, runImmediateUpdate, shouldCheckForUpdates, spawnInstalledSetupRefresh, writeUserInstallStamp, } from '../update.js';
|
|
7
8
|
const PACKAGE_NAME = 'oh-my-codex';
|
|
8
9
|
describe('isNewerVersion', () => {
|
|
9
10
|
it('returns true when latest has higher major', () => {
|
|
@@ -151,6 +152,7 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
151
152
|
}
|
|
152
153
|
it('schedules a deferred update after a successful startup prompt', async () => {
|
|
153
154
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-'));
|
|
155
|
+
const originalMode = process.env.OMX_AUTO_UPDATE;
|
|
154
156
|
const originalLog = console.log;
|
|
155
157
|
const logs = [];
|
|
156
158
|
let inlineUpdateCalls = 0;
|
|
@@ -159,6 +161,7 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
159
161
|
console.log = (...args) => {
|
|
160
162
|
logs.push(args.map((arg) => String(arg)).join(' '));
|
|
161
163
|
};
|
|
164
|
+
delete process.env.OMX_AUTO_UPDATE;
|
|
162
165
|
try {
|
|
163
166
|
await withInteractiveTty(async () => {
|
|
164
167
|
await maybeCheckAndPromptUpdate(cwd, {
|
|
@@ -189,15 +192,23 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
189
192
|
assert.match(logs.join('\n'), /Log: .*update-test\.log/);
|
|
190
193
|
}
|
|
191
194
|
finally {
|
|
195
|
+
if (typeof originalMode === 'string') {
|
|
196
|
+
process.env.OMX_AUTO_UPDATE = originalMode;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
delete process.env.OMX_AUTO_UPDATE;
|
|
200
|
+
}
|
|
192
201
|
console.log = originalLog;
|
|
193
202
|
await rm(cwd, { recursive: true, force: true });
|
|
194
203
|
}
|
|
195
204
|
});
|
|
196
205
|
it('keeps startup update deferred so local setup is not refreshed inline', async () => {
|
|
197
206
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-'));
|
|
207
|
+
const originalMode = process.env.OMX_AUTO_UPDATE;
|
|
198
208
|
const originalLog = console.log;
|
|
199
209
|
const receivedCwds = [];
|
|
200
210
|
console.log = () => undefined;
|
|
211
|
+
delete process.env.OMX_AUTO_UPDATE;
|
|
201
212
|
try {
|
|
202
213
|
await withInteractiveTty(async () => {
|
|
203
214
|
await maybeCheckAndPromptUpdate(cwd, {
|
|
@@ -216,6 +227,12 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
216
227
|
assert.deepEqual(receivedCwds, [cwd]);
|
|
217
228
|
}
|
|
218
229
|
finally {
|
|
230
|
+
if (typeof originalMode === 'string') {
|
|
231
|
+
process.env.OMX_AUTO_UPDATE = originalMode;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
delete process.env.OMX_AUTO_UPDATE;
|
|
235
|
+
}
|
|
219
236
|
console.log = originalLog;
|
|
220
237
|
await rm(cwd, { recursive: true, force: true });
|
|
221
238
|
}
|
|
@@ -296,12 +313,14 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
296
313
|
});
|
|
297
314
|
it('reports scheduler diagnostics when startup deferral cannot be launched', async () => {
|
|
298
315
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-'));
|
|
316
|
+
const originalMode = process.env.OMX_AUTO_UPDATE;
|
|
299
317
|
const originalLog = console.log;
|
|
300
318
|
const logs = [];
|
|
301
319
|
let setupRefreshCalls = 0;
|
|
302
320
|
console.log = (...args) => {
|
|
303
321
|
logs.push(args.map((arg) => String(arg)).join(' '));
|
|
304
322
|
};
|
|
323
|
+
delete process.env.OMX_AUTO_UPDATE;
|
|
305
324
|
try {
|
|
306
325
|
await withInteractiveTty(async () => {
|
|
307
326
|
await maybeCheckAndPromptUpdate(cwd, {
|
|
@@ -321,6 +340,12 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
321
340
|
assert.match(logs.join('\n'), /update-test\.log/);
|
|
322
341
|
}
|
|
323
342
|
finally {
|
|
343
|
+
if (typeof originalMode === 'string') {
|
|
344
|
+
process.env.OMX_AUTO_UPDATE = originalMode;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
delete process.env.OMX_AUTO_UPDATE;
|
|
348
|
+
}
|
|
324
349
|
console.log = originalLog;
|
|
325
350
|
await rm(cwd, { recursive: true, force: true });
|
|
326
351
|
}
|
|
@@ -380,6 +405,89 @@ describe('maybeCheckAndPromptUpdate', () => {
|
|
|
380
405
|
}
|
|
381
406
|
});
|
|
382
407
|
});
|
|
408
|
+
describe('direct npm spawn fallback', () => {
|
|
409
|
+
function enoentResult() {
|
|
410
|
+
const error = Object.assign(new Error('spawnSync npm ENOENT'), { code: 'ENOENT' });
|
|
411
|
+
return { status: null, signal: null, error, stdout: '', stderr: '', output: [null, '', ''], pid: 0 };
|
|
412
|
+
}
|
|
413
|
+
function okResult(stdout = '') {
|
|
414
|
+
return { status: 0, signal: null, error: undefined, stdout, stderr: '', output: [null, stdout, ''], pid: 0 };
|
|
415
|
+
}
|
|
416
|
+
it('falls back to npm.cmd for win32 global installs when direct npm spawn returns ENOENT', () => {
|
|
417
|
+
const calls = [];
|
|
418
|
+
const result = runGlobalUpdate(((command, args) => {
|
|
419
|
+
calls.push({ command, args: args });
|
|
420
|
+
return command === 'npm' ? enoentResult() : okResult();
|
|
421
|
+
}), 'win32');
|
|
422
|
+
assert.equal(result.ok, true);
|
|
423
|
+
assert.deepEqual(calls.map((call) => call.command), ['npm', 'npm.cmd']);
|
|
424
|
+
assert.deepEqual(calls[0].args, ['install', '-g', 'oh-my-codex@latest']);
|
|
425
|
+
assert.deepEqual(calls[1].args, ['install', '-g', 'oh-my-codex@latest']);
|
|
426
|
+
});
|
|
427
|
+
it('does not fall back to npm.cmd for non-Windows ENOENT failures', () => {
|
|
428
|
+
const calls = [];
|
|
429
|
+
const result = runGlobalUpdate(((command) => {
|
|
430
|
+
calls.push(command);
|
|
431
|
+
return enoentResult();
|
|
432
|
+
}), 'linux');
|
|
433
|
+
assert.equal(result.ok, false);
|
|
434
|
+
assert.match(result.stderr, /ENOENT/);
|
|
435
|
+
assert.deepEqual(calls, ['npm']);
|
|
436
|
+
});
|
|
437
|
+
it('packs the dev branch from a local checkout instead of globally installing the git dependency spec', () => {
|
|
438
|
+
const originalNpmLocation = process.env.npm_config_location;
|
|
439
|
+
const calls = [];
|
|
440
|
+
process.env.npm_config_location = 'global';
|
|
441
|
+
try {
|
|
442
|
+
const result = runGlobalUpdate('github:Yeachan-Heo/oh-my-codex#dev', ((command, args, options) => {
|
|
443
|
+
calls.push({ command, args: args, cwd: options?.cwd, env: options?.env });
|
|
444
|
+
if (command === 'git' && args[0] === 'clone') {
|
|
445
|
+
mkdirSync(String(args[args.length - 1]), { recursive: true });
|
|
446
|
+
}
|
|
447
|
+
if (command === 'git' && args[0] === 'rev-parse') {
|
|
448
|
+
return okResult('1234567890abcdef\n');
|
|
449
|
+
}
|
|
450
|
+
if (command === 'npm' && args[0] === 'pack') {
|
|
451
|
+
writeFileSync(join(options?.cwd ?? process.cwd(), 'oh-my-codex-0.18.9.tgz'), 'packed');
|
|
452
|
+
return okResult(JSON.stringify([{ filename: 'oh-my-codex-0.18.9.tgz' }]));
|
|
453
|
+
}
|
|
454
|
+
return okResult();
|
|
455
|
+
}), 'linux');
|
|
456
|
+
assert.equal(result.ok, true);
|
|
457
|
+
assert.deepEqual(calls.map((call) => [call.command, ...call.args.slice(0, 3)]), [
|
|
458
|
+
['git', 'clone', '--depth', '1'],
|
|
459
|
+
['git', 'rev-parse', 'HEAD'],
|
|
460
|
+
['npm', 'install', '--global=false', '--location=project'],
|
|
461
|
+
['npm', 'run', 'prepack'],
|
|
462
|
+
['npm', 'pack', '--ignore-scripts', '--json'],
|
|
463
|
+
['npm', 'install', '-g', join(calls[2].cwd ?? '', 'oh-my-codex-0.18.9.tgz')],
|
|
464
|
+
]);
|
|
465
|
+
const dependencyInstall = calls.find((call) => call.command === 'npm' && call.args[0] === 'install' && call.args.includes('--include=dev'));
|
|
466
|
+
assert.equal(dependencyInstall?.env?.npm_config_global, 'false');
|
|
467
|
+
assert.equal(dependencyInstall?.env?.npm_config_location, 'project');
|
|
468
|
+
assert.equal(calls.some((call) => call.args.includes('github:Yeachan-Heo/oh-my-codex#dev')), false);
|
|
469
|
+
}
|
|
470
|
+
finally {
|
|
471
|
+
if (typeof originalNpmLocation === 'string') {
|
|
472
|
+
process.env.npm_config_location = originalNpmLocation;
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
delete process.env.npm_config_location;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
it('falls back to npm.cmd for win32 global-root lookup when direct npm spawn returns ENOENT', () => {
|
|
480
|
+
const calls = [];
|
|
481
|
+
const root = resolveGlobalInstallRoot(((command, args) => {
|
|
482
|
+
calls.push({ command, args: args });
|
|
483
|
+
return command === 'npm' ? enoentResult() : okResult('C:\\Users\\alice\\AppData\\Roaming\\npm\\node_modules\r\n');
|
|
484
|
+
}), 'win32');
|
|
485
|
+
assert.equal(root, 'C:\\Users\\alice\\AppData\\Roaming\\npm\\node_modules');
|
|
486
|
+
assert.deepEqual(calls.map((call) => call.command), ['npm', 'npm.cmd']);
|
|
487
|
+
assert.deepEqual(calls[0].args, ['root', '-g']);
|
|
488
|
+
assert.deepEqual(calls[1].args, ['root', '-g']);
|
|
489
|
+
});
|
|
490
|
+
});
|
|
383
491
|
describe('runImmediateUpdate', () => {
|
|
384
492
|
it('bypasses the passive cadence and updates immediately on explicit request', async () => {
|
|
385
493
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-now-'));
|
|
@@ -390,6 +498,7 @@ describe('runImmediateUpdate', () => {
|
|
|
390
498
|
const logs = [];
|
|
391
499
|
let setupCalls = 0;
|
|
392
500
|
const refreshCwds = [];
|
|
501
|
+
const installSources = [];
|
|
393
502
|
let updateCalls = 0;
|
|
394
503
|
let latestCalls = 0;
|
|
395
504
|
console.log = (...args) => {
|
|
@@ -408,8 +517,9 @@ describe('runImmediateUpdate', () => {
|
|
|
408
517
|
latestCalls += 1;
|
|
409
518
|
return '0.14.1';
|
|
410
519
|
},
|
|
411
|
-
runGlobalUpdate: () => {
|
|
520
|
+
runGlobalUpdate: (installSource) => {
|
|
412
521
|
updateCalls += 1;
|
|
522
|
+
installSources.push(installSource);
|
|
413
523
|
return { ok: true, stderr: '' };
|
|
414
524
|
},
|
|
415
525
|
runSetupRefresh: async (refreshCwd) => {
|
|
@@ -421,10 +531,13 @@ describe('runImmediateUpdate', () => {
|
|
|
421
531
|
assert.equal(result.status, 'updated');
|
|
422
532
|
assert.equal(latestCalls, 1);
|
|
423
533
|
assert.equal(updateCalls, 1);
|
|
534
|
+
assert.deepEqual(installSources, [`${PACKAGE_NAME}@latest`]);
|
|
424
535
|
assert.equal(setupCalls, 1);
|
|
425
536
|
assert.deepEqual(refreshCwds, [cwd]);
|
|
537
|
+
assert.match(logs.join('\n'), /Selected update channel: stable/);
|
|
538
|
+
assert.match(logs.join('\n'), /Install source: oh-my-codex@latest/);
|
|
426
539
|
assert.match(logs.join('\n'), /Running: npm install -g oh-my-codex@latest/);
|
|
427
|
-
assert.match(logs.join('\n'), /Updated to v0\.14\.1/);
|
|
540
|
+
assert.match(logs.join('\n'), /Updated stable channel to v0\.14\.1/);
|
|
428
541
|
const stamp = JSON.parse(await readFile(stampPath, 'utf-8'));
|
|
429
542
|
assert.equal(stamp.installed_version, '0.14.1');
|
|
430
543
|
assert.equal(stamp.setup_completed_version, '0.14.1');
|
|
@@ -440,12 +553,13 @@ describe('runImmediateUpdate', () => {
|
|
|
440
553
|
await rm(cwd, { recursive: true, force: true });
|
|
441
554
|
}
|
|
442
555
|
});
|
|
443
|
-
it('
|
|
556
|
+
it('force-installs stable for explicit update even when npm is already current', async () => {
|
|
444
557
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-now-'));
|
|
445
558
|
const stampPath = join(cwd, '.codex', '.omx', 'install-state.json');
|
|
446
559
|
const originalCodexHome = process.env.CODEX_HOME;
|
|
447
560
|
const originalLog = console.log;
|
|
448
561
|
const logs = [];
|
|
562
|
+
const installSources = [];
|
|
449
563
|
let updateCalls = 0;
|
|
450
564
|
let refreshCalls = 0;
|
|
451
565
|
console.log = (...args) => {
|
|
@@ -461,8 +575,9 @@ describe('runImmediateUpdate', () => {
|
|
|
461
575
|
const result = await runImmediateUpdate(cwd, {
|
|
462
576
|
getCurrentVersion: async () => '0.14.0',
|
|
463
577
|
fetchLatestVersion: async () => '0.14.0',
|
|
464
|
-
runGlobalUpdate: () => {
|
|
578
|
+
runGlobalUpdate: (installSource) => {
|
|
465
579
|
updateCalls += 1;
|
|
580
|
+
installSources.push(installSource);
|
|
466
581
|
return { ok: true, stderr: '' };
|
|
467
582
|
},
|
|
468
583
|
runSetupRefresh: async () => {
|
|
@@ -470,10 +585,12 @@ describe('runImmediateUpdate', () => {
|
|
|
470
585
|
return { ok: true, stderr: '' };
|
|
471
586
|
},
|
|
472
587
|
});
|
|
473
|
-
assert.equal(result.status, '
|
|
474
|
-
assert.equal(updateCalls,
|
|
475
|
-
assert.equal(refreshCalls,
|
|
476
|
-
assert.
|
|
588
|
+
assert.equal(result.status, 'updated');
|
|
589
|
+
assert.equal(updateCalls, 1);
|
|
590
|
+
assert.equal(refreshCalls, 1);
|
|
591
|
+
assert.deepEqual(installSources, [`${PACKAGE_NAME}@latest`]);
|
|
592
|
+
assert.match(logs.join('\n'), /Selected update channel: stable/);
|
|
593
|
+
assert.match(logs.join('\n'), /Running: npm install -g oh-my-codex@latest/);
|
|
477
594
|
}
|
|
478
595
|
finally {
|
|
479
596
|
console.log = originalLog;
|
|
@@ -486,12 +603,14 @@ describe('runImmediateUpdate', () => {
|
|
|
486
603
|
await rm(cwd, { recursive: true, force: true });
|
|
487
604
|
}
|
|
488
605
|
});
|
|
489
|
-
it('
|
|
606
|
+
it('uses stable as a rollback path while preserving persisted setup preferences', async () => {
|
|
490
607
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-now-'));
|
|
491
608
|
const stampPath = join(cwd, '.codex', '.omx', 'install-state.json');
|
|
492
609
|
const originalCodexHome = process.env.CODEX_HOME;
|
|
493
610
|
const originalLog = console.log;
|
|
494
611
|
const logs = [];
|
|
612
|
+
const installSources = [];
|
|
613
|
+
const setupArgs = resolveSetupRefreshArgs;
|
|
495
614
|
let refreshCalls = 0;
|
|
496
615
|
console.log = (...args) => {
|
|
497
616
|
logs.push(args.map((arg) => String(arg)).join(' '));
|
|
@@ -503,21 +622,34 @@ describe('runImmediateUpdate', () => {
|
|
|
503
622
|
setup_completed_version: '0.13.9',
|
|
504
623
|
updated_at: '2026-04-20T00:00:00.000Z',
|
|
505
624
|
}, stampPath);
|
|
625
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
626
|
+
await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'user', installMode: 'plugin', mcpMode: 'none', teamMode: 'disabled' }, null, 2));
|
|
506
627
|
const result = await runImmediateUpdate(cwd, {
|
|
507
628
|
getCurrentVersion: async () => '0.14.0',
|
|
508
629
|
fetchLatestVersion: async () => '0.14.0',
|
|
509
|
-
runGlobalUpdate: () => {
|
|
510
|
-
|
|
630
|
+
runGlobalUpdate: (installSource) => {
|
|
631
|
+
installSources.push(installSource);
|
|
632
|
+
return { ok: true, stderr: '', revision: '1234567890ab' };
|
|
511
633
|
},
|
|
512
634
|
runSetupRefresh: async () => {
|
|
513
635
|
refreshCalls += 1;
|
|
636
|
+
assert.deepEqual(setupArgs(cwd), [
|
|
637
|
+
'setup',
|
|
638
|
+
'--scope',
|
|
639
|
+
'user',
|
|
640
|
+
'--plugin',
|
|
641
|
+
'--mcp',
|
|
642
|
+
'none',
|
|
643
|
+
'--disable-team',
|
|
644
|
+
]);
|
|
514
645
|
return { ok: true, stderr: '' };
|
|
515
646
|
},
|
|
516
|
-
});
|
|
517
|
-
assert.equal(result.status, '
|
|
647
|
+
}, { channel: 'stable' });
|
|
648
|
+
assert.equal(result.status, 'updated');
|
|
649
|
+
assert.deepEqual(installSources, [`${PACKAGE_NAME}@latest`]);
|
|
518
650
|
assert.equal(refreshCalls, 1);
|
|
519
|
-
assert.match(logs.join('\n'), /
|
|
520
|
-
assert.match(logs.join('\n'), /
|
|
651
|
+
assert.match(logs.join('\n'), /Selected update channel: stable/);
|
|
652
|
+
assert.match(logs.join('\n'), /Install source: oh-my-codex@latest/);
|
|
521
653
|
const stamp = JSON.parse(await readFile(stampPath, 'utf-8'));
|
|
522
654
|
assert.equal(stamp.installed_version, '0.14.0');
|
|
523
655
|
assert.equal(stamp.setup_completed_version, '0.14.0');
|
|
@@ -533,8 +665,66 @@ describe('runImmediateUpdate', () => {
|
|
|
533
665
|
await rm(cwd, { recursive: true, force: true });
|
|
534
666
|
}
|
|
535
667
|
});
|
|
668
|
+
it('installs the upstream dev branch without implying npm latest', async () => {
|
|
669
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-now-dev-'));
|
|
670
|
+
const stampPath = join(cwd, '.codex', '.omx', 'install-state.json');
|
|
671
|
+
const originalCodexHome = process.env.CODEX_HOME;
|
|
672
|
+
const originalLog = console.log;
|
|
673
|
+
const logs = [];
|
|
674
|
+
const installSources = [];
|
|
675
|
+
let latestCalls = 0;
|
|
676
|
+
let refreshCalls = 0;
|
|
677
|
+
console.log = (...args) => {
|
|
678
|
+
logs.push(args.map((arg) => String(arg)).join(' '));
|
|
679
|
+
};
|
|
680
|
+
process.env.CODEX_HOME = join(cwd, '.codex');
|
|
681
|
+
try {
|
|
682
|
+
const result = await runImmediateUpdate(cwd, {
|
|
683
|
+
getCurrentVersion: async () => '0.14.0',
|
|
684
|
+
fetchLatestVersion: async () => {
|
|
685
|
+
latestCalls += 1;
|
|
686
|
+
return '0.14.0';
|
|
687
|
+
},
|
|
688
|
+
runGlobalUpdate: (installSource) => {
|
|
689
|
+
installSources.push(installSource);
|
|
690
|
+
return { ok: true, stderr: '', revision: '1234567890ab' };
|
|
691
|
+
},
|
|
692
|
+
runSetupRefresh: async () => {
|
|
693
|
+
refreshCalls += 1;
|
|
694
|
+
return { ok: true, stderr: '' };
|
|
695
|
+
},
|
|
696
|
+
getInstalledVersionAfterUpdate: async () => '0.15.0',
|
|
697
|
+
getInstalledRevisionAfterUpdate: async () => null,
|
|
698
|
+
}, { channel: 'dev' });
|
|
699
|
+
assert.equal(result.status, 'updated');
|
|
700
|
+
assert.equal(latestCalls, 0);
|
|
701
|
+
assert.equal(refreshCalls, 1);
|
|
702
|
+
assert.deepEqual(installSources, ['github:Yeachan-Heo/oh-my-codex#dev']);
|
|
703
|
+
assert.match(logs.join('\n'), /Selected update channel: dev/);
|
|
704
|
+
assert.match(logs.join('\n'), /Install source: github:Yeachan-Heo\/oh-my-codex#dev/);
|
|
705
|
+
assert.match(logs.join('\n'), /Running: clone dev branch, run prepack, then npm install -g the packed tarball/);
|
|
706
|
+
assert.doesNotMatch(logs.join('\n'), /dev.*oh-my-codex@latest/i);
|
|
707
|
+
const stamp = JSON.parse(await readFile(stampPath, 'utf-8'));
|
|
708
|
+
assert.equal(stamp.installed_version, '0.15.0');
|
|
709
|
+
assert.equal(stamp.setup_completed_version, '0.15.0');
|
|
710
|
+
assert.equal(stamp.install_channel, 'dev');
|
|
711
|
+
assert.equal(stamp.install_source, 'github:Yeachan-Heo/oh-my-codex#dev');
|
|
712
|
+
assert.equal(stamp.install_revision, '1234567890ab');
|
|
713
|
+
}
|
|
714
|
+
finally {
|
|
715
|
+
console.log = originalLog;
|
|
716
|
+
if (typeof originalCodexHome === 'string') {
|
|
717
|
+
process.env.CODEX_HOME = originalCodexHome;
|
|
718
|
+
}
|
|
719
|
+
else {
|
|
720
|
+
delete process.env.CODEX_HOME;
|
|
721
|
+
}
|
|
722
|
+
await rm(cwd, { recursive: true, force: true });
|
|
723
|
+
}
|
|
724
|
+
});
|
|
536
725
|
it('continues explicit update when update-check state cannot be written', async () => {
|
|
537
726
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-now-'));
|
|
727
|
+
const originalCodexHome = process.env.CODEX_HOME;
|
|
538
728
|
const originalLog = console.log;
|
|
539
729
|
const logs = [];
|
|
540
730
|
let updateCalls = 0;
|
|
@@ -542,6 +732,7 @@ describe('runImmediateUpdate', () => {
|
|
|
542
732
|
console.log = (...args) => {
|
|
543
733
|
logs.push(args.map((arg) => String(arg)).join(' '));
|
|
544
734
|
};
|
|
735
|
+
process.env.CODEX_HOME = join(cwd, '.codex');
|
|
545
736
|
try {
|
|
546
737
|
const result = await runImmediateUpdate(cwd, {
|
|
547
738
|
getCurrentVersion: async () => '0.14.0',
|
|
@@ -561,10 +752,16 @@ describe('runImmediateUpdate', () => {
|
|
|
561
752
|
assert.equal(result.status, 'updated');
|
|
562
753
|
assert.equal(updateCalls, 1);
|
|
563
754
|
assert.equal(refreshCalls, 1);
|
|
564
|
-
assert.match(logs.join('\n'), /Updated to v0\.14\.1/);
|
|
755
|
+
assert.match(logs.join('\n'), /Updated stable channel to v0\.14\.1/);
|
|
565
756
|
}
|
|
566
757
|
finally {
|
|
567
758
|
console.log = originalLog;
|
|
759
|
+
if (typeof originalCodexHome === 'string') {
|
|
760
|
+
process.env.CODEX_HOME = originalCodexHome;
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
delete process.env.CODEX_HOME;
|
|
764
|
+
}
|
|
568
765
|
await rm(cwd, { recursive: true, force: true });
|
|
569
766
|
}
|
|
570
767
|
});
|
|
@@ -667,12 +864,67 @@ describe('runDeferredGlobalUpdate', () => {
|
|
|
667
864
|
assert.equal(calls[0].options.env?.OMX_DEFERRED_UPDATE_LOG, result.logPath);
|
|
668
865
|
assert.match(calls[0].args[4], /Get-Process -Id \$parentPid/);
|
|
669
866
|
assert.match(calls[0].args[4], /npm install -g oh-my-codex@latest/);
|
|
670
|
-
assert.match(calls[0].args[4],
|
|
867
|
+
assert.match(calls[0].args[4], /& 'omx' 'setup'/);
|
|
868
|
+
}
|
|
869
|
+
finally {
|
|
870
|
+
await rm(cwd, { recursive: true, force: true });
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
it('preserves plugin setup delivery mode for deferred post-update refreshes', async () => {
|
|
874
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-deferred-update-plugin-'));
|
|
875
|
+
const calls = [];
|
|
876
|
+
try {
|
|
877
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
878
|
+
await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'user', installMode: 'plugin', mcpMode: 'none', teamMode: 'disabled' }, null, 2));
|
|
879
|
+
const result = runDeferredGlobalUpdate(cwd, ((command, args) => {
|
|
880
|
+
calls.push({ command, args: args });
|
|
881
|
+
return {
|
|
882
|
+
once() {
|
|
883
|
+
return this;
|
|
884
|
+
},
|
|
885
|
+
unref() { },
|
|
886
|
+
};
|
|
887
|
+
}), 'linux', 12345);
|
|
888
|
+
assert.equal(result.ok, true);
|
|
889
|
+
assert.equal(calls.length, 1);
|
|
890
|
+
assert.match(calls[0].args[1], /'omx' 'setup' '--scope' 'user' '--plugin' '--mcp' 'none' '--disable-team'/);
|
|
671
891
|
}
|
|
672
892
|
finally {
|
|
673
893
|
await rm(cwd, { recursive: true, force: true });
|
|
674
894
|
}
|
|
675
895
|
});
|
|
896
|
+
it('snapshots deferred setup refresh args when scheduling the detached updater', async () => {
|
|
897
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-deferred-update-snapshot-'));
|
|
898
|
+
const calls = [];
|
|
899
|
+
try {
|
|
900
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
901
|
+
const setupScopePath = join(cwd, '.omx', 'setup-scope.json');
|
|
902
|
+
await writeFile(setupScopePath, JSON.stringify({ scope: 'user', installMode: 'plugin', mcpMode: 'none', teamMode: 'disabled' }, null, 2));
|
|
903
|
+
const result = runDeferredGlobalUpdate(cwd, ((command, args) => {
|
|
904
|
+
calls.push({ command, args: args });
|
|
905
|
+
return {
|
|
906
|
+
once() {
|
|
907
|
+
return this;
|
|
908
|
+
},
|
|
909
|
+
unref() { },
|
|
910
|
+
};
|
|
911
|
+
}), 'linux', 12345);
|
|
912
|
+
await writeFile(setupScopePath, JSON.stringify({ scope: 'project', installMode: 'legacy', mcpMode: 'compat' }, null, 2));
|
|
913
|
+
assert.equal(result.ok, true);
|
|
914
|
+
assert.equal(calls.length, 1);
|
|
915
|
+
assert.match(calls[0].args[1], /'omx' 'setup' '--scope' 'user' '--plugin' '--mcp' 'none' '--disable-team'/);
|
|
916
|
+
assert.doesNotMatch(calls[0].args[1], /compat/);
|
|
917
|
+
assert.doesNotMatch(calls[0].args[1], /legacy/);
|
|
918
|
+
}
|
|
919
|
+
finally {
|
|
920
|
+
await rm(cwd, { recursive: true, force: true });
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
it('quotes deferred setup command arguments at the shell boundary', () => {
|
|
924
|
+
const args = ['setup', '--scope', 'user project', '--mcp', "none'; echo pwned #", '--flag', ''];
|
|
925
|
+
assert.equal(formatDeferredSetupCommand('linux', 'omx tool', args), "'omx tool' 'setup' '--scope' 'user project' '--mcp' 'none'\\''; echo pwned #' '--flag' ''");
|
|
926
|
+
assert.equal(formatDeferredSetupCommand('win32', 'omx tool', args), "& 'omx tool' 'setup' '--scope' 'user project' '--mcp' 'none''; echo pwned #' '--flag' ''");
|
|
927
|
+
});
|
|
676
928
|
});
|
|
677
929
|
describe('post-update setup refresh handoff', () => {
|
|
678
930
|
it('uses the installed package bin entry when resolving the refreshed CLI', async () => {
|
|
@@ -722,5 +974,58 @@ describe('post-update setup refresh handoff', () => {
|
|
|
722
974
|
assert.equal(result.ok, true);
|
|
723
975
|
assert.equal(receivedTimeout, undefined);
|
|
724
976
|
});
|
|
977
|
+
it('passes persisted plugin setup choices to the updated CLI refresh', async () => {
|
|
978
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-plugin-refresh-'));
|
|
979
|
+
const received = [];
|
|
980
|
+
try {
|
|
981
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
982
|
+
await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'user', installMode: 'plugin', mcpMode: 'none', teamMode: 'disabled' }, null, 2));
|
|
983
|
+
const result = spawnInstalledSetupRefresh('/tmp/omx.js', cwd, ((command, args) => {
|
|
984
|
+
received.push({ command, args: args });
|
|
985
|
+
return { status: 0, error: undefined };
|
|
986
|
+
}));
|
|
987
|
+
assert.equal(result.ok, true);
|
|
988
|
+
assert.deepEqual(received[0]?.args, [
|
|
989
|
+
'/tmp/omx.js',
|
|
990
|
+
'setup',
|
|
991
|
+
'--scope',
|
|
992
|
+
'user',
|
|
993
|
+
'--plugin',
|
|
994
|
+
'--mcp',
|
|
995
|
+
'none',
|
|
996
|
+
'--disable-team',
|
|
997
|
+
]);
|
|
998
|
+
assert.deepEqual(resolveSetupRefreshArgs(cwd), [
|
|
999
|
+
'setup',
|
|
1000
|
+
'--scope',
|
|
1001
|
+
'user',
|
|
1002
|
+
'--plugin',
|
|
1003
|
+
'--mcp',
|
|
1004
|
+
'none',
|
|
1005
|
+
'--disable-team',
|
|
1006
|
+
]);
|
|
1007
|
+
}
|
|
1008
|
+
finally {
|
|
1009
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
it('migrates legacy project-local scope when building update setup refresh args', async () => {
|
|
1013
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-update-plugin-legacy-scope-'));
|
|
1014
|
+
try {
|
|
1015
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1016
|
+
await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'project-local', installMode: 'plugin', mcpMode: 'none' }, null, 2));
|
|
1017
|
+
assert.deepEqual(resolveSetupRefreshArgs(cwd), [
|
|
1018
|
+
'setup',
|
|
1019
|
+
'--scope',
|
|
1020
|
+
'project',
|
|
1021
|
+
'--plugin',
|
|
1022
|
+
'--mcp',
|
|
1023
|
+
'none',
|
|
1024
|
+
]);
|
|
1025
|
+
}
|
|
1026
|
+
finally {
|
|
1027
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
725
1030
|
});
|
|
726
1031
|
//# sourceMappingURL=update.test.js.map
|