You need to sign in or sign up before continuing.

kumo-cli 1.0.3 → 1.0.5

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.
Files changed (147) hide show
  1. package/README.md +13 -5
  2. package/dist/auth/credentialsStore.js +61 -14
  3. package/dist/auth/credentialsStore.js.map +1 -1
  4. package/dist/auth/credentialsStore.test.js +60 -0
  5. package/dist/auth/credentialsStore.test.js.map +1 -0
  6. package/dist/claude/fileHistory.js +79 -0
  7. package/dist/claude/fileHistory.js.map +1 -0
  8. package/dist/claude/sessionScanner.js +7 -95
  9. package/dist/claude/sessionScanner.js.map +1 -1
  10. package/dist/claude/sessionScanner.test.js +24 -0
  11. package/dist/claude/sessionScanner.test.js.map +1 -0
  12. package/dist/claude/transcriptParser.js +83 -0
  13. package/dist/claude/transcriptParser.js.map +1 -0
  14. package/dist/claude/transcriptParser.test.js +78 -0
  15. package/dist/claude/transcriptParser.test.js.map +1 -0
  16. package/dist/commands/agentPrompt.js +18 -0
  17. package/dist/commands/agentPrompt.js.map +1 -0
  18. package/dist/commands/cliArgs.js +56 -0
  19. package/dist/commands/cliArgs.js.map +1 -0
  20. package/dist/commands/cliArgs.test.js +25 -0
  21. package/dist/commands/cliArgs.test.js.map +1 -0
  22. package/dist/core/logger.js +7 -2
  23. package/dist/core/logger.js.map +1 -1
  24. package/dist/core/projectFileWatcher.js +56 -0
  25. package/dist/core/projectFileWatcher.js.map +1 -0
  26. package/dist/handlers/fileHandlerPayloads.js +72 -0
  27. package/dist/handlers/fileHandlerPayloads.js.map +1 -0
  28. package/dist/handlers/fileHandlerPayloads.test.js +55 -0
  29. package/dist/handlers/fileHandlerPayloads.test.js.map +1 -0
  30. package/dist/handlers/fileHandlers.js +74 -0
  31. package/dist/handlers/fileHandlers.js.map +1 -0
  32. package/dist/handlers/messageRouter.js +8 -205
  33. package/dist/handlers/messageRouter.js.map +1 -1
  34. package/dist/handlers/promptImages.js +113 -0
  35. package/dist/handlers/promptImages.js.map +1 -0
  36. package/dist/handlers/promptImages.test.js +52 -0
  37. package/dist/handlers/promptImages.test.js.map +1 -0
  38. package/dist/handlers/router.types.js +2 -0
  39. package/dist/handlers/router.types.js.map +1 -0
  40. package/dist/handlers/runtimeHandlers.js +67 -0
  41. package/dist/handlers/runtimeHandlers.js.map +1 -0
  42. package/dist/handlers/sessionHandlers.js +119 -0
  43. package/dist/handlers/sessionHandlers.js.map +1 -0
  44. package/dist/handlers/terminalHandlers.js +40 -0
  45. package/dist/handlers/terminalHandlers.js.map +1 -0
  46. package/dist/index.js +60 -145
  47. package/dist/index.js.map +1 -1
  48. package/dist/pty/notificationDetector.js +29 -0
  49. package/dist/pty/notificationDetector.js.map +1 -0
  50. package/dist/pty/notificationDetector.test.js +24 -0
  51. package/dist/pty/notificationDetector.test.js.map +1 -0
  52. package/dist/pty/ptyMenuParser.js +11 -277
  53. package/dist/pty/ptyMenuParser.js.map +1 -1
  54. package/dist/pty/ptyMenuParser.test.js +26 -0
  55. package/dist/pty/ptyMenuParser.test.js.map +1 -0
  56. package/dist/pty/selectionMenuDetector.js +49 -0
  57. package/dist/pty/selectionMenuDetector.js.map +1 -0
  58. package/dist/pty/selectionMenuDetector.test.js +62 -0
  59. package/dist/pty/selectionMenuDetector.test.js.map +1 -0
  60. package/dist/pty/selectionMenuMeta.js +54 -0
  61. package/dist/pty/selectionMenuMeta.js.map +1 -0
  62. package/dist/pty/selectionMenuMeta.test.js +26 -0
  63. package/dist/pty/selectionMenuMeta.test.js.map +1 -0
  64. package/dist/pty/selectionMenuParser.js +83 -0
  65. package/dist/pty/selectionMenuParser.js.map +1 -0
  66. package/dist/pty/selectionMenuParser.test.js +30 -0
  67. package/dist/pty/selectionMenuParser.test.js.map +1 -0
  68. package/dist/pty/spawn.js +31 -5
  69. package/dist/pty/spawn.js.map +1 -1
  70. package/dist/pty/spawn.test.js +16 -0
  71. package/dist/pty/spawn.test.js.map +1 -0
  72. package/dist/pty/statusSessionDetector.js +28 -0
  73. package/dist/pty/statusSessionDetector.js.map +1 -0
  74. package/dist/pty/statusSessionDetector.test.js +23 -0
  75. package/dist/pty/statusSessionDetector.test.js.map +1 -0
  76. package/dist/pty/terminalManager.js +11 -6
  77. package/dist/pty/terminalManager.js.map +1 -1
  78. package/dist/pty/textInputDetector.js +60 -0
  79. package/dist/pty/textInputDetector.js.map +1 -0
  80. package/dist/pty/textInputDetector.test.js +32 -0
  81. package/dist/pty/textInputDetector.test.js.map +1 -0
  82. package/dist/services/bootstrapService.js +28 -0
  83. package/dist/services/bootstrapService.js.map +1 -0
  84. package/dist/services/checkpointService.js +113 -0
  85. package/dist/services/checkpointService.js.map +1 -0
  86. package/dist/services/checkpointService.test.js +61 -0
  87. package/dist/services/checkpointService.test.js.map +1 -0
  88. package/dist/services/claudeMenuBridge.js +116 -0
  89. package/dist/services/claudeMenuBridge.js.map +1 -0
  90. package/dist/services/claudeMenuBridge.test.js +90 -0
  91. package/dist/services/claudeMenuBridge.test.js.map +1 -0
  92. package/dist/services/claudeService.js +5 -98
  93. package/dist/services/claudeService.js.map +1 -1
  94. package/dist/services/cliRuntime.js +49 -0
  95. package/dist/services/cliRuntime.js.map +1 -0
  96. package/dist/services/cliRuntime.test.js +55 -0
  97. package/dist/services/cliRuntime.test.js.map +1 -0
  98. package/dist/services/fileService.js +19 -23
  99. package/dist/services/fileService.js.map +1 -1
  100. package/dist/services/modelAdapter.test.js +47 -0
  101. package/dist/services/modelAdapter.test.js.map +1 -0
  102. package/dist/services/modelArgs.test.js +64 -0
  103. package/dist/services/modelArgs.test.js.map +1 -0
  104. package/dist/services/modelBaseUrl.test.js +32 -0
  105. package/dist/services/modelBaseUrl.test.js.map +1 -0
  106. package/dist/services/modelService.js +20 -9
  107. package/dist/services/modelService.js.map +1 -1
  108. package/dist/services/modelService.test.js +60 -0
  109. package/dist/services/modelService.test.js.map +1 -1
  110. package/dist/services/notificationDedupe.js +23 -0
  111. package/dist/services/notificationDedupe.js.map +1 -0
  112. package/dist/services/notificationDedupe.test.js +20 -0
  113. package/dist/services/notificationDedupe.test.js.map +1 -0
  114. package/dist/services/pairingService.js +17 -8
  115. package/dist/services/pairingService.js.map +1 -1
  116. package/dist/services/sessionListService.js +19 -0
  117. package/dist/services/sessionListService.js.map +1 -0
  118. package/dist/services/sessionListService.test.js +22 -0
  119. package/dist/services/sessionListService.test.js.map +1 -0
  120. package/dist/services/sessionRollbackService.js +195 -0
  121. package/dist/services/sessionRollbackService.js.map +1 -0
  122. package/dist/services/sessionRollbackService.test.js +142 -0
  123. package/dist/services/sessionRollbackService.test.js.map +1 -0
  124. package/dist/services/sessionService.js +41 -52
  125. package/dist/services/sessionService.js.map +1 -1
  126. package/dist/services/tunnelHelpers.js +69 -0
  127. package/dist/services/tunnelHelpers.js.map +1 -0
  128. package/dist/services/tunnelHelpers.test.js +42 -0
  129. package/dist/services/tunnelHelpers.test.js.map +1 -0
  130. package/dist/services/tunnelService.js +69 -25
  131. package/dist/services/tunnelService.js.map +1 -1
  132. package/dist/services/tunnelService.test.js +91 -0
  133. package/dist/services/tunnelService.test.js.map +1 -0
  134. package/dist/transport/webrtcTransport.js +145 -0
  135. package/dist/transport/webrtcTransport.js.map +1 -0
  136. package/dist/transport/webrtcTransport.test.js +104 -0
  137. package/dist/transport/webrtcTransport.test.js.map +1 -0
  138. package/dist/transport/webrtcTypes.js +29 -0
  139. package/dist/transport/webrtcTypes.js.map +1 -0
  140. package/dist/transport/webrtcTypes.test.js +20 -0
  141. package/dist/transport/webrtcTypes.test.js.map +1 -0
  142. package/dist/transport/wsClient.js +16 -3
  143. package/dist/transport/wsClient.js.map +1 -1
  144. package/dist/utils/safePath.js +18 -6
  145. package/dist/utils/safePath.js.map +1 -1
  146. package/package.json +5 -2
  147. package/scripts/run-tests.mjs +46 -0
