kumo-cli 1.0.6 → 1.2.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.
Files changed (241) hide show
  1. package/README.md +26 -13
  2. package/dist/auth/credentialsStore.js +20 -7
  3. package/dist/auth/credentialsStore.js.map +1 -1
  4. package/dist/claude/conversation.js +272 -0
  5. package/dist/claude/conversation.js.map +1 -0
  6. package/dist/claude/transcriptParser.js +140 -36
  7. package/dist/claude/transcriptParser.js.map +1 -1
  8. package/dist/commands/cliArgs.js +1 -0
  9. package/dist/commands/cliArgs.js.map +1 -1
  10. package/dist/core/config.js +1 -9
  11. package/dist/core/config.js.map +1 -1
  12. package/dist/core/logger.js +50 -21
  13. package/dist/core/logger.js.map +1 -1
  14. package/dist/core/projectFileWatcher.js +100 -36
  15. package/dist/core/projectFileWatcher.js.map +1 -1
  16. package/dist/engine/claudeArgs.js +106 -0
  17. package/dist/engine/claudeArgs.js.map +1 -0
  18. package/dist/engine/claudeBinary.js +94 -0
  19. package/dist/engine/claudeBinary.js.map +1 -0
  20. package/dist/engine/claudeConfig.js +127 -0
  21. package/dist/engine/claudeConfig.js.map +1 -0
  22. package/dist/engine/claudeLogin.js +76 -0
  23. package/dist/engine/claudeLogin.js.map +1 -0
  24. package/dist/engine/controlChannel.js +75 -0
  25. package/dist/engine/controlChannel.js.map +1 -0
  26. package/dist/engine/liveTranscript.js +150 -0
  27. package/dist/engine/liveTranscript.js.map +1 -0
  28. package/dist/engine/ndjson.js +48 -0
  29. package/dist/engine/ndjson.js.map +1 -0
  30. package/dist/engine/permissions.js +101 -0
  31. package/dist/engine/permissions.js.map +1 -0
  32. package/dist/engine/probePool.js +51 -0
  33. package/dist/engine/probePool.js.map +1 -0
  34. package/dist/engine/processTree.js +45 -0
  35. package/dist/engine/processTree.js.map +1 -0
  36. package/dist/engine/remoteConfig.js +17 -0
  37. package/dist/engine/remoteConfig.js.map +1 -0
  38. package/dist/engine/sessionManager.js +444 -0
  39. package/dist/engine/sessionManager.js.map +1 -0
  40. package/dist/engine/settingsCommands.js +260 -0
  41. package/dist/engine/settingsCommands.js.map +1 -0
  42. package/dist/engine/streamSession.js +502 -0
  43. package/dist/engine/streamSession.js.map +1 -0
  44. package/dist/engine/taskTracker.js +110 -0
  45. package/dist/engine/taskTracker.js.map +1 -0
  46. package/dist/engine/toolLabels.js +32 -0
  47. package/dist/engine/toolLabels.js.map +1 -0
  48. package/dist/handlers/controlRequest.js +17 -0
  49. package/dist/handlers/controlRequest.js.map +1 -0
  50. package/dist/handlers/fileHandlers.js +12 -0
  51. package/dist/handlers/fileHandlers.js.map +1 -1
  52. package/dist/handlers/messageRouter.js +8 -1
  53. package/dist/handlers/messageRouter.js.map +1 -1
  54. package/dist/handlers/promptImages.js +5 -91
  55. package/dist/handlers/promptImages.js.map +1 -1
  56. package/dist/handlers/runtimeHandlers.js +100 -32
  57. package/dist/handlers/runtimeHandlers.js.map +1 -1
  58. package/dist/handlers/sessionHandlers.js +85 -80
  59. package/dist/handlers/sessionHandlers.js.map +1 -1
  60. package/dist/handlers/terminalHandlers.js +9 -2
  61. package/dist/handlers/terminalHandlers.js.map +1 -1
  62. package/dist/http/httpClient.js +6 -0
  63. package/dist/http/httpClient.js.map +1 -1
  64. package/dist/index.js +87 -50
  65. package/dist/index.js.map +1 -1
  66. package/dist/pty/terminalManager.js +58 -11
  67. package/dist/pty/terminalManager.js.map +1 -1
  68. package/dist/services/bootstrapService.js +17 -1
  69. package/dist/services/bootstrapService.js.map +1 -1
  70. package/dist/services/claudeAdapterProxy.js +68 -21
  71. package/dist/services/claudeAdapterProxy.js.map +1 -1
  72. package/dist/services/cliRuntime.js +39 -32
  73. package/dist/services/cliRuntime.js.map +1 -1
  74. package/dist/services/effortService.js +13 -60
  75. package/dist/services/effortService.js.map +1 -1
  76. package/dist/services/fileService.js +50 -24
  77. package/dist/services/fileService.js.map +1 -1
  78. package/dist/services/forkService.js +120 -0
  79. package/dist/services/forkService.js.map +1 -0
  80. package/dist/services/modelService.js +86 -89
  81. package/dist/services/modelService.js.map +1 -1
  82. package/dist/services/pairingService.js +21 -15
  83. package/dist/services/pairingService.js.map +1 -1
  84. package/dist/services/sessionListService.js +7 -9
  85. package/dist/services/sessionListService.js.map +1 -1
  86. package/dist/services/sessionService.js +245 -106
  87. package/dist/services/sessionService.js.map +1 -1
  88. package/dist/services/tunnelHelpers.js +9 -5
  89. package/dist/services/tunnelHelpers.js.map +1 -1
  90. package/dist/services/tunnelService.js +21 -5
  91. package/dist/services/tunnelService.js.map +1 -1
  92. package/dist/transport/wsClient.js +60 -42
  93. package/dist/transport/wsClient.js.map +1 -1
  94. package/dist/utils/ignorePaths.js +3 -3
  95. package/dist/utils/ignorePaths.js.map +1 -1
  96. package/dist/utils/json.js +7 -0
  97. package/dist/utils/json.js.map +1 -0
  98. package/dist/utils/localHost.js +17 -0
  99. package/dist/utils/localHost.js.map +1 -0
  100. package/dist/utils/safePath.js +51 -20
  101. package/dist/utils/safePath.js.map +1 -1
  102. package/package.json +5 -12
  103. package/dist/ansiCodes.js +0 -107
  104. package/dist/ansiCodes.js.map +0 -1
  105. package/dist/auth/credentialsStore.test.js +0 -60
  106. package/dist/auth/credentialsStore.test.js.map +0 -1
  107. package/dist/claude/fileHistory.js +0 -79
  108. package/dist/claude/fileHistory.js.map +0 -1
  109. package/dist/claude/generateHookSettings.js +0 -23
  110. package/dist/claude/generateHookSettings.js.map +0 -1
  111. package/dist/claude/hookServer.js +0 -33
  112. package/dist/claude/hookServer.js.map +0 -1
  113. package/dist/claude/sessionScanner.js +0 -162
  114. package/dist/claude/sessionScanner.js.map +0 -1
  115. package/dist/claude/sessionScanner.test.js +0 -24
  116. package/dist/claude/sessionScanner.test.js.map +0 -1
  117. package/dist/claude/transcriptParser.test.js +0 -78
  118. package/dist/claude/transcriptParser.test.js.map +0 -1
  119. package/dist/commands/cliArgs.test.js +0 -25
  120. package/dist/commands/cliArgs.test.js.map +0 -1
  121. package/dist/config.js +0 -40
  122. package/dist/config.js.map +0 -1
  123. package/dist/credentialsStore.js +0 -57
  124. package/dist/credentialsStore.js.map +0 -1
  125. package/dist/generateHookSettings.js +0 -30
  126. package/dist/generateHookSettings.js.map +0 -1
  127. package/dist/handlers/fileHandlerPayloads.test.js +0 -55
  128. package/dist/handlers/fileHandlerPayloads.test.js.map +0 -1
  129. package/dist/handlers/promptImages.test.js +0 -52
  130. package/dist/handlers/promptImages.test.js.map +0 -1
  131. package/dist/hookServer.js +0 -32
  132. package/dist/hookServer.js.map +0 -1
  133. package/dist/ignorePaths.js +0 -68
  134. package/dist/ignorePaths.js.map +0 -1
  135. package/dist/loadDotEnv.js +0 -79
  136. package/dist/loadDotEnv.js.map +0 -1
  137. package/dist/logger.js +0 -29
  138. package/dist/logger.js.map +0 -1
  139. package/dist/portForwardManager.js +0 -97
  140. package/dist/portForwardManager.js.map +0 -1
  141. package/dist/projectHistoryReader.js +0 -85
  142. package/dist/projectHistoryReader.js.map +0 -1
  143. package/dist/pty/ansiCodes.js +0 -14
  144. package/dist/pty/ansiCodes.js.map +0 -1
  145. package/dist/pty/notificationDetector.js +0 -29
  146. package/dist/pty/notificationDetector.js.map +0 -1
  147. package/dist/pty/notificationDetector.test.js +0 -24
  148. package/dist/pty/notificationDetector.test.js.map +0 -1
  149. package/dist/pty/ptyMenuParser.js +0 -91
  150. package/dist/pty/ptyMenuParser.js.map +0 -1
  151. package/dist/pty/ptyMenuParser.test.js +0 -26
  152. package/dist/pty/ptyMenuParser.test.js.map +0 -1
  153. package/dist/pty/ptySnapshotRenderer.js +0 -71
  154. package/dist/pty/ptySnapshotRenderer.js.map +0 -1
  155. package/dist/pty/selectionMenuDetector.js +0 -49
  156. package/dist/pty/selectionMenuDetector.js.map +0 -1
  157. package/dist/pty/selectionMenuDetector.test.js +0 -62
  158. package/dist/pty/selectionMenuDetector.test.js.map +0 -1
  159. package/dist/pty/selectionMenuMeta.js +0 -54
  160. package/dist/pty/selectionMenuMeta.js.map +0 -1
  161. package/dist/pty/selectionMenuMeta.test.js +0 -26
  162. package/dist/pty/selectionMenuMeta.test.js.map +0 -1
  163. package/dist/pty/selectionMenuParser.js +0 -83
  164. package/dist/pty/selectionMenuParser.js.map +0 -1
  165. package/dist/pty/selectionMenuParser.test.js +0 -30
  166. package/dist/pty/selectionMenuParser.test.js.map +0 -1
  167. package/dist/pty/spawn.js +0 -104
  168. package/dist/pty/spawn.js.map +0 -1
  169. package/dist/pty/spawn.test.js +0 -17
  170. package/dist/pty/spawn.test.js.map +0 -1
  171. package/dist/pty/statusSessionDetector.js +0 -28
  172. package/dist/pty/statusSessionDetector.js.map +0 -1
  173. package/dist/pty/statusSessionDetector.test.js +0 -23
  174. package/dist/pty/statusSessionDetector.test.js.map +0 -1
  175. package/dist/pty/textInputDetector.js +0 -60
  176. package/dist/pty/textInputDetector.js.map +0 -1
  177. package/dist/pty/textInputDetector.test.js +0 -32
  178. package/dist/pty/textInputDetector.test.js.map +0 -1
  179. package/dist/ptyMenuParser.js +0 -470
  180. package/dist/ptyMenuParser.js.map +0 -1
  181. package/dist/ptySnapshotRenderer.js +0 -78
  182. package/dist/ptySnapshotRenderer.js.map +0 -1
  183. package/dist/services/checkpointService.js +0 -113
  184. package/dist/services/checkpointService.js.map +0 -1
  185. package/dist/services/checkpointService.test.js +0 -61
  186. package/dist/services/checkpointService.test.js.map +0 -1
  187. package/dist/services/claudeMenuBridge.js +0 -116
  188. package/dist/services/claudeMenuBridge.js.map +0 -1
  189. package/dist/services/claudeMenuBridge.test.js +0 -90
  190. package/dist/services/claudeMenuBridge.test.js.map +0 -1
  191. package/dist/services/claudeService.js +0 -146
  192. package/dist/services/claudeService.js.map +0 -1
  193. package/dist/services/claudeService.test.js +0 -39
  194. package/dist/services/claudeService.test.js.map +0 -1
  195. package/dist/services/cliRuntime.test.js +0 -55
  196. package/dist/services/cliRuntime.test.js.map +0 -1
  197. package/dist/services/modelAdapter.test.js +0 -47
  198. package/dist/services/modelAdapter.test.js.map +0 -1
  199. package/dist/services/modelArgs.test.js +0 -64
  200. package/dist/services/modelArgs.test.js.map +0 -1
  201. package/dist/services/modelBaseUrl.test.js +0 -32
  202. package/dist/services/modelBaseUrl.test.js.map +0 -1
  203. package/dist/services/modelService.test.js +0 -136
  204. package/dist/services/modelService.test.js.map +0 -1
  205. package/dist/services/notificationDedupe.js +0 -23
  206. package/dist/services/notificationDedupe.js.map +0 -1
  207. package/dist/services/notificationDedupe.test.js +0 -20
  208. package/dist/services/notificationDedupe.test.js.map +0 -1
  209. package/dist/services/sessionListService.test.js +0 -22
  210. package/dist/services/sessionListService.test.js.map +0 -1
  211. package/dist/services/sessionRollbackService.js +0 -195
  212. package/dist/services/sessionRollbackService.js.map +0 -1
  213. package/dist/services/sessionRollbackService.test.js +0 -142
  214. package/dist/services/sessionRollbackService.test.js.map +0 -1
  215. package/dist/services/tunnelHelpers.test.js +0 -42
  216. package/dist/services/tunnelHelpers.test.js.map +0 -1
  217. package/dist/services/tunnelService.test.js +0 -91
  218. package/dist/services/tunnelService.test.js.map +0 -1
  219. package/dist/sessionScanner.js +0 -271
  220. package/dist/sessionScanner.js.map +0 -1
  221. package/dist/snapshotScanner.js +0 -154
  222. package/dist/snapshotScanner.js.map +0 -1
  223. package/dist/spawn.js +0 -79
  224. package/dist/spawn.js.map +0 -1
  225. package/dist/terminalManager.js +0 -73
  226. package/dist/terminalManager.js.map +0 -1
  227. package/dist/transport/directWsServer.js +0 -135
  228. package/dist/transport/directWsServer.js.map +0 -1
  229. package/dist/transport/webrtcTransport.js +0 -145
  230. package/dist/transport/webrtcTransport.js.map +0 -1
  231. package/dist/transport/webrtcTransport.test.js +0 -104
  232. package/dist/transport/webrtcTransport.test.js.map +0 -1
  233. package/dist/transport/webrtcTypes.js +0 -29
  234. package/dist/transport/webrtcTypes.js.map +0 -1
  235. package/dist/transport/webrtcTypes.test.js +0 -20
  236. package/dist/transport/webrtcTypes.test.js.map +0 -1
  237. package/dist/utils/ptyBuffer.js +0 -46
  238. package/dist/utils/ptyBuffer.js.map +0 -1
  239. package/scripts/claude_launcher.cjs +0 -71
  240. package/scripts/run-tests.mjs +0 -46
  241. package/scripts/session_hook_forwarder.cjs +0 -44
