@ai-devkit/agent-manager 0.20.0 → 0.22.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/dist/__tests__/adapters/CodexAdapter.test.js +163 -0
- package/dist/__tests__/adapters/CodexAdapter.test.js.map +1 -1
- package/dist/adapters/CodexAdapter.d.ts +11 -4
- package/dist/adapters/CodexAdapter.d.ts.map +1 -1
- package/dist/adapters/CodexAdapter.js +81 -5
- package/dist/adapters/CodexAdapter.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/adapters/CodexAdapter.test.ts +121 -0
- package/src/adapters/CodexAdapter.ts +98 -6
|
@@ -635,6 +635,169 @@ describe('CodexAdapter', ()=>{
|
|
|
635
635
|
});
|
|
636
636
|
}
|
|
637
637
|
});
|
|
638
|
+
it('should map a running Codex process from the hook session mapping', async ()=>{
|
|
639
|
+
const originalHome = process.env.HOME;
|
|
640
|
+
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'codex-mapping-'));
|
|
641
|
+
process.env.HOME = tmpHome;
|
|
642
|
+
try {
|
|
643
|
+
const mappedAdapter = new CodexAdapter(new AgentRegistry(path.join(tmpHome, 'agents.json')));
|
|
644
|
+
const sessionsDir = path.join(tmpHome, '.codex', 'sessions');
|
|
645
|
+
const dateDir = path.join(sessionsDir, '2026', '06', '26');
|
|
646
|
+
const mappingPath = path.join(tmpHome, '.codex', 'ai-devkit', 'sessions.json');
|
|
647
|
+
const sessionFile = path.join(dateDir, 'rollout-2026-06-26T09-56-12-sess-mapped.jsonl');
|
|
648
|
+
const recentTs = new Date().toISOString();
|
|
649
|
+
fs.mkdirSync(dateDir, {
|
|
650
|
+
recursive: true
|
|
651
|
+
});
|
|
652
|
+
fs.mkdirSync(path.dirname(mappingPath), {
|
|
653
|
+
recursive: true
|
|
654
|
+
});
|
|
655
|
+
fs.writeFileSync(sessionFile, [
|
|
656
|
+
JSON.stringify({
|
|
657
|
+
type: 'session_meta',
|
|
658
|
+
payload: {
|
|
659
|
+
id: 'sess-mapped',
|
|
660
|
+
timestamp: recentTs,
|
|
661
|
+
cwd: '/repo-mapped'
|
|
662
|
+
}
|
|
663
|
+
}),
|
|
664
|
+
JSON.stringify({
|
|
665
|
+
type: 'event',
|
|
666
|
+
timestamp: recentTs,
|
|
667
|
+
payload: {
|
|
668
|
+
type: 'agent_message',
|
|
669
|
+
message: 'mapped conversation'
|
|
670
|
+
}
|
|
671
|
+
})
|
|
672
|
+
].join('\n'));
|
|
673
|
+
fs.writeFileSync(mappingPath, JSON.stringify({
|
|
674
|
+
5151: sessionFile
|
|
675
|
+
}));
|
|
676
|
+
const processes = [
|
|
677
|
+
{
|
|
678
|
+
pid: 5151,
|
|
679
|
+
command: 'codex',
|
|
680
|
+
cwd: '/repo-mapped',
|
|
681
|
+
tty: 'ttys001',
|
|
682
|
+
startTime: new Date('2026-06-26T09:56:12.000Z')
|
|
683
|
+
}
|
|
684
|
+
];
|
|
685
|
+
mockedListAgentProcesses.mockReturnValue(processes);
|
|
686
|
+
mockedEnrichProcesses.mockReturnValue(processes);
|
|
687
|
+
const agents = await mappedAdapter.detectAgents();
|
|
688
|
+
expect(agents).toHaveLength(1);
|
|
689
|
+
expect(agents[0]).toMatchObject({
|
|
690
|
+
type: 'codex',
|
|
691
|
+
pid: 5151,
|
|
692
|
+
sessionId: 'sess-mapped',
|
|
693
|
+
projectPath: '/repo-mapped',
|
|
694
|
+
summary: 'mapped conversation',
|
|
695
|
+
sessionFilePath: sessionFile
|
|
696
|
+
});
|
|
697
|
+
expect(mockedBatchGetSessionFileBirthtimes).not.toHaveBeenCalled();
|
|
698
|
+
expect(mockedMatchProcessesToSessions).not.toHaveBeenCalled();
|
|
699
|
+
} finally{
|
|
700
|
+
process.env.HOME = originalHome;
|
|
701
|
+
fs.rmSync(tmpHome, {
|
|
702
|
+
recursive: true,
|
|
703
|
+
force: true
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
it('should fall back to legacy matching when mapped session file cannot be parsed', async ()=>{
|
|
708
|
+
const originalHome = process.env.HOME;
|
|
709
|
+
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'codex-mapping-fallback-'));
|
|
710
|
+
process.env.HOME = tmpHome;
|
|
711
|
+
try {
|
|
712
|
+
const mappedAdapter = new CodexAdapter(new AgentRegistry(path.join(tmpHome, 'agents.json')));
|
|
713
|
+
const sessionsDir = path.join(tmpHome, '.codex', 'sessions');
|
|
714
|
+
const dateDir = path.join(sessionsDir, '2026', '06', '26');
|
|
715
|
+
const mappingPath = path.join(tmpHome, '.codex', 'ai-devkit', 'sessions.json');
|
|
716
|
+
const badSessionFile = path.join(dateDir, 'bad.jsonl');
|
|
717
|
+
const fallbackSessionFile = path.join(dateDir, 'fallback.jsonl');
|
|
718
|
+
const recentTs = new Date().toISOString();
|
|
719
|
+
fs.mkdirSync(dateDir, {
|
|
720
|
+
recursive: true
|
|
721
|
+
});
|
|
722
|
+
fs.mkdirSync(path.dirname(mappingPath), {
|
|
723
|
+
recursive: true
|
|
724
|
+
});
|
|
725
|
+
fs.writeFileSync(badSessionFile, '{not-json');
|
|
726
|
+
fs.writeFileSync(fallbackSessionFile, [
|
|
727
|
+
JSON.stringify({
|
|
728
|
+
type: 'session_meta',
|
|
729
|
+
payload: {
|
|
730
|
+
id: 'sess-fallback',
|
|
731
|
+
timestamp: recentTs,
|
|
732
|
+
cwd: '/repo-fallback'
|
|
733
|
+
}
|
|
734
|
+
}),
|
|
735
|
+
JSON.stringify({
|
|
736
|
+
type: 'event',
|
|
737
|
+
timestamp: recentTs,
|
|
738
|
+
payload: {
|
|
739
|
+
type: 'token_count',
|
|
740
|
+
message: 'fallback conversation'
|
|
741
|
+
}
|
|
742
|
+
})
|
|
743
|
+
].join('\n'));
|
|
744
|
+
fs.writeFileSync(mappingPath, JSON.stringify({
|
|
745
|
+
6161: badSessionFile
|
|
746
|
+
}));
|
|
747
|
+
const processes = [
|
|
748
|
+
{
|
|
749
|
+
pid: 6161,
|
|
750
|
+
command: 'codex',
|
|
751
|
+
cwd: '/repo-fallback',
|
|
752
|
+
tty: 'ttys001',
|
|
753
|
+
startTime: new Date('2026-06-26T09:56:12.000Z')
|
|
754
|
+
}
|
|
755
|
+
];
|
|
756
|
+
const fallbackSession = {
|
|
757
|
+
sessionId: 'sess-fallback',
|
|
758
|
+
filePath: fallbackSessionFile,
|
|
759
|
+
projectDir: dateDir,
|
|
760
|
+
birthtimeMs: new Date('2026-06-26T09:56:15.000Z').getTime(),
|
|
761
|
+
resolvedCwd: ''
|
|
762
|
+
};
|
|
763
|
+
mockedListAgentProcesses.mockReturnValue(processes);
|
|
764
|
+
mockedEnrichProcesses.mockReturnValue(processes);
|
|
765
|
+
mockedBatchGetSessionFileBirthtimes.mockReturnValue([
|
|
766
|
+
fallbackSession
|
|
767
|
+
]);
|
|
768
|
+
mockedMatchProcessesToSessions.mockReturnValue([
|
|
769
|
+
{
|
|
770
|
+
process: processes[0],
|
|
771
|
+
session: {
|
|
772
|
+
...fallbackSession,
|
|
773
|
+
resolvedCwd: '/repo-fallback'
|
|
774
|
+
},
|
|
775
|
+
deltaMs: 3000
|
|
776
|
+
}
|
|
777
|
+
]);
|
|
778
|
+
const agents = await mappedAdapter.detectAgents();
|
|
779
|
+
expect(agents).toHaveLength(1);
|
|
780
|
+
expect(agents[0]).toMatchObject({
|
|
781
|
+
pid: 6161,
|
|
782
|
+
sessionId: 'sess-fallback',
|
|
783
|
+
summary: 'fallback conversation',
|
|
784
|
+
sessionFilePath: fallbackSessionFile
|
|
785
|
+
});
|
|
786
|
+
expect(mockedMatchProcessesToSessions).toHaveBeenCalledWith([
|
|
787
|
+
processes[0]
|
|
788
|
+
], expect.arrayContaining([
|
|
789
|
+
expect.objectContaining({
|
|
790
|
+
filePath: fallbackSessionFile
|
|
791
|
+
})
|
|
792
|
+
]));
|
|
793
|
+
} finally{
|
|
794
|
+
process.env.HOME = originalHome;
|
|
795
|
+
fs.rmSync(tmpHome, {
|
|
796
|
+
recursive: true,
|
|
797
|
+
force: true
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
});
|
|
638
801
|
});
|
|
639
802
|
describe('detectAgents — registry cache short-circuit', ()=>{
|
|
640
803
|
let tmpDir;
|