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.
- package/README.md +26 -13
- package/dist/auth/credentialsStore.js +20 -7
- package/dist/auth/credentialsStore.js.map +1 -1
- package/dist/claude/conversation.js +272 -0
- package/dist/claude/conversation.js.map +1 -0
- package/dist/claude/transcriptParser.js +140 -36
- package/dist/claude/transcriptParser.js.map +1 -1
- package/dist/commands/cliArgs.js +1 -0
- package/dist/commands/cliArgs.js.map +1 -1
- package/dist/core/config.js +1 -9
- package/dist/core/config.js.map +1 -1
- package/dist/core/logger.js +50 -21
- package/dist/core/logger.js.map +1 -1
- package/dist/core/projectFileWatcher.js +100 -36
- package/dist/core/projectFileWatcher.js.map +1 -1
- package/dist/engine/claudeArgs.js +106 -0
- package/dist/engine/claudeArgs.js.map +1 -0
- package/dist/engine/claudeBinary.js +94 -0
- package/dist/engine/claudeBinary.js.map +1 -0
- package/dist/engine/claudeConfig.js +127 -0
- package/dist/engine/claudeConfig.js.map +1 -0
- package/dist/engine/claudeLogin.js +76 -0
- package/dist/engine/claudeLogin.js.map +1 -0
- package/dist/engine/controlChannel.js +75 -0
- package/dist/engine/controlChannel.js.map +1 -0
- package/dist/engine/liveTranscript.js +150 -0
- package/dist/engine/liveTranscript.js.map +1 -0
- package/dist/engine/ndjson.js +48 -0
- package/dist/engine/ndjson.js.map +1 -0
- package/dist/engine/permissions.js +101 -0
- package/dist/engine/permissions.js.map +1 -0
- package/dist/engine/probePool.js +51 -0
- package/dist/engine/probePool.js.map +1 -0
- package/dist/engine/processTree.js +45 -0
- package/dist/engine/processTree.js.map +1 -0
- package/dist/engine/remoteConfig.js +17 -0
- package/dist/engine/remoteConfig.js.map +1 -0
- package/dist/engine/sessionManager.js +444 -0
- package/dist/engine/sessionManager.js.map +1 -0
- package/dist/engine/settingsCommands.js +260 -0
- package/dist/engine/settingsCommands.js.map +1 -0
- package/dist/engine/streamSession.js +502 -0
- package/dist/engine/streamSession.js.map +1 -0
- package/dist/engine/taskTracker.js +110 -0
- package/dist/engine/taskTracker.js.map +1 -0
- package/dist/engine/toolLabels.js +32 -0
- package/dist/engine/toolLabels.js.map +1 -0
- package/dist/handlers/controlRequest.js +17 -0
- package/dist/handlers/controlRequest.js.map +1 -0
- package/dist/handlers/fileHandlers.js +12 -0
- package/dist/handlers/fileHandlers.js.map +1 -1
- package/dist/handlers/messageRouter.js +8 -1
- package/dist/handlers/messageRouter.js.map +1 -1
- package/dist/handlers/promptImages.js +5 -91
- package/dist/handlers/promptImages.js.map +1 -1
- package/dist/handlers/runtimeHandlers.js +100 -32
- package/dist/handlers/runtimeHandlers.js.map +1 -1
- package/dist/handlers/sessionHandlers.js +85 -80
- package/dist/handlers/sessionHandlers.js.map +1 -1
- package/dist/handlers/terminalHandlers.js +9 -2
- package/dist/handlers/terminalHandlers.js.map +1 -1
- package/dist/http/httpClient.js +6 -0
- package/dist/http/httpClient.js.map +1 -1
- package/dist/index.js +87 -50
- package/dist/index.js.map +1 -1
- package/dist/pty/terminalManager.js +58 -11
- package/dist/pty/terminalManager.js.map +1 -1
- package/dist/services/bootstrapService.js +17 -1
- package/dist/services/bootstrapService.js.map +1 -1
- package/dist/services/claudeAdapterProxy.js +68 -21
- package/dist/services/claudeAdapterProxy.js.map +1 -1
- package/dist/services/cliRuntime.js +39 -32
- package/dist/services/cliRuntime.js.map +1 -1
- package/dist/services/effortService.js +13 -60
- package/dist/services/effortService.js.map +1 -1
- package/dist/services/fileService.js +50 -24
- package/dist/services/fileService.js.map +1 -1
- package/dist/services/forkService.js +120 -0
- package/dist/services/forkService.js.map +1 -0
- package/dist/services/modelService.js +86 -89
- package/dist/services/modelService.js.map +1 -1
- package/dist/services/pairingService.js +21 -15
- package/dist/services/pairingService.js.map +1 -1
- package/dist/services/sessionListService.js +7 -9
- package/dist/services/sessionListService.js.map +1 -1
- package/dist/services/sessionService.js +245 -106
- package/dist/services/sessionService.js.map +1 -1
- package/dist/services/tunnelHelpers.js +9 -5
- package/dist/services/tunnelHelpers.js.map +1 -1
- package/dist/services/tunnelService.js +21 -5
- package/dist/services/tunnelService.js.map +1 -1
- package/dist/transport/wsClient.js +60 -42
- package/dist/transport/wsClient.js.map +1 -1
- package/dist/utils/ignorePaths.js +3 -3
- package/dist/utils/ignorePaths.js.map +1 -1
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/localHost.js +17 -0
- package/dist/utils/localHost.js.map +1 -0
- package/dist/utils/safePath.js +51 -20
- package/dist/utils/safePath.js.map +1 -1
- package/package.json +5 -12
- package/dist/ansiCodes.js +0 -107
- package/dist/ansiCodes.js.map +0 -1
- package/dist/auth/credentialsStore.test.js +0 -60
- package/dist/auth/credentialsStore.test.js.map +0 -1
- package/dist/claude/fileHistory.js +0 -79
- package/dist/claude/fileHistory.js.map +0 -1
- package/dist/claude/generateHookSettings.js +0 -23
- package/dist/claude/generateHookSettings.js.map +0 -1
- package/dist/claude/hookServer.js +0 -33
- package/dist/claude/hookServer.js.map +0 -1
- package/dist/claude/sessionScanner.js +0 -162
- package/dist/claude/sessionScanner.js.map +0 -1
- package/dist/claude/sessionScanner.test.js +0 -24
- package/dist/claude/sessionScanner.test.js.map +0 -1
- package/dist/claude/transcriptParser.test.js +0 -78
- package/dist/claude/transcriptParser.test.js.map +0 -1
- package/dist/commands/cliArgs.test.js +0 -25
- package/dist/commands/cliArgs.test.js.map +0 -1
- package/dist/config.js +0 -40
- package/dist/config.js.map +0 -1
- package/dist/credentialsStore.js +0 -57
- package/dist/credentialsStore.js.map +0 -1
- package/dist/generateHookSettings.js +0 -30
- package/dist/generateHookSettings.js.map +0 -1
- package/dist/handlers/fileHandlerPayloads.test.js +0 -55
- package/dist/handlers/fileHandlerPayloads.test.js.map +0 -1
- package/dist/handlers/promptImages.test.js +0 -52
- package/dist/handlers/promptImages.test.js.map +0 -1
- package/dist/hookServer.js +0 -32
- package/dist/hookServer.js.map +0 -1
- package/dist/ignorePaths.js +0 -68
- package/dist/ignorePaths.js.map +0 -1
- package/dist/loadDotEnv.js +0 -79
- package/dist/loadDotEnv.js.map +0 -1
- package/dist/logger.js +0 -29
- package/dist/logger.js.map +0 -1
- package/dist/portForwardManager.js +0 -97
- package/dist/portForwardManager.js.map +0 -1
- package/dist/projectHistoryReader.js +0 -85
- package/dist/projectHistoryReader.js.map +0 -1
- package/dist/pty/ansiCodes.js +0 -14
- package/dist/pty/ansiCodes.js.map +0 -1
- package/dist/pty/notificationDetector.js +0 -29
- package/dist/pty/notificationDetector.js.map +0 -1
- package/dist/pty/notificationDetector.test.js +0 -24
- package/dist/pty/notificationDetector.test.js.map +0 -1
- package/dist/pty/ptyMenuParser.js +0 -91
- package/dist/pty/ptyMenuParser.js.map +0 -1
- package/dist/pty/ptyMenuParser.test.js +0 -26
- package/dist/pty/ptyMenuParser.test.js.map +0 -1
- package/dist/pty/ptySnapshotRenderer.js +0 -71
- package/dist/pty/ptySnapshotRenderer.js.map +0 -1
- package/dist/pty/selectionMenuDetector.js +0 -49
- package/dist/pty/selectionMenuDetector.js.map +0 -1
- package/dist/pty/selectionMenuDetector.test.js +0 -62
- package/dist/pty/selectionMenuDetector.test.js.map +0 -1
- package/dist/pty/selectionMenuMeta.js +0 -54
- package/dist/pty/selectionMenuMeta.js.map +0 -1
- package/dist/pty/selectionMenuMeta.test.js +0 -26
- package/dist/pty/selectionMenuMeta.test.js.map +0 -1
- package/dist/pty/selectionMenuParser.js +0 -83
- package/dist/pty/selectionMenuParser.js.map +0 -1
- package/dist/pty/selectionMenuParser.test.js +0 -30
- package/dist/pty/selectionMenuParser.test.js.map +0 -1
- package/dist/pty/spawn.js +0 -104
- package/dist/pty/spawn.js.map +0 -1
- package/dist/pty/spawn.test.js +0 -17
- package/dist/pty/spawn.test.js.map +0 -1
- package/dist/pty/statusSessionDetector.js +0 -28
- package/dist/pty/statusSessionDetector.js.map +0 -1
- package/dist/pty/statusSessionDetector.test.js +0 -23
- package/dist/pty/statusSessionDetector.test.js.map +0 -1
- package/dist/pty/textInputDetector.js +0 -60
- package/dist/pty/textInputDetector.js.map +0 -1
- package/dist/pty/textInputDetector.test.js +0 -32
- package/dist/pty/textInputDetector.test.js.map +0 -1
- package/dist/ptyMenuParser.js +0 -470
- package/dist/ptyMenuParser.js.map +0 -1
- package/dist/ptySnapshotRenderer.js +0 -78
- package/dist/ptySnapshotRenderer.js.map +0 -1
- package/dist/services/checkpointService.js +0 -113
- package/dist/services/checkpointService.js.map +0 -1
- package/dist/services/checkpointService.test.js +0 -61
- package/dist/services/checkpointService.test.js.map +0 -1
- package/dist/services/claudeMenuBridge.js +0 -116
- package/dist/services/claudeMenuBridge.js.map +0 -1
- package/dist/services/claudeMenuBridge.test.js +0 -90
- package/dist/services/claudeMenuBridge.test.js.map +0 -1
- package/dist/services/claudeService.js +0 -146
- package/dist/services/claudeService.js.map +0 -1
- package/dist/services/claudeService.test.js +0 -39
- package/dist/services/claudeService.test.js.map +0 -1
- package/dist/services/cliRuntime.test.js +0 -55
- package/dist/services/cliRuntime.test.js.map +0 -1
- package/dist/services/modelAdapter.test.js +0 -47
- package/dist/services/modelAdapter.test.js.map +0 -1
- package/dist/services/modelArgs.test.js +0 -64
- package/dist/services/modelArgs.test.js.map +0 -1
- package/dist/services/modelBaseUrl.test.js +0 -32
- package/dist/services/modelBaseUrl.test.js.map +0 -1
- package/dist/services/modelService.test.js +0 -136
- package/dist/services/modelService.test.js.map +0 -1
- package/dist/services/notificationDedupe.js +0 -23
- package/dist/services/notificationDedupe.js.map +0 -1
- package/dist/services/notificationDedupe.test.js +0 -20
- package/dist/services/notificationDedupe.test.js.map +0 -1
- package/dist/services/sessionListService.test.js +0 -22
- package/dist/services/sessionListService.test.js.map +0 -1
- package/dist/services/sessionRollbackService.js +0 -195
- package/dist/services/sessionRollbackService.js.map +0 -1
- package/dist/services/sessionRollbackService.test.js +0 -142
- package/dist/services/sessionRollbackService.test.js.map +0 -1
- package/dist/services/tunnelHelpers.test.js +0 -42
- package/dist/services/tunnelHelpers.test.js.map +0 -1
- package/dist/services/tunnelService.test.js +0 -91
- package/dist/services/tunnelService.test.js.map +0 -1
- package/dist/sessionScanner.js +0 -271
- package/dist/sessionScanner.js.map +0 -1
- package/dist/snapshotScanner.js +0 -154
- package/dist/snapshotScanner.js.map +0 -1
- package/dist/spawn.js +0 -79
- package/dist/spawn.js.map +0 -1
- package/dist/terminalManager.js +0 -73
- package/dist/terminalManager.js.map +0 -1
- package/dist/transport/directWsServer.js +0 -135
- package/dist/transport/directWsServer.js.map +0 -1
- package/dist/transport/webrtcTransport.js +0 -145
- package/dist/transport/webrtcTransport.js.map +0 -1
- package/dist/transport/webrtcTransport.test.js +0 -104
- package/dist/transport/webrtcTransport.test.js.map +0 -1
- package/dist/transport/webrtcTypes.js +0 -29
- package/dist/transport/webrtcTypes.js.map +0 -1
- package/dist/transport/webrtcTypes.test.js +0 -20
- package/dist/transport/webrtcTypes.test.js.map +0 -1
- package/dist/utils/ptyBuffer.js +0 -46
- package/dist/utils/ptyBuffer.js.map +0 -1
- package/scripts/claude_launcher.cjs +0 -71
- package/scripts/run-tests.mjs +0 -46
- package/scripts/session_hook_forwarder.cjs +0 -44
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnelHelpers.js","sourceRoot":"","sources":["../../src/services/tunnelHelpers.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE/C,
|
|
1
|
+
{"version":3,"file":"tunnelHelpers.js","sourceRoot":"","sources":["../../src/services/tunnelHelpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,25 +48,41 @@ async function proxyHttpRequest(input) {
|
|
|
48
48
|
req.end();
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
|
+
// requests proxied at once; a page firing hundreds of calls waits on 503s instead of
|
|
52
|
+
// opening hundreds of sockets and buffers on this machine
|
|
53
|
+
const MAX_TUNNEL_IN_FLIGHT = 32;
|
|
54
|
+
let inFlight = 0;
|
|
51
55
|
// proxy a http request from the server through this cli to a local service
|
|
52
56
|
export async function handleTunnelRequest(req) {
|
|
57
|
+
if (inFlight >= MAX_TUNNEL_IN_FLIGHT)
|
|
58
|
+
return tunnelError(String(req.requestId), 503, 'too many tunnel requests');
|
|
59
|
+
inFlight++;
|
|
60
|
+
try {
|
|
61
|
+
return await proxyTunnelRequest(req);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
inFlight--;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function proxyTunnelRequest(req) {
|
|
68
|
+
if (typeof req.method !== 'string' || !/^[A-Z]{1,16}$/.test(req.method))
|
|
69
|
+
return tunnelError(String(req.requestId), 400, 'invalid method');
|
|
53
70
|
const port = Number(req.port);
|
|
54
71
|
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
55
72
|
return tunnelError(req.requestId, 400, 'invalid port');
|
|
56
73
|
if (allowedPorts.size > 0 && !allowedPorts.has(port))
|
|
57
74
|
return tunnelError(req.requestId, 403, 'port not allowed');
|
|
58
75
|
const safePath = normalizeTunnelPath(req.path);
|
|
59
|
-
const
|
|
60
|
-
const url = `http://${targetHost}:${port}${safePath}`;
|
|
76
|
+
const url = `http://${DEFAULT_TUNNEL_HOST}:${port}${safePath}`;
|
|
61
77
|
const hostHeader = resolveTunnelHostHeader(port, req.host);
|
|
62
78
|
const body = decodeTunnelBody(req);
|
|
63
79
|
if (body && body.length > MAX_TUNNEL_BODY_BYTES)
|
|
64
80
|
return tunnelError(req.requestId, 413, 'request body too large');
|
|
65
|
-
const filteredHeaders = filterTunnelRequestHeaders(req.headers,
|
|
81
|
+
const filteredHeaders = filterTunnelRequestHeaders(req.headers, DEFAULT_TUNNEL_HOST, port, hostHeader);
|
|
66
82
|
log(`[tunnel] ${req.method} ${url}`);
|
|
67
83
|
try {
|
|
68
84
|
const res = await proxyHttpRequest({
|
|
69
|
-
hostname:
|
|
85
|
+
hostname: DEFAULT_TUNNEL_HOST,
|
|
70
86
|
port,
|
|
71
87
|
path: safePath,
|
|
72
88
|
method: req.method,
|
|
@@ -75,7 +91,7 @@ export async function handleTunnelRequest(req) {
|
|
|
75
91
|
});
|
|
76
92
|
const buf = res.body;
|
|
77
93
|
log(`[tunnel] response ${res.status} ${url} (${buf.length} bytes)`);
|
|
78
|
-
const respHeaders = rewriteTunnelResponseHeaders(res.headers,
|
|
94
|
+
const respHeaders = rewriteTunnelResponseHeaders(res.headers, DEFAULT_TUNNEL_HOST, port, hostHeader);
|
|
79
95
|
return { type: 'tunnel_response', requestId: req.requestId, status: res.status, headers: respHeaders, body: buf.toString('base64') };
|
|
80
96
|
}
|
|
81
97
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnelService.js","sourceRoot":"","sources":["../../src/services/tunnelService.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"tunnelService.js","sourceRoot":"","sources":["../../src/services/tunnelService.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,17 +9,25 @@ function stringifyPayload(data) {
|
|
|
9
9
|
return JSON.stringify({ error: error instanceof Error ? error.message : String(error) });
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
// terminal traffic is a frame per keystroke and per output burst: too chatty for the log
|
|
13
|
+
const UNLOGGED = new Set(['terminal_output', 'terminal_input']);
|
|
14
|
+
// one log line per frame, sized from the already serialized text
|
|
15
|
+
function logFrame(direction, msg, size) {
|
|
16
|
+
if (UNLOGGED.has(String(msg['type'])))
|
|
17
|
+
return;
|
|
18
|
+
const extras = ['requestId', 'terminalId', 'status'].filter((key) => msg[key] !== undefined).map((key) => ` ${key}=${String(msg[key])}`);
|
|
19
|
+
log(`[ws] ${direction} ${String(msg['type'])}${extras.join('')} ${size}B`);
|
|
20
|
+
}
|
|
21
|
+
// the server pings every 30s; missing two and a half of them means the link is dead
|
|
22
|
+
const SERVER_PING_TIMEOUT_MS = 75_000;
|
|
23
|
+
// the largest frame the app sends: a file write, prompt images or a 10 MB tunnel body as base64
|
|
24
|
+
const MAX_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
25
|
+
// reconnect waits double from 3s up to 30s, plus some jitter so many clis do not return at once
|
|
26
|
+
const RECONNECT_BASE_MS = 3000;
|
|
27
|
+
const RECONNECT_MAX_MS = 30_000;
|
|
28
|
+
export function reconnectDelay(attempt) {
|
|
29
|
+
const delay = Math.min(RECONNECT_BASE_MS * 2 ** Math.max(0, attempt - 1), RECONNECT_MAX_MS);
|
|
30
|
+
return delay + Math.floor(Math.random() * delay * 0.25);
|
|
23
31
|
}
|
|
24
32
|
export class WsClient {
|
|
25
33
|
onOpen;
|
|
@@ -27,74 +35,84 @@ export class WsClient {
|
|
|
27
35
|
onClose;
|
|
28
36
|
ws = null;
|
|
29
37
|
reconnectTimer = null;
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
pingWatchdog = null;
|
|
39
|
+
attempts = 0;
|
|
40
|
+
// close() was called: the socket stays down
|
|
41
|
+
closed = false;
|
|
32
42
|
constructor(onOpen, onMessage, onClose) {
|
|
33
43
|
this.onOpen = onOpen;
|
|
34
44
|
this.onMessage = onMessage;
|
|
35
45
|
this.onClose = onClose;
|
|
36
46
|
}
|
|
37
|
-
onSent(cb) { this.onSendListeners.push(cb); }
|
|
38
47
|
send(data) {
|
|
39
48
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
40
49
|
const payload = stringifyPayload(data);
|
|
41
|
-
|
|
50
|
+
logFrame('outgoing', data, payload.length);
|
|
42
51
|
this.ws.send(payload);
|
|
43
|
-
|
|
44
|
-
cb();
|
|
52
|
+
return;
|
|
45
53
|
}
|
|
54
|
+
// the app resyncs what it missed once the socket is back
|
|
55
|
+
log(`[ws] dropped ${String(data['type'])} while disconnected`);
|
|
46
56
|
}
|
|
47
57
|
connect() {
|
|
48
|
-
this.
|
|
49
|
-
|
|
58
|
+
this.closed = false;
|
|
59
|
+
const ws = new WebSocket(SERVER_WS(), { maxPayload: MAX_PAYLOAD_BYTES });
|
|
60
|
+
this.ws = ws;
|
|
61
|
+
// ws answers pings itself; a silent server means a half-open link, so drop it and reconnect
|
|
62
|
+
const armWatchdog = () => {
|
|
63
|
+
this.clearWatchdog();
|
|
64
|
+
this.pingWatchdog = setTimeout(() => ws.terminate(), SERVER_PING_TIMEOUT_MS);
|
|
65
|
+
};
|
|
66
|
+
ws.on('open', () => {
|
|
67
|
+
this.attempts = 0;
|
|
50
68
|
log(`[ws] connected to ${SERVER_WS()}`);
|
|
51
|
-
|
|
52
|
-
clearInterval(this.pingInterval);
|
|
53
|
-
this.pingInterval = setInterval(() => {
|
|
54
|
-
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
55
|
-
this.ws.ping();
|
|
56
|
-
this.send({ type: 'cli_heartbeat' });
|
|
57
|
-
}
|
|
58
|
-
}, 5000);
|
|
69
|
+
armWatchdog();
|
|
59
70
|
Promise.resolve(this.onOpen()).catch((e) => log(`[onOpen] error: ${e}`));
|
|
60
71
|
});
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
ws.on('ping', armWatchdog);
|
|
73
|
+
ws.on('message', (raw) => {
|
|
63
74
|
const rawText = raw.toString();
|
|
64
75
|
try {
|
|
65
76
|
const parsed = JSON.parse(rawText);
|
|
66
|
-
|
|
77
|
+
logFrame('incoming', parsed, rawText.length);
|
|
67
78
|
this.onMessage(parsed);
|
|
68
79
|
}
|
|
69
80
|
catch (error) {
|
|
70
81
|
log(`[ws] incoming parse error: ${error}`);
|
|
71
82
|
}
|
|
72
83
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
ws.on('close', () => {
|
|
85
|
+
this.clearWatchdog();
|
|
86
|
+
// closed on purpose, or replaced by a newer socket: no reconnect from here
|
|
87
|
+
if (this.closed || this.ws !== ws)
|
|
88
|
+
return;
|
|
89
|
+
const delay = reconnectDelay(++this.attempts);
|
|
90
|
+
log(`[ws] disconnected, reconnecting in ${Math.round(delay / 1000)}s`);
|
|
79
91
|
this.onClose?.();
|
|
80
|
-
this.reconnectTimer = setTimeout(() => this.connect(),
|
|
92
|
+
this.reconnectTimer = setTimeout(() => this.connect(), delay);
|
|
81
93
|
});
|
|
82
|
-
|
|
94
|
+
// the reason a connect failed; 'close' follows and schedules the retry
|
|
95
|
+
// a refused connect to localhost is an AggregateError with no message, only codes
|
|
96
|
+
ws.on('error', (error) => log(`[ws] error: ${error.message || error.code || error.name}`));
|
|
83
97
|
}
|
|
84
98
|
close() {
|
|
99
|
+
this.closed = true;
|
|
85
100
|
if (this.reconnectTimer) {
|
|
86
101
|
clearTimeout(this.reconnectTimer);
|
|
87
102
|
this.reconnectTimer = null;
|
|
88
103
|
}
|
|
89
|
-
|
|
90
|
-
clearInterval(this.pingInterval);
|
|
91
|
-
this.pingInterval = null;
|
|
92
|
-
}
|
|
104
|
+
this.clearWatchdog();
|
|
93
105
|
try {
|
|
94
106
|
this.ws?.close();
|
|
95
107
|
}
|
|
96
108
|
catch { }
|
|
97
109
|
this.ws = null;
|
|
98
110
|
}
|
|
111
|
+
clearWatchdog() {
|
|
112
|
+
if (this.pingWatchdog) {
|
|
113
|
+
clearTimeout(this.pingWatchdog);
|
|
114
|
+
this.pingWatchdog = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
99
117
|
}
|
|
100
118
|
//# sourceMappingURL=wsClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wsClient.js","sourceRoot":"","sources":["../../src/transport/wsClient.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAI9C,SAAS,gBAAgB,CAAC,IAAa;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED,SAAS,
|
|
1
|
+
{"version":3,"file":"wsClient.js","sourceRoot":"","sources":["../../src/transport/wsClient.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAI9C,SAAS,gBAAgB,CAAC,IAAa;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED,yFAAyF;AACzF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEhE,iEAAiE;AACjE,SAAS,QAAQ,CAAC,SAAkC,EAAE,GAA4B,EAAE,IAAY;IAC9F,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAAE,OAAO;IAC9C,MAAM,MAAM,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IACzI,GAAG,CAAC,QAAQ,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AAC7E,CAAC;AAED,oFAAoF;AACpF,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,gGAAgG;AAChG,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,gGAAgG;AAChG,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC5F,OAAO,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,QAAQ;IAST;IACA;IACA;IAVF,EAAE,GAAqB,IAAI,CAAC;IAC5B,cAAc,GAA0B,IAAI,CAAC;IAC7C,YAAY,GAA0B,IAAI,CAAC;IAC3C,QAAQ,GAAG,CAAC,CAAC;IACrB,4CAA4C;IACpC,MAAM,GAAG,KAAK,CAAC;IAEvB,YACU,MAAkC,EAClC,SAA2B,EAC3B,OAAoB;QAFpB,WAAM,GAAN,MAAM,CAA4B;QAClC,cAAS,GAAT,SAAS,CAAkB;QAC3B,YAAO,GAAP,OAAO,CAAa;IAC3B,CAAC;IAEJ,IAAI,CAAC,IAAY;QACf,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvC,QAAQ,CAAC,UAAU,EAAE,IAA+B,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACtE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QACD,yDAAyD;QACzD,GAAG,CAAC,gBAAgB,MAAM,CAAE,IAAgC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;IAC9F,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,4FAA4F;QAC5F,MAAM,WAAW,GAAG,GAAS,EAAE;YAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,sBAAsB,CAAC,CAAC;QAC/E,CAAC,CAAC;QACF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;YAClB,GAAG,CAAC,qBAAqB,SAAS,EAAE,EAAE,CAAC,CAAC;YACxC,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC3B,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YACvB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;gBAC9D,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAAC,GAAG,CAAC,8BAA8B,KAAK,EAAE,CAAC,CAAC;YAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,2EAA2E;YAC3E,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE;gBAAE,OAAO;YAC1C,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9C,GAAG,CAAC,sCAAsC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QACH,uEAAuE;QACvE,kFAAkF;QAClF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,OAAO,IAAK,KAA+B,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAAC,CAAC;QAC3F,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC;YAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAClC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;IACjB,CAAC;IAEO,aAAa;QACnB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAAC,CAAC;IACvF,CAAC;CACF"}
|
|
@@ -30,7 +30,7 @@ function parseGitignore(content) {
|
|
|
30
30
|
}
|
|
31
31
|
return names;
|
|
32
32
|
}
|
|
33
|
-
// load ignored names combining defaults + .gitignore in given root, cached by mtime
|
|
33
|
+
// load ignored names combining defaults + .gitignore in given root, cached by root and mtime
|
|
34
34
|
export function loadIgnoredNames(projectRoot) {
|
|
35
35
|
const gitignore = path.join(projectRoot, '.gitignore');
|
|
36
36
|
let mtime = 0;
|
|
@@ -38,7 +38,7 @@ export function loadIgnoredNames(projectRoot) {
|
|
|
38
38
|
mtime = fs.statSync(gitignore).mtimeMs;
|
|
39
39
|
}
|
|
40
40
|
catch { }
|
|
41
|
-
if (cache && cache.mtime === mtime)
|
|
41
|
+
if (cache && cache.root === projectRoot && cache.mtime === mtime)
|
|
42
42
|
return cache.set;
|
|
43
43
|
const set = new Set(DEFAULT_IGNORES);
|
|
44
44
|
if (mtime > 0) {
|
|
@@ -48,7 +48,7 @@ export function loadIgnoredNames(projectRoot) {
|
|
|
48
48
|
}
|
|
49
49
|
catch { }
|
|
50
50
|
}
|
|
51
|
-
cache = { mtime, set };
|
|
51
|
+
cache = { root: projectRoot, mtime, set };
|
|
52
52
|
return set;
|
|
53
53
|
}
|
|
54
54
|
//# sourceMappingURL=ignorePaths.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ignorePaths.js","sourceRoot":"","sources":["../../src/utils/ignorePaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,gEAAgE;AAChE,MAAM,eAAe,GAAa;IAChC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;IACnE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU;IACtE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe;IACpE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ;IACzD,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,aAAa;IACrE,MAAM,EAAE,aAAa,EAAE,oBAAoB;IAC3C,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS;IACtC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,kBAAkB;IACtD,+BAA+B;IAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa;IAC9C,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa;CAC7D,CAAC;AAEF,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"ignorePaths.js","sourceRoot":"","sources":["../../src/utils/ignorePaths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// readers for untyped json from claude's stream and the app: a wrong type reads as empty
|
|
2
|
+
export const str = (value) => (typeof value === 'string' ? value : '');
|
|
3
|
+
export const obj = (value) => value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
4
|
+
export const list = (value) => (Array.isArray(value) ? value.map(obj) : []);
|
|
5
|
+
// the keys of source that hold a value
|
|
6
|
+
export const pick = (source, keys) => Object.fromEntries(keys.filter((key) => source[key] !== undefined && source[key] !== null).map((key) => [key, source[key]]));
|
|
7
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/utils/json.ts"],"names":[],"mappings":"AAEA,yFAAyF;AAEzF,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAExF,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,KAAc,EAAc,EAAE,CAChD,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;AAE3F,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAc,EAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEnG,uCAAuC;AACvC,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAkB,EAAE,IAAc,EAAc,EAAE,CACrE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// loopback and private-network hosts, where plain http stays on this machine or the lan
|
|
2
|
+
export function isLocalHost(hostname) {
|
|
3
|
+
const host = hostname.replace(/^\[|\]$/g, '').toLowerCase();
|
|
4
|
+
return host === 'localhost' || host.endsWith('.local') || host === '::1'
|
|
5
|
+
|| /^127\./.test(host) || /^10\./.test(host) || /^192\.168\./.test(host) || /^172\.(1[6-9]|2\d|3[01])\./.test(host);
|
|
6
|
+
}
|
|
7
|
+
// whether a url sends its traffic in the clear to a host outside this machine and the lan
|
|
8
|
+
export function isCleartextRemote(rawUrl) {
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(rawUrl);
|
|
11
|
+
return (url.protocol === 'http:' || url.protocol === 'ws:') && !isLocalHost(url.hostname);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=localHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localHost.js","sourceRoot":"","sources":["../../src/utils/localHost.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5D,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,KAAK;WACnE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/utils/safePath.js
CHANGED
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import os from 'node:os';
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
//
|
|
3
|
+
// whether target lies outside root (root itself counts as inside)
|
|
4
|
+
function isOutside(root, target) {
|
|
5
|
+
const relative = path.relative(root, target);
|
|
6
|
+
return relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative);
|
|
7
|
+
}
|
|
8
|
+
// real location of a path that may not exist yet: resolve its nearest existing ancestor
|
|
9
|
+
function realpathLoose(target) {
|
|
10
|
+
let existing = target;
|
|
11
|
+
const tail = [];
|
|
12
|
+
for (;;) {
|
|
13
|
+
try {
|
|
14
|
+
return path.join(fs.realpathSync.native(existing), ...tail.reverse());
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
const parent = path.dirname(existing);
|
|
18
|
+
if (parent === existing)
|
|
19
|
+
return target;
|
|
20
|
+
tail.push(path.basename(existing));
|
|
21
|
+
existing = parent;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// resolve a user-supplied path inside root, absolute or relative; symlinks and junctions
|
|
26
|
+
// are followed so a link cannot lead out of the root.
|
|
5
27
|
// handles msys2/git-bash style paths like /e/Data/... → E:\Data\... on windows.
|
|
6
28
|
export function safePath(requestedPath, root = process.cwd()) {
|
|
7
29
|
let p = requestedPath || '.';
|
|
@@ -13,12 +35,24 @@ export function safePath(requestedPath, root = process.cwd()) {
|
|
|
13
35
|
const normalized = path.normalize(p);
|
|
14
36
|
const projectRoot = path.resolve(root);
|
|
15
37
|
const resolved = path.isAbsolute(normalized) ? path.resolve(normalized) : path.resolve(projectRoot, normalized);
|
|
16
|
-
|
|
17
|
-
if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
38
|
+
if (isOutside(projectRoot, resolved) || isOutside(realpathLoose(projectRoot), realpathLoose(resolved))) {
|
|
18
39
|
throw new Error('path traversal blocked');
|
|
19
40
|
}
|
|
20
41
|
return resolved;
|
|
21
42
|
}
|
|
43
|
+
// the project root a request works in: the cli's own folder, or a folder inside it
|
|
44
|
+
export function projectRootOf(cwd) {
|
|
45
|
+
return typeof cwd === 'string' && cwd ? safePath(cwd) : process.cwd();
|
|
46
|
+
}
|
|
47
|
+
// a path a mutating op may touch: given, inside root and not the root itself
|
|
48
|
+
export function mutablePath(requestedPath, root) {
|
|
49
|
+
if (typeof requestedPath !== 'string' || !requestedPath.trim())
|
|
50
|
+
throw new Error('path is required');
|
|
51
|
+
const resolved = safePath(requestedPath, root);
|
|
52
|
+
if (path.relative(path.resolve(root), resolved) === '')
|
|
53
|
+
throw new Error('refusing to modify the project root');
|
|
54
|
+
return resolved;
|
|
55
|
+
}
|
|
22
56
|
export function safeCwd(requestedCwd) {
|
|
23
57
|
if (!requestedCwd)
|
|
24
58
|
return process.cwd();
|
|
@@ -32,24 +66,21 @@ export function safeCwd(requestedCwd) {
|
|
|
32
66
|
return process.cwd();
|
|
33
67
|
}
|
|
34
68
|
}
|
|
35
|
-
// recursively copy a file or directory tree
|
|
69
|
+
// recursively copy a file or directory tree; links are copied as links, and a folder cannot be copied into itself
|
|
36
70
|
export function copyRecursive(src, dest) {
|
|
37
|
-
|
|
38
|
-
if (stat.isDirectory()) {
|
|
39
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
40
|
-
for (const child of fs.readdirSync(src)) {
|
|
41
|
-
copyRecursive(path.join(src, child), path.join(dest, child));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
fs.copyFileSync(src, dest);
|
|
46
|
-
}
|
|
71
|
+
fs.cpSync(src, dest, { recursive: true, verbatimSymlinks: true });
|
|
47
72
|
}
|
|
48
|
-
// claude
|
|
73
|
+
// claude code's folder name for a project, as its own code makes it: every character but
|
|
74
|
+
// a-z, A-Z and 0-9 becomes "-", and a name past 200 characters is cut and ends in a hash of
|
|
75
|
+
// the cwd. any other spelling misses the folder of a cwd with a dot, a space or an accent
|
|
76
|
+
const MAX_PROJECT_FOLDER = 200;
|
|
49
77
|
export function cwdToProjectFolder(cwd) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
78
|
+
const name = cwd.replace(/[^a-zA-Z0-9]/g, '-');
|
|
79
|
+
if (name.length <= MAX_PROJECT_FOLDER)
|
|
80
|
+
return name;
|
|
81
|
+
let hash = 0;
|
|
82
|
+
for (let i = 0; i < cwd.length; i++)
|
|
83
|
+
hash = ((hash << 5) - hash + cwd.charCodeAt(i)) | 0;
|
|
84
|
+
return `${name.slice(0, MAX_PROJECT_FOLDER)}-${Math.abs(hash).toString(36)}`;
|
|
54
85
|
}
|
|
55
86
|
//# sourceMappingURL=safePath.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safePath.js","sourceRoot":"","sources":["../../src/utils/safePath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"safePath.js","sourceRoot":"","sources":["../../src/utils/safePath.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kumo-cli",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Kumo CLI — where your code drifts between devices, softly. A pairing-based companion for the Kumo app that bridges your terminal sessions to remote devices.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,13 +9,12 @@
|
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
-
"scripts",
|
|
13
12
|
"README.md",
|
|
14
13
|
"LICENSE"
|
|
15
14
|
],
|
|
16
15
|
"scripts": {
|
|
17
16
|
"dev": "node --no-deprecation --import tsx src/index.ts --env-file ../.env",
|
|
18
|
-
"build": "tsc",
|
|
17
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
|
|
19
18
|
"lint": "tsc --noEmit",
|
|
20
19
|
"test": "node ./scripts/run-tests.mjs",
|
|
21
20
|
"test:cov": "node ./scripts/run-tests.mjs --coverage",
|
|
@@ -27,14 +26,14 @@
|
|
|
27
26
|
},
|
|
28
27
|
"license": "MIT",
|
|
29
28
|
"author": "Kumo",
|
|
30
|
-
"homepage": "https://
|
|
29
|
+
"homepage": "https://kumocli.com",
|
|
31
30
|
"repository": {
|
|
32
31
|
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/
|
|
32
|
+
"url": "git+https://github.com/tungnguyensnk/kumo.git",
|
|
34
33
|
"directory": "cli"
|
|
35
34
|
},
|
|
36
35
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/
|
|
36
|
+
"url": "https://github.com/tungnguyensnk/kumo/issues"
|
|
38
37
|
},
|
|
39
38
|
"keywords": [
|
|
40
39
|
"kumo",
|
|
@@ -48,20 +47,14 @@
|
|
|
48
47
|
"websocket"
|
|
49
48
|
],
|
|
50
49
|
"dependencies": {
|
|
51
|
-
"@xterm/headless": "^6.0.0",
|
|
52
|
-
"bonjour-service": "^1.3.0",
|
|
53
50
|
"claude-adapter": "^2.1.1",
|
|
54
51
|
"fastify": "^5.8.5",
|
|
55
|
-
"http-proxy": "^1.18.1",
|
|
56
52
|
"node-pty": "^1.1.0",
|
|
57
53
|
"openai": "^6.39.1",
|
|
58
|
-
"uuid": "^10.0.0",
|
|
59
54
|
"ws": "^8.18.0"
|
|
60
55
|
},
|
|
61
56
|
"devDependencies": {
|
|
62
|
-
"@types/http-proxy": "^1.17.17",
|
|
63
57
|
"@types/node": "^22.0.0",
|
|
64
|
-
"@types/uuid": "^10.0.0",
|
|
65
58
|
"@types/ws": "^8.5.12",
|
|
66
59
|
"tsx": "^4.19.2",
|
|
67
60
|
"typescript": "^5.6.0"
|