@@ -0,0 +1,61 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { buildRollbackResult, rollbackChatTurnOnDisk } from './checkpointService.js';
7
+ test('buildRollbackResult truncates history to selected user message', () => {
8
+ const result = buildRollbackResult('sess-1', 'u1', [
9
+ { id: 'u1', role: 'user', content: 'first' },
10
+ { id: 'a1', role: 'assistant', content: 'reply' },
11
+ { id: 'u2', role: 'user', content: 'second' },
12
+ { id: 'a2', role: 'assistant', content: 'reply2' },
13
+ ]);
14
+ assert.equal(result.sessionId, 'sess-1');
15
+ assert.equal(result.restoredPrompt, 'first');
16
+ assert.deepEqual(result.messages.map((m) => m.id), ['u1', 'a1']);
17
+ });
18
+ test('rollbackChatTurnOnDisk restores file changes from later turns', () => {
19
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'kumo-rollback-'));
20
+ const prevCwd = process.cwd();
21
+ process.chdir(tempRoot);
22
+ try {
23
+ fs.mkdirSync(path.join(tempRoot, 'lib'), { recursive: true });
24
+ fs.writeFileSync(path.join(tempRoot, 'lib', 'demo.txt'), 'after second', 'utf-8');
25
+ const result = rollbackChatTurnOnDisk('sess-1', 'u1', [
26
+ { id: 'u1', role: 'user', content: 'first' },
27
+ {
28
+ id: 'a1',
29
+ role: 'assistant',
30
+ content: 'reply1',
31
+ toolUses: [
32
+ { toolName: 'Write', input: { file_path: 'lib/demo.txt', content: 'first version' } },
33
+ ],
34
+ },
35
+ { id: 'u2', role: 'user', content: 'second' },
36
+ {
37
+ id: 'a2',
38
+ role: 'assistant',
39
+ content: 'reply2',
40
+ toolUses: [
41
+ {
42
+ toolName: 'Write',
43
+ input: {
44
+ file_path: 'lib/demo.txt',
45
+ content: 'after second',
46
+ old_content: 'first version',
47
+ },
48
+ },
49
+ ],
50
+ },
51
+ ]);
52
+ assert.equal(fs.readFileSync(path.join(tempRoot, 'lib', 'demo.txt'), 'utf-8'), 'first version');
53
+ assert.deepEqual(result.restoredFiles, ['lib/demo.txt']);
54
+ assert.deepEqual(result.messages.map((m) => m.id), ['u1', 'a1']);
55
+ }
56
+ finally {
57
+ process.chdir(prevCwd);
58
+ fs.rmSync(tempRoot, { recursive: true, force: true });
59
+ }
60
+ });
61
+ //# sourceMappingURL=checkpointService.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpointService.test.js","sourceRoot":"","sources":["../../src/services/checkpointService.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import { log } from '../core/logger.js';
2
+ import { NotificationDedupe } from './notificationDedupe.js';
3
+ const LOGIN_WARNING_MESSAGE = 'Not logged in · Run /login';
4
+ // translate parsed pty elements into ws messages and handle safe auto-accept flows
5
+ export class ClaudeMenuBridge {
6
+ send;
7
+ getEffectiveEffort;
8
+ getWorkingDir;
9
+ autoAcceptedApiKeyDialog = false;
10
+ menuIdCounter = 0;
11
+ notificationDedupe = new NotificationDedupe();
12
+ constructor(send, getEffectiveEffort, getWorkingDir) {
13
+ this.send = send;
14
+ this.getEffectiveEffort = getEffectiveEffort;
15
+ this.getWorkingDir = getWorkingDir;
16
+ }
17
+ // reset transient state whenever a fresh claude process is spawned
18
+ reset() {
19
+ this.autoAcceptedApiKeyDialog = false;
20
+ }
21
+ // handle a parser event and emit ws payloads or synthetic process input
22
+ handleElement(element, process) {
23
+ switch (element.type) {
24
+ case 'selection':
25
+ this.handleSelection(element, process);
26
+ break;
27
+ case 'input':
28
+ log(`[parser] input: "${element.label}" = "${element.value}"`);
29
+ this.send({
30
+ type: 'text_input',
31
+ label: element.label,
32
+ value: element.value,
33
+ placeholder: element.placeholder,
34
+ cursorPosition: element.cursorPosition,
35
+ });
36
+ break;
37
+ case 'notification':
38
+ this.handleNotification(element);
39
+ break;
40
+ case 'status': {
41
+ const effort = element.effort ?? this.getEffectiveEffort();
42
+ log(`[parser] status: model=${element.model}, effort=${effort}, logged=${element.loggedIn}`);
43
+ this.send({ type: 'cli_status', loggedIn: element.loggedIn, effort, workingDir: element.workingDir });
44
+ break;
45
+ }
46
+ case 'session':
47
+ log(`[parser] session: ${element.sessionId}`);
48
+ this.send({ type: 'session_info', sessionId: element.sessionId, resumeCommand: element.resumeCommand });
49
+ break;
50
+ }
51
+ }
52
+ // auto-accept known safe dialogs or forward the menu to the app
53
+ handleSelection(element, process) {
54
+ if (element.options.length === 0) {
55
+ log('[parser] ignoring empty menu');
56
+ return;
57
+ }
58
+ if (element.title.includes('Bypass Permissions')) {
59
+ if (this.tryAcceptYes(element, process, 'auto-accepted bypass permissions dialog'))
60
+ return;
61
+ }
62
+ if (!this.autoAcceptedApiKeyDialog &&
63
+ (element.title.includes('Detected a custom API key') || element.title.includes('Do you want to use this API key'))) {
64
+ if (this.tryAcceptYes(element, process, 'auto-accepted custom api key dialog', true)) {
65
+ this.autoAcceptedApiKeyDialog = true;
66
+ return;
67
+ }
68
+ }
69
+ this.menuIdCounter += 1;
70
+ const id = `menu-${this.menuIdCounter}`;
71
+ log(`[parser] menu detected: "${element.title}" (${element.options.length} opts, selected: ${element.selectedIndex})`);
72
+ log(`[parser] options: ${JSON.stringify(element.options)}`);
73
+ this.send({
74
+ type: 'prompt_options',
75
+ id,
76
+ title: element.title,
77
+ description: element.description,
78
+ options: element.options,
79
+ selectedIndex: element.selectedIndex,
80
+ hint: element.hint,
81
+ footer: element.footer,
82
+ });
83
+ }
84
+ // forward deduped notifications and update cli status for login warnings
85
+ handleNotification(element) {
86
+ log(`[parser] notification: [${element.level}] ${element.message}`);
87
+ if (this.notificationDedupe.shouldSend(element.level, element.message)) {
88
+ this.send({ type: 'notification', level: element.level, message: element.message });
89
+ }
90
+ if (element.level === 'warning' && element.message.trim().toLowerCase() === LOGIN_WARNING_MESSAGE.toLowerCase()) {
91
+ this.send({
92
+ type: 'cli_status',
93
+ loggedIn: false,
94
+ effort: this.getEffectiveEffort(),
95
+ workingDir: this.getWorkingDir(),
96
+ });
97
+ }
98
+ }
99
+ // try to auto-press "yes" inside a selection dialog
100
+ tryAcceptYes(element, process, logMessage, exact = false) {
101
+ const yesIndex = element.options.findIndex((option) => (exact
102
+ ? option.label.trim().toLowerCase() === 'yes'
103
+ : option.label.trim().toLowerCase().includes('yes')));
104
+ if (yesIndex < 0 || !process)
105
+ return false;
106
+ const delta = yesIndex - element.selectedIndex;
107
+ const key = delta < 0 ? '\x1b[A' : '\x1b[B';
108
+ for (let index = 0; index < Math.abs(delta); index += 1) {
109
+ process.write(key);
110
+ }
111
+ process.write('\r');
112
+ log(`[parser] ${logMessage}`);
113
+ return true;
114
+ }
115
+ }
116
+ //# sourceMappingURL=claudeMenuBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeMenuBridge.js","sourceRoot":"","sources":["../../src/services/claudeMenuBridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { ClaudeMenuBridge } from './claudeMenuBridge.js';
4
+ function createBridge(sent) {
5
+ return new ClaudeMenuBridge((data) => sent.push(data), () => 'high', () => 'E:\\Data\\new_journey\\kumo\\cli');
6
+ }
7
+ function createProcessRecorder() {
8
+ const writes = [];
9
+ return {
10
+ process: {
11
+ write(data) {
12
+ writes.push(data);
13
+ },
14
+ },
15
+ writes,
16
+ };
17
+ }
18
+ test('auto accepts bypass permissions dialog without sending prompt options', () => {
19
+ const sent = [];
20
+ const bridge = createBridge(sent);
21
+ const recorder = createProcessRecorder();
22
+ bridge.handleElement({
23
+ type: 'selection',
24
+ title: 'Bypass Permissions',
25
+ options: [
26
+ { index: 0, label: 'Yes', isSelected: false },
27
+ { index: 1, label: 'No', isSelected: true },
28
+ ],
29
+ selectedIndex: 1,
30
+ }, recorder.process);
31
+ assert.deepEqual(recorder.writes, ['\x1b[A', '\r']);
32
+ assert.equal(sent.length, 0);
33
+ });
34
+ test('auto accepts custom api key dialog only once', () => {
35
+ const sent = [];
36
+ const bridge = createBridge(sent);
37
+ const recorder = createProcessRecorder();
38
+ const element = {
39
+ type: 'selection',
40
+ title: 'Detected a custom API key',
41
+ options: [
42
+ { index: 0, label: 'Yes', isSelected: true },
43
+ { index: 1, label: 'No', isSelected: false },
44
+ ],
45
+ selectedIndex: 0,
46
+ };
47
+ bridge.handleElement(element, recorder.process);
48
+ bridge.handleElement(element, recorder.process);
49
+ assert.deepEqual(recorder.writes, ['\r']);
50
+ assert.equal(sent.length, 1);
51
+ assert.equal(sent[0]?.type, 'prompt_options');
52
+ });
53
+ test('login warning sends both notification and logged-out status', () => {
54
+ const sent = [];
55
+ const bridge = createBridge(sent);
56
+ bridge.handleElement({
57
+ type: 'notification',
58
+ level: 'warning',
59
+ message: 'Not logged in · Run /login',
60
+ }, null);
61
+ assert.deepEqual(sent, [
62
+ { type: 'notification', level: 'warning', message: 'Not logged in · Run /login' },
63
+ { type: 'cli_status', loggedIn: false, effort: 'high', workingDir: 'E:\\Data\\new_journey\\kumo\\cli' },
64
+ ]);
65
+ });
66
+ test('selection prompts receive stable incremental ids', () => {
67
+ const sent = [];
68
+ const bridge = createBridge(sent);
69
+ bridge.handleElement({
70
+ type: 'selection',
71
+ title: 'Select model',
72
+ options: [
73
+ { index: 0, label: 'Sonnet', isSelected: true },
74
+ { index: 1, label: 'Opus', isSelected: false },
75
+ ],
76
+ selectedIndex: 0,
77
+ }, null);
78
+ bridge.handleElement({
79
+ type: 'selection',
80
+ title: 'Select effort',
81
+ options: [
82
+ { index: 0, label: 'High', isSelected: true },
83
+ { index: 1, label: 'Max', isSelected: false },
84
+ ],
85
+ selectedIndex: 0,
86
+ }, null);
87
+ assert.equal(sent[0]?.id, 'menu-1');
88
+ assert.equal(sent[1]?.id, 'menu-2');
89
+ });
90
+ //# sourceMappingURL=claudeMenuBridge.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeMenuBridge.test.js","sourceRoot":"","sources":["../../src/services/claudeMenuBridge.test.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,7 @@ import { PtyMenuParser } from '../pty/ptyMenuParser.js';
3
3
  import { PtySnapshotRenderer } from '../pty/ptySnapshotRenderer.js';
