oh-my-codex 0.21.26 → 0.21.28
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 +6 -6
- package/Cargo.toml +1 -1
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +37 -0
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/cli/__tests__/jetbrains-scroll-diagnostic.test.d.ts +2 -0
- package/dist/cli/__tests__/jetbrains-scroll-diagnostic.test.d.ts.map +1 -0
- package/dist/cli/__tests__/jetbrains-scroll-diagnostic.test.js +60 -0
- package/dist/cli/__tests__/jetbrains-scroll-diagnostic.test.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/leader/__tests__/contract.test.js +2 -2
- package/dist/leader/__tests__/contract.test.js.map +1 -1
- package/dist/leader/contract.d.ts +1 -1
- package/dist/leader/contract.d.ts.map +1 -1
- package/dist/leader/contract.js +1 -1
- package/dist/leader/contract.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +73 -4
- 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 +20 -0
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/subagents/__tests__/tracker.test.js +106 -10
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/tracker.d.ts +7 -0
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +54 -8
- package/dist/subagents/tracker.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/src/scripts/__tests__/codex-native-hook.test.ts +87 -4
- package/src/scripts/codex-native-hook.ts +23 -0
|
@@ -179,7 +179,7 @@ describe('subagents/tracker', () => {
|
|
|
179
179
|
nested: { thread_id: 'nested', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'direct', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
|
|
180
180
|
revoked: { thread_id: 'revoked', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: true, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
|
|
181
181
|
} } } }));
|
|
182
|
-
const context = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
182
|
+
const context = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '';
|
|
183
183
|
assert.match(context, /resume_agent\("direct"\)/);
|
|
184
184
|
assert.doesNotMatch(context, /resume_agent\("root"\)|resume_agent\("nested"\)|resume_agent\("revoked"\)/);
|
|
185
185
|
const persisted = JSON.parse(readFileSync(path, 'utf8'));
|
|
@@ -204,7 +204,7 @@ describe('subagents/tracker', () => {
|
|
|
204
204
|
const repaired = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
|
|
205
205
|
assert.equal(repaired.sessions.canonical.threads.child.reopen_authority_revoked, undefined);
|
|
206
206
|
assert.equal(repaired.sessions['root-a'].threads.child.reopen_authority_revoked, undefined);
|
|
207
|
-
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root-a', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
|
|
207
|
+
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root-a', source: 'resume', availableTools: ['resume_agent'] }) ?? '', /resume_agent\("child"\)/);
|
|
208
208
|
}
|
|
209
209
|
finally {
|
|
210
210
|
rmSync(cwd, { recursive: true, force: true });
|
|
@@ -312,7 +312,7 @@ describe('subagents/tracker', () => {
|
|
|
312
312
|
recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root' });
|
|
313
313
|
const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
|
|
314
314
|
assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, undefined);
|
|
315
|
-
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
|
|
315
|
+
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '', /resume_agent\("child"\)/);
|
|
316
316
|
}
|
|
317
317
|
finally {
|
|
318
318
|
rmSync(cwd, { recursive: true, force: true });
|
|
@@ -341,7 +341,7 @@ describe('subagents/tracker', () => {
|
|
|
341
341
|
legacy: { thread_id: 'legacy', kind: 'subagent', provenance_kind: 'adapted', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
|
|
342
342
|
} } } }));
|
|
343
343
|
recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
|
|
344
|
-
const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
344
|
+
const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '';
|
|
345
345
|
assert.match(context, /resume_agent\("child"\)/);
|
|
346
346
|
assert.doesNotMatch(context, /resume_agent\("legacy"\)/);
|
|
347
347
|
}
|
|
@@ -360,7 +360,7 @@ describe('subagents/tracker', () => {
|
|
|
360
360
|
} },
|
|
361
361
|
} }));
|
|
362
362
|
recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
|
|
363
|
-
const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
363
|
+
const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '';
|
|
364
364
|
assert.match(context, /resume_agent\("child"\)/);
|
|
365
365
|
const persisted = JSON.parse(readFileSync(path, 'utf8'));
|
|
366
366
|
assert.equal(persisted.sessions.correlation.threads.child.provenance_kind, DESCRIPTIVE_ADAPTED_PROVENANCE);
|
|
@@ -528,7 +528,7 @@ describe('subagents/tracker', () => {
|
|
|
528
528
|
const snapshot = await readSubagentTrackingState(cwd);
|
|
529
529
|
const descriptive = recordSubagentTurn(snapshot, { sessionId: 'canonical', threadId: 'child', kind: 'subagent' });
|
|
530
530
|
await writeSubagentTrackingState(cwd, descriptive);
|
|
531
|
-
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
|
|
531
|
+
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '', /resume_agent\("child"\)/);
|
|
532
532
|
}
|
|
533
533
|
finally {
|
|
534
534
|
rmSync(cwd, { recursive: true, force: true });
|
|
@@ -584,7 +584,7 @@ describe('subagents/tracker', () => {
|
|
|
584
584
|
const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-authority-fence-'));
|
|
585
585
|
try {
|
|
586
586
|
recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
|
|
587
|
-
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
|
|
587
|
+
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '', /resume_agent\("child"\)/);
|
|
588
588
|
// Simulate a revocation whose transaction failed: the tracker still shows
|
|
589
589
|
// valid authority, but the fence records the unpublished denial.
|
|
590
590
|
fenceNativeSubagentAuthorities(cwd, ['child'], 'identity_untrusted_revocation_failed');
|
|
@@ -675,7 +675,7 @@ describe('subagents/tracker', () => {
|
|
|
675
675
|
const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-global-denial-'));
|
|
676
676
|
try {
|
|
677
677
|
recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
|
|
678
|
-
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
|
|
678
|
+
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '', /resume_agent\("child"\)/);
|
|
679
679
|
// Simulates both the tracker revocation AND the locked fence failing.
|
|
680
680
|
assert.equal(forceGlobalAuthorityDenial(cwd, 'identity_untrusted_denial_escalated'), true);
|
|
681
681
|
assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /unreadable_authority_fence/);
|
|
@@ -840,6 +840,102 @@ describe('subagents/tracker', () => {
|
|
|
840
840
|
rmSync(cwd, { recursive: true, force: true });
|
|
841
841
|
}
|
|
842
842
|
});
|
|
843
|
+
it('covers hosts without resume_agent in SessionStart reopen guidance', () => {
|
|
844
|
+
const cwd = mkdtempSync(join(tmpdir(), 'omx-3866-tracker-no-resume-tool-'));
|
|
845
|
+
try {
|
|
846
|
+
const path = subagentTrackingPath(cwd);
|
|
847
|
+
mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
|
|
848
|
+
writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
|
|
849
|
+
child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
|
|
850
|
+
} } } }));
|
|
851
|
+
// With partial availableTools not including resume_agent, availability is unknown:
|
|
852
|
+
// guidance lists targets and explicitly checks availability before requiring invocation (issue #3866)
|
|
853
|
+
const contextUnknown = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: ['Read', 'Edit'] }) ?? '';
|
|
854
|
+
assert.match(contextUnknown, /Unknown: resume_agent tool availability could not be determined/);
|
|
855
|
+
assert.match(contextUnknown, /"child"/);
|
|
856
|
+
assert.match(contextUnknown, /If resume_agent is callable, use resume_agent\(<id>\)/);
|
|
857
|
+
assert.match(contextUnknown, /If resume_agent is not callable, continue in the root/);
|
|
858
|
+
// Without availableTools provided, availability is also unknown (no inventory to check)
|
|
859
|
+
const contextNoInventory = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
860
|
+
assert.match(contextNoInventory, /Unknown: resume_agent tool availability could not be determined/);
|
|
861
|
+
assert.match(contextNoInventory, /"child"/);
|
|
862
|
+
// With resume_agent explicitly in availableTools, guidance instructs the call
|
|
863
|
+
const contextWithTool = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: ['read', 'resume_agent', 'edit'] }) ?? '';
|
|
864
|
+
assert.match(contextWithTool, /Reopen these persisted subagents/);
|
|
865
|
+
assert.match(contextWithTool, /resume_agent\("child"\)/);
|
|
866
|
+
assert.doesNotMatch(contextWithTool, /Unknown/);
|
|
867
|
+
}
|
|
868
|
+
finally {
|
|
869
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
it('handles tool inventory with object entry shapes (name/tool_name/toolName fields)', () => {
|
|
873
|
+
const cwd = mkdtempSync(join(tmpdir(), 'omx-3866-tracker-tool-objects-'));
|
|
874
|
+
try {
|
|
875
|
+
const path = subagentTrackingPath(cwd);
|
|
876
|
+
mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
|
|
877
|
+
writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
|
|
878
|
+
child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
|
|
879
|
+
} } } }));
|
|
880
|
+
// Object entry with 'name' field
|
|
881
|
+
const contextNameField = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: [{ name: 'Read' }, { name: 'resume_agent' }, { name: 'Edit' }] }) ?? '';
|
|
882
|
+
assert.match(contextNameField, /Reopen these persisted subagents/);
|
|
883
|
+
assert.match(contextNameField, /resume_agent\("child"\)/);
|
|
884
|
+
// Object entry with 'tool_name' field
|
|
885
|
+
const contextToolName = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: [{ tool_name: 'Read' }, { tool_name: 'resume_agent' }] }) ?? '';
|
|
886
|
+
assert.match(contextToolName, /Reopen these persisted subagents/);
|
|
887
|
+
assert.match(contextToolName, /resume_agent\("child"\)/);
|
|
888
|
+
// Object entry with 'toolName' field
|
|
889
|
+
const contextToolNameCamel = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: [{ toolName: 'Read' }, { toolName: 'resume_agent' }] }) ?? '';
|
|
890
|
+
assert.match(contextToolNameCamel, /Reopen these persisted subagents/);
|
|
891
|
+
assert.match(contextToolNameCamel, /resume_agent\("child"\)/);
|
|
892
|
+
// Object entry without matching fields (unknown)
|
|
893
|
+
const contextEmptyObject = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume', availableTools: [{ name: undefined, tool_name: undefined, toolName: undefined }] }) ?? '';
|
|
894
|
+
assert.match(contextEmptyObject, /Unknown: resume_agent tool availability could not be determined/);
|
|
895
|
+
assert.match(contextEmptyObject, /If resume_agent is callable/);
|
|
896
|
+
}
|
|
897
|
+
finally {
|
|
898
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
it('emits unavailable warning when explicit unsupported native subagent evidence is provided', () => {
|
|
902
|
+
const cwd = mkdtempSync(join(tmpdir(), 'omx-3866-tracker-unsupported-evidence-'));
|
|
903
|
+
try {
|
|
904
|
+
const path = subagentTrackingPath(cwd);
|
|
905
|
+
mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
|
|
906
|
+
writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
|
|
907
|
+
child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
|
|
908
|
+
} } } }));
|
|
909
|
+
// With explicit unsupported evidence, resume_agent is unavailable even with tool in inventory
|
|
910
|
+
const unsupportedEvidence = { status: 'unsupported', reason: 'native_subagents_unsupported', source: 'hook_payload_capability', evidenceSummary: 'test evidence' };
|
|
911
|
+
const contextUnavailable = consumeDirectChildReopenContext(cwd, {
|
|
912
|
+
sessionId: 'root',
|
|
913
|
+
rootNativeSessionId: 'root',
|
|
914
|
+
source: 'resume',
|
|
915
|
+
availableTools: ['read', 'resume_agent', 'edit'],
|
|
916
|
+
unsupportedNativeSubagentEvidence: unsupportedEvidence,
|
|
917
|
+
}) ?? '';
|
|
918
|
+
// Should emit warning about unavailable resume_agent
|
|
919
|
+
assert.match(contextUnavailable, /Warning: resume_agent tool is not available/);
|
|
920
|
+
assert.doesNotMatch(contextUnavailable, /resume_agent\(/);
|
|
921
|
+
assert.match(contextUnavailable, /Do not spawn a same-role\/same-lane replacement/);
|
|
922
|
+
// With unsupported evidence but without availableTools, still unavailable (not unknown)
|
|
923
|
+
const contextUnavailableNoTools = consumeDirectChildReopenContext(cwd, {
|
|
924
|
+
sessionId: 'root',
|
|
925
|
+
rootNativeSessionId: 'root',
|
|
926
|
+
source: 'resume',
|
|
927
|
+
unsupportedNativeSubagentEvidence: unsupportedEvidence,
|
|
928
|
+
}) ?? '';
|
|
929
|
+
assert.match(contextUnavailableNoTools, /Warning: resume_agent tool is not available/);
|
|
930
|
+
assert.doesNotMatch(contextUnavailableNoTools, /Unknown:/);
|
|
931
|
+
// Without unsupported evidence, back to unknown state (no tools in inventory)
|
|
932
|
+
const contextUnknown = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
933
|
+
assert.match(contextUnknown, /Unknown: resume_agent tool availability could not be determined/);
|
|
934
|
+
}
|
|
935
|
+
finally {
|
|
936
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
937
|
+
}
|
|
938
|
+
});
|
|
843
939
|
it('revokes direct-child authority when an authoritative observation moves it under a nested parent', () => {
|
|
844
940
|
const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-direct-to-nested-'));
|
|
845
941
|
try {
|
|
@@ -872,7 +968,7 @@ describe('subagents/tracker', () => {
|
|
|
872
968
|
const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-reopen-first-'));
|
|
873
969
|
try {
|
|
874
970
|
recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root' });
|
|
875
|
-
const first = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
971
|
+
const first = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '';
|
|
876
972
|
assert.match(first, /resume_agent\("child"\)/);
|
|
877
973
|
const requestedAt = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.resume_requested_at;
|
|
878
974
|
assert.match(requestedAt, /^\d{4}-\d{2}-\d{2}T/);
|
|
@@ -925,7 +1021,7 @@ describe('subagents/tracker', () => {
|
|
|
925
1021
|
competitor = spawnAuthorityCompetitor(cwd, 'revoke', readyPath, resultPath);
|
|
926
1022
|
waitForFileSync(readyPath, 10_000);
|
|
927
1023
|
});
|
|
928
|
-
const first = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
|
|
1024
|
+
const first = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume', availableTools: ['resume_agent'] }) ?? '';
|
|
929
1025
|
__setCrossProcessPublishBarrierForTest(null);
|
|
930
1026
|
assert.match(first, /resume_agent\("child"\)/);
|
|
931
1027
|
const requestedAt = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.resume_requested_at;
|