@@ -0,0 +1,150 @@
1
+ import { compactBoundaryMessage, isThinkingBlock, parseTranscriptMessage, thinkingSeconds, rememberToolResults, } from '../claude/transcriptParser.js';
2
+ import { str } from '../utils/json.js';
3
+ // enough history to fold late tool results into their message without growing forever
4
+ const MAX_TRACKED = 300;
5
+ const blocksOf = (content) => Array.isArray(content) ? content.filter((b) => !!b && typeof b === 'object') : [];
6
+ // a block claude may send again: a tool use by its id, text by itself, anything else whole
7
+ const blockKey = (block) => block['type'] === 'tool_use' ? `tool_use:${str(block['id'])}`
8
+ : block['type'] === 'text' ? `text:${str(block['text'])}`
9
+ : JSON.stringify(block);
10
+ // thinking and other blocks show nothing in the app
11
+ const isVisible = (block) => block['type'] === 'text' || block['type'] === 'tool_use';
12
+ // turns stream-json stdout frames into app transcript messages the way the extension renders a
13
+ // live turn: assistant blocks merged by message id (one frame per block), tool results folded
14
+ // into their tool use, prompts from the --replay-user-messages echo under the uuid we sent.
15
+ // every update re-emits the whole message under the same id, so the app replaces it; updates of
16
+ // one tick go out together (parallel tool results) and a change the app cannot see (a thinking
17
+ // block) sends nothing
18
+ export class LiveTranscript {
19
+ emit;
20
+ now;
21
+ assistants = new Map();
22
+ owners = new Map();
23
+ results = new Map();
24
+ dirty = new Set();
25
+ flushTimer = null;
26
+ // the last frame of each thread (the main one, each subagent): a thinking block took the time
27
+ // since then
28
+ lastFrameAt = new Map();
29
+ constructor(emit, now = Date.now) {
30
+ this.emit = emit;
31
+ this.now = now;
32
+ }
33
+ handle(frame) {
34
+ if (frame['type'] === 'assistant')
35
+ this.assistant(frame);
36
+ else if (frame['type'] === 'user')
37
+ this.user(frame);
38
+ else if (frame['type'] === 'system' && frame['subtype'] === 'compact_boundary') {
39
+ this.flush();
40
+ this.emit(compactBoundaryMessage(frame, new Date().toISOString()));
41
+ }
42
+ this.lastFrameAt.set(str(frame['parent_tool_use_id']), this.now());
43
+ }
44
+ // emit the messages updated since the last flush; the session calls it before any other event
45
+ // so the app sees the transcript and the turn state in order
46
+ flush() {
47
+ if (this.flushTimer)
48
+ clearImmediate(this.flushTimer);
49
+ this.flushTimer = null;
50
+ for (const id of this.dirty)
51
+ this.emitAssistant(id);
52
+ this.dirty.clear();
53
+ }
54
+ assistant(frame) {
55
+ const message = frame['message'];
56
+ const id = str(message?.['id']) || str(frame['uuid']);
57
+ if (!id)
58
+ return;
59
+ const entry = this.assistants.get(id) ?? { blocks: [], seen: new Set(), timestamp: new Date().toISOString(), version: 0, sent: 0 };
60
+ for (const block of blocksOf(message?.['content'])) {
61
+ const key = blockKey(block);
62
+ if (entry.seen.has(key))
63
+ continue;
64
+ entry.seen.add(key);
65
+ entry.blocks.push(block);
66
+ // shown with the message's next visible block
67
+ const since = this.lastFrameAt.get(str(frame['parent_tool_use_id']));
68
+ if (isThinkingBlock(block) && since !== undefined)
69
+ entry.thinkingMs = (entry.thinkingMs ?? 0) + this.now() - since;
70
+ if (isVisible(block))
71
+ entry.version++;
72
+ if (block['type'] === 'tool_use' && typeof block['id'] === 'string')
73
+ this.owners.set(block['id'], id);
74
+ }
75
+ entry.parentToolUseId = str(frame['parent_tool_use_id']) || entry.parentToolUseId;
76
+ this.track(id, entry);
77
+ this.publish(id);
78
+ }
79
+ user(frame) {
80
+ // claude's own messages, such as the summary a compaction starts from, are no prompts
81
+ if (frame['isSynthetic'] === true)
82
+ return;
83
+ const parentToolUseId = str(frame['parent_tool_use_id']) || undefined;
84
+ const message = frame['message'];
85
+ const jsonl = {
86
+ type: 'user',
87
+ uuid: str(frame['uuid']) || undefined,
88
+ message,
89
+ toolUseResult: frame['tool_use_result'],
90
+ isSidechain: parentToolUseId !== undefined,
91
+ };
92
+ const toolResults = blocksOf(message?.content).filter((b) => b['type'] === 'tool_result');
93
+ if (toolResults.length > 0) {
94
+ rememberToolResults(jsonl, this.results);
95
+ const owners = new Set(toolResults.map((b) => this.owners.get(str(b['tool_use_id']))));
96
+ for (const owner of owners) {
97
+ const entry = owner ? this.assistants.get(owner) : undefined;
98
+ if (!entry)
99
+ continue;
100
+ entry.version++;
101
+ this.publish(owner);
102
+ }
103
+ return;
104
+ }
105
+ const parsed = parseTranscriptMessage(jsonl, { timestamp: new Date().toISOString() });
106
+ if (!parsed)
107
+ return;
108
+ this.flush();
109
+ this.emit(parentToolUseId ? { ...parsed, parentToolUseId } : parsed);
110
+ }
111
+ publish(id) {
112
+ this.dirty.add(id);
113
+ this.flushTimer ??= setImmediate(() => this.flush());
114
+ }
115
+ emitAssistant(id) {
116
+ const entry = this.assistants.get(id);
117
+ if (!entry || entry.sent === entry.version)
118
+ return;
119
+ const parsed = parseTranscriptMessage({
120
+ type: 'assistant',
121
+ uuid: id,
122
+ message: { role: 'assistant', content: entry.blocks },
123
+ isSidechain: entry.parentToolUseId !== undefined,
124
+ }, { timestamp: entry.timestamp, toolResults: this.results });
125
+ entry.sent = entry.version;
126
+ if (!parsed)
127
+ return;
128
+ this.emit({
129
+ ...parsed,
130
+ ...(entry.parentToolUseId ? { parentToolUseId: entry.parentToolUseId } : {}),
131
+ ...(entry.thinkingMs !== undefined ? { thinkingSeconds: thinkingSeconds(entry.thinkingMs) } : {}),
132
+ });
133
+ }
134
+ track(id, entry) {
135
+ this.assistants.delete(id);
136
+ this.assistants.set(id, entry);
137
+ while (this.assistants.size > MAX_TRACKED) {
138
+ const [oldest, old] = this.assistants.entries().next().value;
139
+ this.assistants.delete(oldest);
140
+ for (const block of old.blocks) {
141
+ const toolId = str(block['id']);
142
+ if (toolId && this.owners.get(toolId) === oldest) {
143
+ this.owners.delete(toolId);
144
+ this.results.delete(toolId);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ //# sourceMappingURL=liveTranscript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveTranscript.js","sourceRoot":"","sources":["../../src/engine/liveTranscript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { log } from '../core/logger.js';
2
+ // read line-delimited json from a stream, tolerating partial chunks and skipping blank/non-json lines
3
+ export function readNdjson(stream, onMessage) {
4
+ // the start of a line still waiting for its newline, in pieces: joined once when it ends,
5
+ // so a 20 MB line (an echoed prompt with images) is not copied and searched per chunk
6
+ let parts = [];
7
+ const handleLine = (raw) => {
8
+ const line = raw.trim();
9
+ if (!line)
10
+ return;
11
+ let parsed;
12
+ try {
13
+ parsed = JSON.parse(line);
14
+ }
15
+ catch {
16
+ log(`[ndjson] skipped non-json line: ${line.slice(0, 200)}`);
17
+ return;
18
+ }
19
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
20
+ onMessage(parsed);
21
+ };
22
+ stream.setEncoding('utf8');
23
+ stream.on('data', (chunk) => {
24
+ // only the new chunk is searched for line ends
25
+ let start = 0;
26
+ for (let index = chunk.indexOf('\n'); index >= 0; index = chunk.indexOf('\n', start)) {
27
+ parts.push(chunk.slice(start, index));
28
+ handleLine(parts.join(''));
29
+ parts = [];
30
+ start = index + 1;
31
+ }
32
+ if (start < chunk.length)
33
+ parts.push(chunk.slice(start));
34
+ });
35
+ stream.on('end', () => {
36
+ if (parts.length > 0)
37
+ handleLine(parts.join(''));
38
+ parts = [];
39
+ });
40
+ }
41
+ // write one json message followed by a newline; returns false when the stream is no longer writable
42
+ export function writeNdjson(stream, msg) {
43
+ if (stream.destroyed || stream.writableEnded)
44
+ return false;
45
+ stream.write(`${JSON.stringify(msg)}\n`);
46
+ return true;
47
+ }
48
+ //# sourceMappingURL=ndjson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ndjson.js","sourceRoot":"","sources":["../../src/engine/ndjson.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAIxC,sGAAsG;AACtG,MAAM,UAAU,UAAU,CAAC,MAAgB,EAAE,SAAoC;IAC/E,0FAA0F;IAC1F,sFAAsF;IACtF,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,MAAM,UAAU,GAAG,CAAC,GAAW,EAAQ,EAAE;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,mCAAmC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QACD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,MAAoB,CAAC,CAAC;IACtG,CAAC,CAAC;IACF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QAClC,+CAA+C;QAC/C,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACrF,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YACtC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3B,KAAK,GAAG,EAAE,CAAC;YACX,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;QACpB,CAAC;QACD,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QACpB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,MAAgB,EAAE,GAAY;IACxD,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { remoteUserConfigAllowed } from './remoteConfig.js';
2
+ const PERMISSION_MODES = new Set(['default', 'acceptEdits', 'plan', 'bypassPermissions', 'auto', 'dontAsk']);
3
+ const DESTINATIONS = new Set(['userSettings', 'projectSettings', 'localSettings', 'session', 'cliArg']);
4
+ // approving a plan with "manually approve edits" sends this update even though the cli never suggests it
5
+ const RESET_MODE_UPDATE = { type: 'setMode', mode: 'default', destination: 'session' };
6
+ export const DEFAULT_DENY_MESSAGE = "The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed.";
7
+ export function isPermissionMode(value) {
8
+ return typeof value === 'string' && PERMISSION_MODES.has(value);
9
+ }
10
+ const str = (value) => (typeof value === 'string' ? value : undefined);
11
+ const bool = (value) => (typeof value === 'boolean' ? value : undefined);
12
+ export const stripAnsi = (value) => value?.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '');
13
+ function kindOf(toolName) {
14
+ if (toolName === 'AskUserQuestion')
15
+ return 'ask_user_question';
16
+ if (toolName === 'ExitPlanMode')
17
+ return 'exit_plan_mode';
18
+ return 'tool';
19
+ }
20
+ // map a cli can_use_tool request into the ws v2 claude_permission_request payload
21
+ export function toPermissionRequest(sessionId, requestId, request) {
22
+ const toolName = str(request['tool_name']) ?? 'unknown';
23
+ const input = request['input'] && typeof request['input'] === 'object' ? request['input'] : {};
24
+ const suggestions = Array.isArray(request['permission_suggestions'])
25
+ ? request['permission_suggestions'].filter((s) => !!s && typeof s === 'object')
26
+ : [];
27
+ return {
28
+ type: 'claude_permission_request',
29
+ sessionId,
30
+ requestId,
31
+ kind: kindOf(toolName),
32
+ toolName,
33
+ displayName: str(request['display_name']),
34
+ title: str(request['title']),
35
+ description: str(request['description']),
36
+ input,
37
+ toolUseId: str(request['tool_use_id']),
38
+ suggestions,
39
+ decisionReason: stripAnsi(str(request['decision_reason'])),
40
+ blockedPath: str(request['blocked_path']),
41
+ defaultToNo: bool(request['default_to_no']),
42
+ suppressAlwaysAllowRule: bool(request['suppress_always_allow_rule']),
43
+ requiresUserInteraction: bool(request['requires_user_interaction']),
44
+ agentId: str(request['agent_id']),
45
+ };
46
+ }
47
+ // json with sorted object keys so structurally equal updates compare equal
48
+ function canonical(value) {
49
+ return JSON.stringify(value, (_key, v) => (v && typeof v === 'object' && !Array.isArray(v)
50
+ ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => (a < b ? -1 : 1)))
51
+ : v));
52
+ }
53
+ // keep only updates the prompt offered (rules may change destination); drop bypass unless allowed.
54
+ // without --allow-remote-config a rule meant for user settings lands in this project's local ones
55
+ export function filterPermissionUpdates(updates, suggestions, allowBypass) {
56
+ if (!Array.isArray(updates))
57
+ return [];
58
+ const resetMode = canonical(RESET_MODE_UPDATE);
59
+ const local = (u) => u['destination'] === 'userSettings' && !remoteUserConfigAllowed() ? { ...u, destination: 'localSettings' } : u;
60
+ return updates.filter((update) => {
61
+ if (!update || typeof update !== 'object')
62
+ return false;
63
+ const u = update;
64
+ if (u['type'] === 'setMode' && u['mode'] === 'bypassPermissions' && !allowBypass)
65
+ return false;
66
+ const key = canonical(u);
67
+ if (key === resetMode)
68
+ return true;
69
+ const destination = u['destination'];
70
+ return suggestions.some((s) => (s['type'] === 'setMode'
71
+ ? key === canonical(s)
72
+ : typeof destination === 'string' && DESTINATIONS.has(destination) && key === canonical({ ...s, destination })));
73
+ }).map(local);
74
+ }
75
+ // build the PermissionResult written back to the cli for a can_use_tool request
76
+ export function buildPermissionResult(pending, decision, allowBypass) {
77
+ if (decision.behavior === 'allow') {
78
+ return {
79
+ behavior: 'allow',
80
+ updatedInput: decision.updatedInput ?? pending.input,
81
+ updatedPermissions: filterPermissionUpdates(decision.updatedPermissions, pending.suggestions, allowBypass),
82
+ };
83
+ }
84
+ const message = decision.message?.trim() ? decision.message : DEFAULT_DENY_MESSAGE;
85
+ return { behavior: 'deny', message, interrupt: decision.interrupt ?? !decision.message?.trim() };
86
+ }
87
+ // validate a claude_permission_response payload coming from the app
88
+ export function parsePermissionDecision(msg) {
89
+ const behavior = msg['behavior'];
90
+ if (behavior !== 'allow' && behavior !== 'deny')
91
+ return null;
92
+ const updatedInput = msg['updatedInput'];
93
+ return {
94
+ behavior,
95
+ updatedInput: updatedInput && typeof updatedInput === 'object' && !Array.isArray(updatedInput) ? updatedInput : undefined,
96
+ updatedPermissions: msg['updatedPermissions'],
97
+ message: str(msg['message']),
98
+ interrupt: bool(msg['interrupt']),
99
+ };
100
+ }
101
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/engine/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ // how long the shared probe waits for the next account-wide read before it closes
2
+ const PROBE_IDLE_MS = 60_000;
3
+ // one silent claude answers account-wide reads while no chat runs, instead of a claude per
4
+ // read; it closes once nothing used it for a while, and starts again when needed
5
+ export class ProbePool {
6
+ startProbe;
7
+ idleMs;
8
+ probe = null;
9
+ users = 0;
10
+ idle = null;
11
+ constructor(startProbe, idleMs = PROBE_IDLE_MS) {
12
+ this.startProbe = startProbe;
13
+ this.idleMs = idleMs;
14
+ }
15
+ async use(fn) {
16
+ if (this.idle)
17
+ clearTimeout(this.idle);
18
+ this.idle = null;
19
+ this.users++;
20
+ try {
21
+ return await fn(await this.live());
22
+ }
23
+ finally {
24
+ this.users--;
25
+ if (this.users === 0 && this.probe) {
26
+ this.idle = setTimeout(() => void this.close(), this.idleMs);
27
+ this.idle.unref?.();
28
+ }
29
+ }
30
+ }
31
+ async close() {
32
+ if (this.idle)
33
+ clearTimeout(this.idle);
34
+ this.idle = null;
35
+ const starting = this.probe;
36
+ this.probe = null;
37
+ const probe = await starting?.catch(() => null);
38
+ await probe?.close('probe');
39
+ }
40
+ // the shared probe, started again when it never came up or has exited since
41
+ async live() {
42
+ const current = this.probe;
43
+ const probe = await current?.catch(() => null);
44
+ if (probe?.alive)
45
+ return probe;
46
+ if (this.probe === current)
47
+ this.probe = this.startProbe();
48
+ return this.probe;
49
+ }
50
+ }
51
+ //# sourceMappingURL=probePool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probePool.js","sourceRoot":"","sources":["../../src/engine/probePool.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B,2FAA2F;AAC3F,iFAAiF;AACjF,MAAM,OAAO,SAAS;IAMD;IACA;IANX,KAAK,GAAkC,IAAI,CAAC;IAC5C,KAAK,GAAG,CAAC,CAAC;IACV,IAAI,GAA0B,IAAI,CAAC;IAE3C,YACmB,UAAwC,EACxC,SAAS,aAAa;QADtB,eAAU,GAAV,UAAU,CAA8B;QACxC,WAAM,GAAN,MAAM,CAAgB;IACtC,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAI,EAA0C;QACrD,IAAI,IAAI,CAAC,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC7D,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,4EAA4E;IACpE,KAAK,CAAC,IAAI;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,KAAK,EAAE,KAAK;YAAE,OAAO,KAAK,CAAC;QAC/B,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC,KAAM,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,45 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ // on posix each claude leads its own process group, so a kill reaches the jobs it started (a
3
+ // Bash tool left running) too; windows kills the tree with taskkill /T instead
4
+ export const OWN_GROUP = process.platform !== 'win32';
5
+ // groups still running when the cli exits go with it, as they would have with the terminal's
6
+ // ctrl+c had they stayed in its group
7
+ const liveGroups = new Set();
8
+ let exitHookSet = false;
9
+ function killGroup(pid) {
10
+ try {
11
+ process.kill(-pid, 'SIGKILL');
12
+ }
13
+ catch { }
14
+ }
15
+ // a child spawned as the leader of its own group (detached: OWN_GROUP)
16
+ export function trackGroup(pid) {
17
+ liveGroups.add(pid);
18
+ if (exitHookSet)
19
+ return;
20
+ exitHookSet = true;
21
+ process.on('exit', () => {
22
+ for (const group of liveGroups)
23
+ killGroup(group);
24
+ });
25
+ }
26
+ // the child exited: its pid may be handed to another process from now on
27
+ export function untrackGroup(pid) {
28
+ liveGroups.delete(pid);
29
+ }
30
+ // kill a child and everything it started
31
+ export function killTree(child) {
32
+ if (process.platform === 'win32' && child.pid) {
33
+ spawnSync('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' });
34
+ }
35
+ else if (OWN_GROUP && child.pid) {
36
+ killGroup(child.pid);
37
+ }
38
+ else {
39
+ try {
40
+ child.kill('SIGKILL');
41
+ }
42
+ catch { }
43
+ }
44
+ }
45
+ //# sourceMappingURL=processTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processTree.js","sourceRoot":"","sources":["../../src/engine/processTree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AAElE,6FAA6F;AAC7F,+EAA+E;AAC/E,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAEtD,6FAA6F;AAC7F,sCAAsC;AACtC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AACrC,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW;QAAE,OAAO;IACxB,WAAW,GAAG,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACtB,KAAK,MAAM,KAAK,IAAI,UAAU;YAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,QAAQ,CAAC,KAAmB;IAC1C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QAC9C,SAAS,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzG,CAAC;SAAM,IAAI,SAAS,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QAClC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACzC,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ // whether the app may change settings that apply to every claude session on this machine
2
+ // (~/.claude/settings.json hooks and rules, user-scope mcp servers). they outlive kumo, so the app
3
+ // only gets them when kumo runs with --allow-remote-config
4
+ let allowed = false;
5
+ export const ALLOW_REMOTE_CONFIG_FLAG = '--allow-remote-config';
6
+ export function allowRemoteUserConfig(value) {
7
+ allowed = value;
8
+ }
9
+ export function remoteUserConfigAllowed() {
10
+ return allowed;
11
+ }
12
+ export function assertUserConfigAllowed() {
13
+ if (!allowed) {
14
+ throw new Error(`Changing user settings from the app needs kumo started with ${ALLOW_REMOTE_CONFIG_FLAG}. Use project or local settings instead.`);
15
+ }
16
+ }
17
+ //# sourceMappingURL=remoteConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteConfig.js","sourceRoot":"","sources":["../../src/engine/remoteConfig.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,mGAAmG;AACnG,2DAA2D;AAC3D,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,MAAM,CAAC,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAEhE,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,+DAA+D,wBAAwB,0CAA0C,CAAC,CAAC;IACrJ,CAAC;AACH,CAAC"}