4
4
  import { PtyBuffer } from '../utils/ptyBuffer.js';
5
5
  import { log, debugWrite } from '../core/logger.js';
6
- const LOGIN_WARNING_MESSAGE = 'Not logged in · Run /login';
7
- const NOTIFICATION_DEDUPE_WINDOW_MS = 5 * 60 * 1000;
6
+ import { ClaudeMenuBridge } from './claudeMenuBridge.js';
8
7
  // manage the lifecycle of a claude pty process plus its snapshot/parser
9
8
  export class ClaudeService {
10
9
  send;
@@ -14,14 +13,12 @@ export class ClaudeService {
14
13
  process = null;
15
14
  cleanup = null;
16
15
  isRespawning = false;
17
- autoAcceptedApiKeyDialog = false;
18
- menuIdCounter = 0;
19
16
  pendingSelectNudgeTimer = null;
20
17
  menuParser;
18
+ menuBridge;
21
19
  snapshotRenderer;
22
20
  buffer;
23
21
  lastWsSendAt = 0;
24
- notificationDedupes = new Map();
25
22
  args = [];
26
23
  settingsPath = '';
27
24
  onExit = null;
@@ -32,6 +29,7 @@ export class ClaudeService {
32
29
  this.getDeviceToken = getDeviceToken;
33
30
  this.snapshotRenderer = new PtySnapshotRenderer(process.stdout.columns ?? 120, process.stdout.rows ?? 30);
34
31
  this.buffer = new PtyBuffer(this.snapshotRenderer);
32
+ this.menuBridge = new ClaudeMenuBridge(this.send, () => this.effort.getEffective(), () => process.cwd());
35
33
  this.menuParser = new PtyMenuParser((el) => this.handleMenuElement(el));
36
34
  }
37
35
  // expose a wrapper so wsClient can stamp the last-send timestamp here
@@ -117,7 +115,7 @@ export class ClaudeService {
117
115
  }
118
116
  this.cleanup?.();
119
117
  this.cleanup = null;
120
- this.autoAcceptedApiKeyDialog = false;
118
+ this.menuBridge.reset();
121
119
  this.resetSnapshot();
122
120
  this.args = await this.model.ensureBeforeSpawn(this.args, this.getDeviceToken());
123
121
  this.args = this.effort.ensureBeforeSpawn(this.args);
@@ -126,7 +124,6 @@ export class ClaudeService {
126
124
  this.cleanup = cleanup;
127
125
  this.send({
128
126
  type: 'cli_status',
129
- model: this.model.getCurrent()?.model,
130
127
  effort: this.effort.getEffective(),
131
128
  workingDir: process.cwd(),
132
129
  });
@@ -143,97 +140,7 @@ export class ClaudeService {
143
140
  }
144
141
  // handle a parsed pty menu element and translate into ws message
145
142
  handleMenuElement(element) {
146
- switch (element.type) {
147
- case 'selection': {
148
- if (element.options.length === 0) {
149
- log(`[parser] ignoring empty menu`);
150
- break;
151
- }
152
- if (element.title.includes('Bypass Permissions')) {
153
- if (this.tryAcceptYes(element, 'auto-accepted bypass permissions dialog'))
154
- break;
155
- }
156
- if (!this.autoAcceptedApiKeyDialog &&
157
- (element.title.includes('Detected a custom API key') || element.title.includes('Do you want to use this API key'))) {
158
- if (this.tryAcceptYes(element, 'auto-accepted custom api key dialog', true)) {
159
- this.autoAcceptedApiKeyDialog = true;
160
- break;
161
- }
162
- }
163
- this.menuIdCounter++;
164
- const id = `menu-${this.menuIdCounter}`;
165
- log(`[parser] menu detected: "${element.title}" (${element.options.length} opts, selected: ${element.selectedIndex})`);
166
- log(`[parser] options: ${JSON.stringify(element.options)}`);
167
- this.send({
168
- type: 'prompt_options',
169
- id,
170
- title: element.title,
171
- description: element.description,
172
- options: element.options,
173
- selectedIndex: element.selectedIndex,
174
- hint: element.hint,
175
- footer: element.footer,
176
- });
177
- break;
178
- }
179
- case 'input':
180
- log(`[parser] input: "${element.label}" = "${element.value}"`);
181
- this.send({ type: 'text_input', label: element.label, value: element.value, placeholder: element.placeholder, cursorPosition: element.cursorPosition });
182
- break;
183
- case 'notification':
184
- log(`[parser] notification: [${element.level}] ${element.message}`);
185
- if (this.shouldSendNotification(element.level, element.message)) {
186
- this.send({ type: 'notification', level: element.level, message: element.message });
187
- }
188
- if (element.level === 'warning' && element.message.trim().toLowerCase() === LOGIN_WARNING_MESSAGE.toLowerCase()) {
189
- const effort = this.effort.getEffective();
190
- this.send({ type: 'cli_status', loggedIn: false, model: 'no model', effort, workingDir: process.cwd() });
191
- }
192
- break;
193
- case 'status': {
194
- const effort = element.effort ?? this.effort.getEffective();
195
- log(`[parser] status: model=${element.model}, effort=${effort}, logged=${element.loggedIn}`);
196
- this.send({ type: 'cli_status', loggedIn: element.loggedIn, model: element.model, effort, workingDir: element.workingDir });
197
- break;
198
- }
199
- case 'session':
200
- log(`[parser] session: ${element.sessionId}`);
201
- this.send({ type: 'session_info', sessionId: element.sessionId, resumeCommand: element.resumeCommand });
202
- break;
203
- case 'prompt':
204
- break;
205
- }
206
- }
207
- // try to auto-press "yes" inside a selection dialog
208
- tryAcceptYes(element, logMsg, exact = false) {
209
- const yesIndex = element.options.findIndex((o) => exact
210
- ? o.label.trim().toLowerCase() === 'yes'
211
- : o.label.trim().toLowerCase().includes('yes'));
212
- if (yesIndex < 0 || !this.process)
213
- return false;
214
- const delta = yesIndex - element.selectedIndex;
215
- const key = delta < 0 ? '\x1b[A' : '\x1b[B';
216
- for (let i = 0; i < Math.abs(delta); i++)
217
- this.process.write(key);
218
- this.process.write('\r');
219
- log(`[parser] ${logMsg}`);
220
- return true;
221
- }
222
- shouldSendNotification(level, message) {
223
- const now = Date.now();
224
- const key = this.buildNotificationKey(level, message);
225
- for (const [existingKey, expiresAt] of this.notificationDedupes) {
226
- if (expiresAt <= now)
227
- this.notificationDedupes.delete(existingKey);
228
- }
229
- const expiresAt = this.notificationDedupes.get(key);
230
- if (expiresAt && expiresAt > now)
231
- return false;
232
- this.notificationDedupes.set(key, now + NOTIFICATION_DEDUPE_WINDOW_MS);
233
- return true;
234
- }
235
- buildNotificationKey(level, message) {
236
- return `${level.trim().toLowerCase()}::${message.trim().replace(/\s+/g, ' ').toLowerCase()}`;
143
+ this.menuBridge.handleElement(element, this.process);
237
144
  }
238
145
  }
239
146
  //# sourceMappingURL=claudeService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claudeService.js","sourceRoot":"","sources":["../../src/services/claudeService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claudeService.js","sourceRoot":"","sources":["../../src/services/claudeService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { log } from '../core/logger.js';
2
+ import { SessionScanner } from '../claude/sessionScanner.js';
3
+ import { loadSessionList } from './sessionListService.js';
4
+ // ensure claude always runs with the permissions bypass flag expected by the app flow
5
+ export function ensureClaudeArgs(args) {
6
+ return args.includes('--dangerously-skip-permissions') ? [...args] : [...args, '--dangerously-skip-permissions'];
7
+ }
8
+ // create the hook-server callback that keeps scanner state, prompt replay, and assistant completion in sync
9
+ export function createSessionStartHandler(params) {
10
+ return (sessionId) => {
11
+ params.state.currentSessionId = sessionId;
12
+ params.resetSnapshot();
13
+ params.send({ type: 'session_start', sessionId });
14
+ params.state.scanner?.stop();
15
+ params.state.scanner = (params.scannerFactory?.(sessionId, params.state.startScannerAtEnd) ?? new SessionScanner(sessionId, params.state.startScannerAtEnd));
16
+ params.state.startScannerAtEnd = false;
17
+ params.state.scanner.on('message', (message) => {
18
+ params.send({ type: 'transcript', message });
19
+ if (message.role === 'assistant' && message.stopReason === 'end_turn') {
20
+ log(`[scanner] assistant_done detected, stopReason=${message.stopReason}`);
21
+ params.send({ type: 'assistant_done' });
22
+ }
23
+ });
24
+ params.state.scanner.start();
25
+ if (!params.state.pendingPrompt)
26
+ return;
27
+ const queuedPrompt = params.state.pendingPrompt;
28
+ params.state.pendingPrompt = null;
29
+ params.dispatchPrompt(queuedPrompt);
30
+ };
31
+ }
32
+ // create the ws onOpen hook that registers the cli, refreshes sessions, and restarts file watching
33
+ export function createWsOpenHandler(params) {
34
+ return async () => {
35
+ const credentials = params.credentials();
36
+ params.send({
37
+ type: 'register',
38
+ clientType: 'cli',
39
+ deviceToken: credentials?.deviceToken,
40
+ deviceUuid: credentials?.deviceUuid,
41
+ cwd: process.cwd(),
42
+ });
43
+ params.resetMenu();
44
+ params.restartWatcher();
45
+ const sessions = await loadSessionList(undefined, params.currentSessionId());
46
+ params.send({ type: 'session_list', sessions });
47
+ };
48
+ }
49
+ //# sourceMappingURL=cliRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliRuntime.js","sourceRoot":"","sources":["../../src/services/cliRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAY1D,sFAAsF;AACtF,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,gCAAgC,CAAC,CAAC;AACnH,CAAC;AAED,4GAA4G;AAC5G,MAAM,UAAU,yBAAyB,CAAC,MAMzC;IACC,OAAO,CAAC,SAAiB,EAAE,EAAE;QAC3B,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAC1C,MAAM,CAAC,aAAa,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,IAAI,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAmB,CAAC;QAC/K,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;YAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBACtE,GAAG,CAAC,iDAAiD,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;gBAC3E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa;YAAE,OAAO;QACxC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,mBAAmB,CAAC,MAMnC;IACC,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,WAAW,EAAE,WAAW;YACrC,UAAU,EAAE,WAAW,EAAE,UAAU;YACnC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC7E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { createSessionStartHandler, createWsOpenHandler, ensureClaudeArgs } from './cliRuntime.js';
4
+ test('ensureClaudeArgs appends the bypass flag only once', () => {
5
+ assert.deepEqual(ensureClaudeArgs(['--debug']), ['--debug', '--dangerously-skip-permissions']);
6
+ assert.deepEqual(ensureClaudeArgs(['--dangerously-skip-permissions']), ['--dangerously-skip-permissions']);
7
+ });
8
+ test('createSessionStartHandler replays pending prompt and announces assistant completion', async () => {
9
+ const sent = [];
10
+ const dispatched = [];
11
+ const state = {
12
+ currentSessionId: null,
13
+ pendingPrompt: 'hello',
14
+ startScannerAtEnd: false,
15
+ scanner: null,
16
+ };
17
+ const handler = createSessionStartHandler({
18
+ state,
19
+ send: (data) => sent.push(data),
20
+ resetSnapshot: () => { },
21
+ dispatchPrompt: (text) => dispatched.push(text),
22
+ scannerFactory: () => ({
23
+ stop() { },
24
+ on(_event, handler) {
25
+ handler({ role: 'assistant', stopReason: 'end_turn' });
26
+ return this;
27
+ },
28
+ start() { },
29
+ }),
30
+ });
31
+ handler('session-1');
32
+ assert.equal(state.currentSessionId, 'session-1');
33
+ assert.equal(state.pendingPrompt, null);
34
+ assert.equal(dispatched[0], 'hello');
35
+ assert.equal(sent[0]?.type, 'session_start');
36
+ });
37
+ test('createWsOpenHandler registers the cli and sends a session list', async () => {
38
+ const sent = [];
39
+ let menuReset = false;
40
+ let watcherRestarted = false;
41
+ const handler = createWsOpenHandler({
42
+ send: (data) => sent.push(data),
43
+ credentials: () => ({ deviceUuid: 'device-1', deviceToken: 'token-1', serverUrl: 'http://localhost' }),
44
+ currentSessionId: () => 'session-1',
45
+ resetMenu: () => { menuReset = true; },
46
+ restartWatcher: () => { watcherRestarted = true; },
47
+ });
48
+ await handler();
49
+ assert.equal(sent[0]?.type, 'register');
50
+ assert.equal(sent[0]?.deviceToken, 'token-1');
51
+ assert.equal(sent.at(-1)?.type, 'session_list');
52
+ assert.equal(menuReset, true);
53
+ assert.equal(watcherRestarted, true);
54
+ });
55
+ //# sourceMappingURL=cliRuntime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliRuntime.test.js","sourceRoot":"","sources":["../../src/services/cliRuntime.test.ts"],"names":[],"mappings":"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"}