Skip to content

Commit 3d1f1b1

Browse files
committed
chore(cli): refactor ClaudeCodeAdapter
1 parent cbcc219 commit 3d1f1b1

3 files changed

Lines changed: 429 additions & 394 deletions

File tree

packages/agent-manager/src/__tests__/adapters/ClaudeCodeAdapter.test.ts

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ describe('ClaudeCodeAdapter', () => {
361361
(adapter as any).projectsDir = projectsDir;
362362

363363
// Simulate JSONL disappearing between existence check and read
364-
jest.spyOn(adapter as any, 'readSession').mockReturnValueOnce(null);
364+
jest.spyOn((adapter as any).parser, 'readSession').mockReturnValueOnce(null);
365365

366366
const agents = await adapter.detectAgents();
367367

@@ -408,7 +408,7 @@ describe('ClaudeCodeAdapter', () => {
408408
]);
409409

410410
// Simulate JSONL disappearing between match and read
411-
jest.spyOn(adapter as any, 'readSession').mockReturnValueOnce(null);
411+
jest.spyOn((adapter as any).parser, 'readSession').mockReturnValueOnce(null);
412412

413413
const agents = await adapter.detectAgents();
414414

@@ -601,7 +601,7 @@ describe('ClaudeCodeAdapter', () => {
601601
describe('helper methods', () => {
602602
describe('determineStatus', () => {
603603
it('should return "unknown" for sessions with no last entry type', () => {
604-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
604+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
605605

606606
const session = {
607607
sessionId: 'test',
@@ -615,7 +615,7 @@ describe('ClaudeCodeAdapter', () => {
615615
});
616616

617617
it('should return "waiting" for assistant entries', () => {
618-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
618+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
619619

620620
const session = {
621621
sessionId: 'test',
@@ -630,7 +630,7 @@ describe('ClaudeCodeAdapter', () => {
630630
});
631631

632632
it('should return "waiting" for user interruption', () => {
633-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
633+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
634634

635635
const session = {
636636
sessionId: 'test',
@@ -645,7 +645,7 @@ describe('ClaudeCodeAdapter', () => {
645645
});
646646

647647
it('should return "running" for user/progress entries', () => {
648-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
648+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
649649

650650
const session = {
651651
sessionId: 'test',
@@ -660,7 +660,7 @@ describe('ClaudeCodeAdapter', () => {
660660
});
661661

662662
it('should not override status based on age (process is running)', () => {
663-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
663+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
664664

665665
const oldDate = new Date(Date.now() - 10 * 60 * 1000);
666666
const session = {
@@ -676,7 +676,7 @@ describe('ClaudeCodeAdapter', () => {
676676
});
677677

678678
it('should return "idle" for system entries', () => {
679-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
679+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
680680

681681
const session = {
682682
sessionId: 'test',
@@ -691,7 +691,7 @@ describe('ClaudeCodeAdapter', () => {
691691
});
692692

693693
it('should return "running" for thinking entries', () => {
694-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
694+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
695695

696696
const session = {
697697
sessionId: 'test',
@@ -706,7 +706,7 @@ describe('ClaudeCodeAdapter', () => {
706706
});
707707

708708
it('should return "running" for progress entries', () => {
709-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
709+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
710710

711711
const session = {
712712
sessionId: 'test',
@@ -721,7 +721,7 @@ describe('ClaudeCodeAdapter', () => {
721721
});
722722

723723
it('should return "unknown" for unrecognized entry types', () => {
724-
const determineStatus = (adapter as any).determineStatus.bind(adapter);
724+
const determineStatus = (adapter as any).parser.determineStatus.bind((adapter as any).parser);
725725

726726
const session = {
727727
sessionId: 'test',
@@ -738,12 +738,12 @@ describe('ClaudeCodeAdapter', () => {
738738

739739
describe('extractUserMessageText', () => {
740740
it('should extract plain string content', () => {
741-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
741+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
742742
expect(extract('hello world')).toBe('hello world');
743743
});
744744

745745
it('should extract text from array content blocks', () => {
746-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
746+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
747747

748748
const content = [
749749
{ type: 'tool_result', content: 'some result' },
@@ -753,43 +753,43 @@ describe('ClaudeCodeAdapter', () => {
753753
});
754754

755755
it('should return undefined for empty/null content', () => {
756-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
756+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
757757

758758
expect(extract(undefined)).toBeUndefined();
759759
expect(extract('')).toBeUndefined();
760760
expect(extract([])).toBeUndefined();
761761
});
762762

763763
it('should parse command-message tags', () => {
764-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
764+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
765765

766766
const msg = '<command-message><command-name>commit</command-name><command-args>fix bug</command-args></command-message>';
767767
expect(extract(msg)).toBe('commit fix bug');
768768
});
769769

770770
it('should parse command-message without args', () => {
771-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
771+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
772772

773773
const msg = '<command-message><command-name>help</command-name></command-message>';
774774
expect(extract(msg)).toBe('help');
775775
});
776776

777777
it('should extract ARGUMENTS from skill expansion', () => {
778-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
778+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
779779

780780
const msg = 'Base directory for this skill: /some/path\n\nSome instructions\n\nARGUMENTS: implement the feature';
781781
expect(extract(msg)).toBe('implement the feature');
782782
});
783783

784784
it('should return undefined for skill expansion without ARGUMENTS', () => {
785-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
785+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
786786

787787
const msg = 'Base directory for this skill: /some/path\n\nSome instructions only';
788788
expect(extract(msg)).toBeUndefined();
789789
});
790790

791791
it('should filter noise messages', () => {
792-
const extract = (adapter as any).extractUserMessageText.bind(adapter);
792+
const extract = (adapter as any).parser['extractUserMessageText'].bind((adapter as any).parser);
793793

794794
expect(extract('[Request interrupted by user]')).toBeUndefined();
795795
expect(extract('Tool loaded.')).toBeUndefined();
@@ -799,7 +799,7 @@ describe('ClaudeCodeAdapter', () => {
799799

800800
describe('parseCommandMessage', () => {
801801
it('should return undefined for malformed command-message', () => {
802-
const parse = (adapter as any).parseCommandMessage.bind(adapter);
802+
const parse = (adapter as any).parser['parseCommandMessage'].bind((adapter as any).parser);
803803
expect(parse('<command-message>no tags</command-message>')).toBeUndefined();
804804
});
805805
});
@@ -977,7 +977,7 @@ describe('ClaudeCodeAdapter', () => {
977977

978978
describe('readSession', () => {
979979
it('should parse session file with timestamps, cwd, and entry type', () => {
980-
const readSession = (adapter as any).readSession.bind(adapter);
980+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
981981

982982
const filePath = path.join(tmpDir, 'test-session.jsonl');
983983
const lines = [
@@ -999,7 +999,7 @@ describe('ClaudeCodeAdapter', () => {
999999
});
10001000

10011001
it('should detect user interruption', () => {
1002-
const readSession = (adapter as any).readSession.bind(adapter);
1002+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10031003

10041004
const filePath = path.join(tmpDir, 'interrupted.jsonl');
10051005
const lines = [
@@ -1019,7 +1019,7 @@ describe('ClaudeCodeAdapter', () => {
10191019
});
10201020

10211021
it('should return session with defaults for empty file', () => {
1022-
const readSession = (adapter as any).readSession.bind(adapter);
1022+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10231023

10241024
const filePath = path.join(tmpDir, 'empty.jsonl');
10251025
fs.writeFileSync(filePath, '');
@@ -1030,12 +1030,12 @@ describe('ClaudeCodeAdapter', () => {
10301030
});
10311031

10321032
it('should return null for non-existent file', () => {
1033-
const readSession = (adapter as any).readSession.bind(adapter);
1033+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10341034
expect(readSession(path.join(tmpDir, 'nonexistent.jsonl'), '/test')).toBeNull();
10351035
});
10361036

10371037
it('should skip metadata entry types for lastEntryType', () => {
1038-
const readSession = (adapter as any).readSession.bind(adapter);
1038+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10391039

10401040
const filePath = path.join(tmpDir, 'metadata-test.jsonl');
10411041
const lines = [
@@ -1051,7 +1051,7 @@ describe('ClaudeCodeAdapter', () => {
10511051
});
10521052

10531053
it('should parse snapshot.timestamp from file-history-snapshot first entry', () => {
1054-
const readSession = (adapter as any).readSession.bind(adapter);
1054+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10551055

10561056
const filePath = path.join(tmpDir, 'snapshot-ts.jsonl');
10571057
const lines = [
@@ -1070,7 +1070,7 @@ describe('ClaudeCodeAdapter', () => {
10701070
});
10711071

10721072
it('should extract lastUserMessage from session entries', () => {
1073-
const readSession = (adapter as any).readSession.bind(adapter);
1073+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10741074

10751075
const filePath = path.join(tmpDir, 'user-msg.jsonl');
10761076
const lines = [
@@ -1086,7 +1086,7 @@ describe('ClaudeCodeAdapter', () => {
10861086
});
10871087

10881088
it('should use lastCwd as projectPath when projectPath is empty', () => {
1089-
const readSession = (adapter as any).readSession.bind(adapter);
1089+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
10901090

10911091
const filePath = path.join(tmpDir, 'no-project.jsonl');
10921092
const lines = [
@@ -1099,7 +1099,7 @@ describe('ClaudeCodeAdapter', () => {
10991099
});
11001100

11011101
it('should handle malformed JSON lines gracefully', () => {
1102-
const readSession = (adapter as any).readSession.bind(adapter);
1102+
const readSession = (adapter as any).parser.readSession.bind((adapter as any).parser);
11031103

11041104
const filePath = path.join(tmpDir, 'malformed.jsonl');
11051105
const lines = [

0 commit comments

Comments
 (0)