oh-my-codex 0.18.2 → 0.18.3
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.toml +1 -1
- package/dist/agents/__tests__/definitions.test.js +9 -0
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +1 -0
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +10 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/auth/__tests__/config-sessions.test.d.ts +2 -0
- package/dist/auth/__tests__/config-sessions.test.d.ts.map +1 -0
- package/dist/auth/__tests__/config-sessions.test.js +48 -0
- package/dist/auth/__tests__/config-sessions.test.js.map +1 -0
- package/dist/auth/__tests__/quota-rotation.test.d.ts +2 -0
- package/dist/auth/__tests__/quota-rotation.test.d.ts.map +1 -0
- package/dist/auth/__tests__/quota-rotation.test.js +33 -0
- package/dist/auth/__tests__/quota-rotation.test.js.map +1 -0
- package/dist/auth/__tests__/redact.test.d.ts +2 -0
- package/dist/auth/__tests__/redact.test.d.ts.map +1 -0
- package/dist/auth/__tests__/redact.test.js +20 -0
- package/dist/auth/__tests__/redact.test.js.map +1 -0
- package/dist/auth/__tests__/storage.test.d.ts +2 -0
- package/dist/auth/__tests__/storage.test.d.ts.map +1 -0
- package/dist/auth/__tests__/storage.test.js +108 -0
- package/dist/auth/__tests__/storage.test.js.map +1 -0
- package/dist/auth/config.d.ts +9 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/config.js +77 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/hotswap.d.ts +36 -0
- package/dist/auth/hotswap.d.ts.map +1 -0
- package/dist/auth/hotswap.js +159 -0
- package/dist/auth/hotswap.js.map +1 -0
- package/dist/auth/index.d.ts +8 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +8 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/paths.d.ts +12 -0
- package/dist/auth/paths.d.ts.map +1 -0
- package/dist/auth/paths.js +78 -0
- package/dist/auth/paths.js.map +1 -0
- package/dist/auth/quota-detector.d.ts +10 -0
- package/dist/auth/quota-detector.d.ts.map +1 -0
- package/dist/auth/quota-detector.js +40 -0
- package/dist/auth/quota-detector.js.map +1 -0
- package/dist/auth/redact.d.ts +2 -0
- package/dist/auth/redact.d.ts.map +1 -0
- package/dist/auth/redact.js +26 -0
- package/dist/auth/redact.js.map +1 -0
- package/dist/auth/rotation.d.ts +9 -0
- package/dist/auth/rotation.d.ts.map +1 -0
- package/dist/auth/rotation.js +26 -0
- package/dist/auth/rotation.js.map +1 -0
- package/dist/auth/sessions.d.ts +15 -0
- package/dist/auth/sessions.d.ts.map +1 -0
- package/dist/auth/sessions.js +62 -0
- package/dist/auth/sessions.js.map +1 -0
- package/dist/auth/storage.d.ts +27 -0
- package/dist/auth/storage.d.ts.map +1 -0
- package/dist/auth/storage.js +111 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/cli/__tests__/auth.test.d.ts +2 -0
- package/dist/cli/__tests__/auth.test.d.ts.map +1 -0
- package/dist/cli/__tests__/auth.test.js +168 -0
- package/dist/cli/__tests__/auth.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js +51 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/explore.test.js +20 -0
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +10 -0
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/nested-help-routing.test.js +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +30 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +47 -0
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/auth.d.ts +4 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +89 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +19 -7
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explore.d.ts.map +1 -1
- package/dist/cli/explore.js +12 -0
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +20 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +104 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +11 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/config/__tests__/deep-interview.test.d.ts +2 -0
- package/dist/config/__tests__/deep-interview.test.d.ts.map +1 -0
- package/dist/config/__tests__/deep-interview.test.js +239 -0
- package/dist/config/__tests__/deep-interview.test.js.map +1 -0
- package/dist/config/__tests__/generator-idempotent.test.js +123 -0
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/deep-interview.d.ts +22 -0
- package/dist/config/deep-interview.d.ts.map +1 -0
- package/dist/config/deep-interview.js +151 -0
- package/dist/config/deep-interview.js.map +1 -0
- package/dist/config/generator.d.ts +5 -2
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +106 -36
- package/dist/config/generator.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +2 -0
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/explore-routing.test.js +1 -0
- package/dist/hooks/__tests__/explore-routing.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +301 -0
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/deep-interview-config-instruction.d.ts +3 -0
- package/dist/hooks/deep-interview-config-instruction.d.ts.map +1 -0
- package/dist/hooks/deep-interview-config-instruction.js +47 -0
- package/dist/hooks/deep-interview-config-instruction.js.map +1 -0
- package/dist/hooks/explore-routing.d.ts.map +1 -1
- package/dist/hooks/explore-routing.js +1 -0
- package/dist/hooks/explore-routing.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +5 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +52 -8
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +4 -4
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +94 -9
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +103 -1
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/reconcile.d.ts +1 -1
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +8 -0
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/tmux.d.ts +7 -0
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +46 -9
- package/dist/hud/tmux.js.map +1 -1
- package/dist/question/deep-interview.d.ts +2 -0
- package/dist/question/deep-interview.d.ts.map +1 -1
- package/dist/question/deep-interview.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +387 -0
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +24 -2
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/state/__tests__/planning-gate.test.d.ts +2 -0
- package/dist/state/__tests__/planning-gate.test.d.ts.map +1 -0
- package/dist/state/__tests__/planning-gate.test.js +219 -0
- package/dist/state/__tests__/planning-gate.test.js.map +1 -0
- package/dist/state/workflow-transition.d.ts +23 -0
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +63 -0
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +86 -0
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +7 -0
- package/dist/team/tmux-session.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +10 -0
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +6 -2
- package/prompts/scholastic.md +11 -0
- package/skills/deep-interview/SKILL.md +10 -0
- package/skills/ralplan/SKILL.md +6 -2
- package/src/scripts/__tests__/codex-native-hook.test.ts +485 -0
- package/src/scripts/codex-native-hook.ts +23 -1
- package/templates/catalog-manifest.json +5 -0
|
@@ -8,6 +8,21 @@ import { detectKeywords, detectPrimaryKeyword, recordSkillActivation, DEEP_INTER
|
|
|
8
8
|
import { SKILL_ACTIVE_STATE_FILE } from '../../state/skill-active.js';
|
|
9
9
|
import { isUnderspecifiedForExecution, applyRalplanGate } from '../keyword-detector.js';
|
|
10
10
|
import { KEYWORD_TRIGGER_DEFINITIONS } from '../keyword-registry.js';
|
|
11
|
+
async function withIsolatedHome(prefix, run) {
|
|
12
|
+
const homeDir = await mkdtemp(join(tmpdir(), `omx-keyword-home-${prefix}-`));
|
|
13
|
+
const previousHome = process.env.HOME;
|
|
14
|
+
try {
|
|
15
|
+
process.env.HOME = homeDir;
|
|
16
|
+
return await run(homeDir);
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
if (typeof previousHome === 'string')
|
|
20
|
+
process.env.HOME = previousHome;
|
|
21
|
+
else
|
|
22
|
+
delete process.env.HOME;
|
|
23
|
+
await rm(homeDir, { recursive: true, force: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
11
26
|
describe('keyword detector team compatibility', () => {
|
|
12
27
|
it('keeps explicit $skill order in detectKeywords results (left-to-right)', () => {
|
|
13
28
|
const matches = detectKeywords('$analyze $ultraqa $code-review now');
|
|
@@ -1079,6 +1094,292 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
1079
1094
|
await rm(cwd, { recursive: true, force: true });
|
|
1080
1095
|
}
|
|
1081
1096
|
});
|
|
1097
|
+
it('persists repo-local deep-interview config values into activation and mode state', async () => {
|
|
1098
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-config-'));
|
|
1099
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1100
|
+
try {
|
|
1101
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1102
|
+
await mkdir(stateDir, { recursive: true });
|
|
1103
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), `[omx.deepInterview]
|
|
1104
|
+
defaultProfile = "standard"
|
|
1105
|
+
standardThreshold = 0.05
|
|
1106
|
+
standardMaxRounds = 15
|
|
1107
|
+
enableChallengeModes = false
|
|
1108
|
+
`);
|
|
1109
|
+
const result = await recordSkillActivation({
|
|
1110
|
+
stateDir,
|
|
1111
|
+
sourceCwd: cwd,
|
|
1112
|
+
text: '$deep-interview clarify runtime config',
|
|
1113
|
+
sessionId: 'sess-deep-interview-config',
|
|
1114
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1115
|
+
});
|
|
1116
|
+
assert.ok(result);
|
|
1117
|
+
assert.equal(result.skill, 'deep-interview');
|
|
1118
|
+
assert.equal(result.deep_interview_config?.profile, 'standard');
|
|
1119
|
+
assert.equal(result.deep_interview_config?.threshold, 0.05);
|
|
1120
|
+
assert.equal(result.deep_interview_config?.maxRounds, 15);
|
|
1121
|
+
assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-deep-interview-config/deep-interview-state.json');
|
|
1122
|
+
const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-deep-interview-config', DEEP_INTERVIEW_STATE_FILE), 'utf-8'));
|
|
1123
|
+
assert.equal(modeState.profile, 'standard');
|
|
1124
|
+
assert.equal(modeState.threshold, 0.05);
|
|
1125
|
+
assert.equal(modeState.max_rounds, 15);
|
|
1126
|
+
assert.equal(modeState.enable_challenge_modes, false);
|
|
1127
|
+
assert.equal(modeState.config_source, join(cwd, '.omx', 'config.toml'));
|
|
1128
|
+
assert.equal(modeState.deep_interview_config?.sourcePath, join(cwd, '.omx', 'config.toml'));
|
|
1129
|
+
}
|
|
1130
|
+
finally {
|
|
1131
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
it('persists deep-interview config when mixed workflow prompts defer execution modes', async () => {
|
|
1135
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-config-mixed-'));
|
|
1136
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1137
|
+
const sessionId = 'sess-deep-interview-config-mixed';
|
|
1138
|
+
try {
|
|
1139
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1140
|
+
await mkdir(stateDir, { recursive: true });
|
|
1141
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), `[omx.deepInterview]
|
|
1142
|
+
defaultProfile = "deep"
|
|
1143
|
+
deepThreshold = 0.13
|
|
1144
|
+
deepMaxRounds = 21
|
|
1145
|
+
enableChallengeModes = false
|
|
1146
|
+
`);
|
|
1147
|
+
const result = await recordSkillActivation({
|
|
1148
|
+
stateDir,
|
|
1149
|
+
sourceCwd: cwd,
|
|
1150
|
+
text: '$autopilot $deep-interview prove mixed workflow config',
|
|
1151
|
+
sessionId,
|
|
1152
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1153
|
+
});
|
|
1154
|
+
assert.ok(result);
|
|
1155
|
+
assert.equal(result.skill, 'deep-interview');
|
|
1156
|
+
assert.deepEqual(result.deferred_skills, ['autopilot']);
|
|
1157
|
+
assert.equal(result.input_lock?.active, true);
|
|
1158
|
+
assert.equal(result.deep_interview_config?.profile, 'deep');
|
|
1159
|
+
assert.equal(result.deep_interview_config?.threshold, 0.13);
|
|
1160
|
+
assert.equal(result.deep_interview_config?.maxRounds, 21);
|
|
1161
|
+
assert.equal(result.deep_interview_config?.enableChallengeModes, false);
|
|
1162
|
+
const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, DEEP_INTERVIEW_STATE_FILE), 'utf-8'));
|
|
1163
|
+
assert.equal(modeState.profile, 'deep');
|
|
1164
|
+
assert.equal(modeState.threshold, 0.13);
|
|
1165
|
+
assert.equal(modeState.max_rounds, 21);
|
|
1166
|
+
assert.equal(modeState.enable_challenge_modes, false);
|
|
1167
|
+
assert.equal(modeState.config_source, join(cwd, '.omx', 'config.toml'));
|
|
1168
|
+
assert.equal(modeState.deep_interview_config?.profile, 'deep');
|
|
1169
|
+
assert.equal(modeState.input_lock?.active, true);
|
|
1170
|
+
}
|
|
1171
|
+
finally {
|
|
1172
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1173
|
+
}
|
|
1174
|
+
});
|
|
1175
|
+
it('shows before-after state change when deep-interview config is added at runtime', async () => {
|
|
1176
|
+
await withIsolatedHome('deep-interview-config-before-after', async () => {
|
|
1177
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-config-before-after-'));
|
|
1178
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1179
|
+
const sessionId = 'sess-deep-interview-config-before-after';
|
|
1180
|
+
const statePath = join(stateDir, 'sessions', sessionId, DEEP_INTERVIEW_STATE_FILE);
|
|
1181
|
+
try {
|
|
1182
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1183
|
+
await mkdir(stateDir, { recursive: true });
|
|
1184
|
+
const before = await recordSkillActivation({
|
|
1185
|
+
stateDir,
|
|
1186
|
+
sourceCwd: cwd,
|
|
1187
|
+
text: '$deep-interview prove config before state',
|
|
1188
|
+
sessionId,
|
|
1189
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1190
|
+
});
|
|
1191
|
+
const beforeModeState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
1192
|
+
assert.ok(before);
|
|
1193
|
+
assert.equal(before.deep_interview_config, undefined);
|
|
1194
|
+
assert.equal(beforeModeState.deep_interview_config, undefined);
|
|
1195
|
+
assert.equal(beforeModeState.profile, undefined);
|
|
1196
|
+
assert.equal(beforeModeState.threshold, undefined);
|
|
1197
|
+
assert.equal(beforeModeState.max_rounds, undefined);
|
|
1198
|
+
assert.equal(beforeModeState.config_source, undefined);
|
|
1199
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), `[omx.deepInterview]
|
|
1200
|
+
defaultProfile = "standard"
|
|
1201
|
+
standardThreshold = 0.05
|
|
1202
|
+
standardMaxRounds = 15
|
|
1203
|
+
`);
|
|
1204
|
+
const after = await recordSkillActivation({
|
|
1205
|
+
stateDir,
|
|
1206
|
+
sourceCwd: cwd,
|
|
1207
|
+
text: '$deep-interview prove config after state',
|
|
1208
|
+
sessionId,
|
|
1209
|
+
nowIso: '2026-02-25T00:00:01.000Z',
|
|
1210
|
+
});
|
|
1211
|
+
const afterModeState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
1212
|
+
assert.ok(after);
|
|
1213
|
+
assert.equal(after.deep_interview_config?.profile, 'standard');
|
|
1214
|
+
assert.equal(after.deep_interview_config?.threshold, 0.05);
|
|
1215
|
+
assert.equal(after.deep_interview_config?.maxRounds, 15);
|
|
1216
|
+
assert.equal(afterModeState.deep_interview_config?.profile, 'standard');
|
|
1217
|
+
assert.equal(afterModeState.profile, 'standard');
|
|
1218
|
+
assert.equal(afterModeState.threshold, 0.05);
|
|
1219
|
+
assert.equal(afterModeState.max_rounds, 15);
|
|
1220
|
+
assert.equal(afterModeState.config_source, join(cwd, '.omx', 'config.toml'));
|
|
1221
|
+
}
|
|
1222
|
+
finally {
|
|
1223
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
});
|
|
1227
|
+
it('preserves deep-interview config values during continuation prompts', async () => {
|
|
1228
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-config-continuation-'));
|
|
1229
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1230
|
+
const sessionId = 'sess-deep-interview-config-continuation';
|
|
1231
|
+
const statePath = join(stateDir, 'sessions', sessionId, DEEP_INTERVIEW_STATE_FILE);
|
|
1232
|
+
try {
|
|
1233
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1234
|
+
await mkdir(stateDir, { recursive: true });
|
|
1235
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), `[omx.deepInterview]
|
|
1236
|
+
defaultProfile = "standard"
|
|
1237
|
+
standardThreshold = 0.05
|
|
1238
|
+
standardMaxRounds = 15
|
|
1239
|
+
`);
|
|
1240
|
+
await recordSkillActivation({
|
|
1241
|
+
stateDir,
|
|
1242
|
+
sourceCwd: cwd,
|
|
1243
|
+
text: '$deep-interview prove config continuation',
|
|
1244
|
+
sessionId,
|
|
1245
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1246
|
+
});
|
|
1247
|
+
const continued = await recordSkillActivation({
|
|
1248
|
+
stateDir,
|
|
1249
|
+
sourceCwd: cwd,
|
|
1250
|
+
text: 'continue',
|
|
1251
|
+
sessionId,
|
|
1252
|
+
nowIso: '2026-02-25T00:00:01.000Z',
|
|
1253
|
+
});
|
|
1254
|
+
const modeState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
1255
|
+
assert.equal(continued?.skill, 'deep-interview');
|
|
1256
|
+
assert.equal(continued?.deep_interview_config?.profile, 'standard');
|
|
1257
|
+
assert.equal(continued?.deep_interview_config?.threshold, 0.05);
|
|
1258
|
+
assert.equal(continued?.deep_interview_config?.maxRounds, 15);
|
|
1259
|
+
assert.equal(modeState.deep_interview_config?.profile, 'standard');
|
|
1260
|
+
assert.equal(modeState.profile, 'standard');
|
|
1261
|
+
assert.equal(modeState.threshold, 0.05);
|
|
1262
|
+
assert.equal(modeState.max_rounds, 15);
|
|
1263
|
+
}
|
|
1264
|
+
finally {
|
|
1265
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1268
|
+
it('preserves explicit deep-interview profile flags during continuation prompts', async () => {
|
|
1269
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-config-profile-continuation-'));
|
|
1270
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1271
|
+
const sessionId = 'sess-deep-interview-config-profile-continuation';
|
|
1272
|
+
const statePath = join(stateDir, 'sessions', sessionId, DEEP_INTERVIEW_STATE_FILE);
|
|
1273
|
+
try {
|
|
1274
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1275
|
+
await mkdir(stateDir, { recursive: true });
|
|
1276
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), `[omx.deepInterview]
|
|
1277
|
+
defaultProfile = "standard"
|
|
1278
|
+
standardThreshold = 0.22
|
|
1279
|
+
standardMaxRounds = 13
|
|
1280
|
+
deepThreshold = 0.13
|
|
1281
|
+
deepMaxRounds = 21
|
|
1282
|
+
`);
|
|
1283
|
+
const started = await recordSkillActivation({
|
|
1284
|
+
stateDir,
|
|
1285
|
+
sourceCwd: cwd,
|
|
1286
|
+
text: '$deep-interview --deep prove explicit profile continuation',
|
|
1287
|
+
sessionId,
|
|
1288
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1289
|
+
});
|
|
1290
|
+
const continued = await recordSkillActivation({
|
|
1291
|
+
stateDir,
|
|
1292
|
+
sourceCwd: cwd,
|
|
1293
|
+
text: 'continue',
|
|
1294
|
+
sessionId,
|
|
1295
|
+
nowIso: '2026-02-25T00:00:01.000Z',
|
|
1296
|
+
});
|
|
1297
|
+
const modeState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
1298
|
+
assert.equal(started?.deep_interview_config?.profile, 'deep');
|
|
1299
|
+
assert.equal(continued?.deep_interview_config?.profile, 'deep');
|
|
1300
|
+
assert.equal(continued?.deep_interview_config?.threshold, 0.13);
|
|
1301
|
+
assert.equal(continued?.deep_interview_config?.maxRounds, 21);
|
|
1302
|
+
assert.equal(modeState.deep_interview_config?.profile, 'deep');
|
|
1303
|
+
assert.equal(modeState.profile, 'deep');
|
|
1304
|
+
assert.equal(modeState.threshold, 0.13);
|
|
1305
|
+
assert.equal(modeState.max_rounds, 21);
|
|
1306
|
+
}
|
|
1307
|
+
finally {
|
|
1308
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
it('keeps the documented deep-interview Suggested Config executable through activation state', async () => {
|
|
1312
|
+
const skillDoc = await readFile(join(process.cwd(), 'skills', 'deep-interview', 'SKILL.md'), 'utf-8');
|
|
1313
|
+
const markerIndex = skillDoc.indexOf('## Suggested Config (optional)');
|
|
1314
|
+
assert.notEqual(markerIndex, -1);
|
|
1315
|
+
const configMatch = skillDoc.slice(markerIndex).match(/```toml\n([\s\S]*?)\n```/);
|
|
1316
|
+
assert.ok(configMatch);
|
|
1317
|
+
const documentedConfig = configMatch[1]?.trimEnd();
|
|
1318
|
+
assert.ok(documentedConfig);
|
|
1319
|
+
assert.match(documentedConfig, /standardThreshold = 0\.20/);
|
|
1320
|
+
assert.match(documentedConfig, /standardMaxRounds = 12/);
|
|
1321
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-doc-config-'));
|
|
1322
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1323
|
+
const sessionId = 'sess-deep-interview-doc-config';
|
|
1324
|
+
const statePath = join(stateDir, 'sessions', sessionId, DEEP_INTERVIEW_STATE_FILE);
|
|
1325
|
+
try {
|
|
1326
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1327
|
+
await mkdir(stateDir, { recursive: true });
|
|
1328
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), `${documentedConfig}\n`);
|
|
1329
|
+
const result = await recordSkillActivation({
|
|
1330
|
+
stateDir,
|
|
1331
|
+
sourceCwd: cwd,
|
|
1332
|
+
text: '$deep-interview prove documented config runtime contract',
|
|
1333
|
+
sessionId,
|
|
1334
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1335
|
+
});
|
|
1336
|
+
const modeState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
1337
|
+
assert.ok(result);
|
|
1338
|
+
assert.equal(result.deep_interview_config?.profile, 'standard');
|
|
1339
|
+
assert.equal(result.deep_interview_config?.threshold, 0.2);
|
|
1340
|
+
assert.equal(result.deep_interview_config?.maxRounds, 12);
|
|
1341
|
+
assert.equal(modeState.deep_interview_config?.profile, 'standard');
|
|
1342
|
+
assert.equal(modeState.profile, 'standard');
|
|
1343
|
+
assert.equal(modeState.threshold, 0.2);
|
|
1344
|
+
assert.equal(modeState.max_rounds, 12);
|
|
1345
|
+
assert.equal(modeState.config_source, join(cwd, '.omx', 'config.toml'));
|
|
1346
|
+
}
|
|
1347
|
+
finally {
|
|
1348
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1349
|
+
}
|
|
1350
|
+
});
|
|
1351
|
+
it('keeps deep-interview activation alive when repo config TOML is malformed', async () => {
|
|
1352
|
+
await withIsolatedHome('deep-interview-malformed-config', async () => {
|
|
1353
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-malformed-config-'));
|
|
1354
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1355
|
+
const originalWarn = console.warn;
|
|
1356
|
+
try {
|
|
1357
|
+
console.warn = () => { };
|
|
1358
|
+
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
1359
|
+
await mkdir(stateDir, { recursive: true });
|
|
1360
|
+
await writeFile(join(cwd, '.omx', 'config.toml'), '[omx.deepInterview\nstandardThreshold = 0.05\n');
|
|
1361
|
+
const result = await recordSkillActivation({
|
|
1362
|
+
stateDir,
|
|
1363
|
+
sourceCwd: cwd,
|
|
1364
|
+
text: '$deep-interview clarify despite malformed config',
|
|
1365
|
+
sessionId: 'sess-deep-interview-malformed-config',
|
|
1366
|
+
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1367
|
+
});
|
|
1368
|
+
assert.ok(result);
|
|
1369
|
+
assert.equal(result.skill, 'deep-interview');
|
|
1370
|
+
assert.equal(result.active, true);
|
|
1371
|
+
assert.equal(result.deep_interview_config, undefined);
|
|
1372
|
+
const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-deep-interview-malformed-config', DEEP_INTERVIEW_STATE_FILE), 'utf-8'));
|
|
1373
|
+
assert.equal(modeState.mode, 'deep-interview');
|
|
1374
|
+
assert.equal(modeState.active, true);
|
|
1375
|
+
assert.equal(modeState.deep_interview_config, undefined);
|
|
1376
|
+
}
|
|
1377
|
+
finally {
|
|
1378
|
+
console.warn = originalWarn;
|
|
1379
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
});
|
|
1082
1383
|
it('creates the session-scoped deep-interview state directory before persisting mode state', async () => {
|
|
1083
1384
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-session-dir-'));
|
|
1084
1385
|
const stateDir = join(cwd, '.omx', 'state');
|