@episoda/cli 0.2.220 → 0.2.222
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/daemon/daemon-process.js +102 -9
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -36,7 +36,8 @@ var require_command_protocol = __commonJS({
|
|
|
36
36
|
"../core/dist/command-protocol.js"(exports2) {
|
|
37
37
|
"use strict";
|
|
38
38
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
39
|
-
exports2.WORKTREE_STATUS_VALUES = void 0;
|
|
39
|
+
exports2.WORKTREE_STATUS_VALUES = exports2.DAEMON_PROTOCOL_VERSION = void 0;
|
|
40
|
+
exports2.DAEMON_PROTOCOL_VERSION = 2;
|
|
40
41
|
exports2.WORKTREE_STATUS_VALUES = [
|
|
41
42
|
"pending",
|
|
42
43
|
"provisioning",
|
|
@@ -2180,6 +2181,7 @@ var require_websocket_client = __commonJS({
|
|
|
2180
2181
|
exports2.EpisodaClient = void 0;
|
|
2181
2182
|
var ws_1 = __importDefault(require("ws"));
|
|
2182
2183
|
var https_1 = __importDefault(require("https"));
|
|
2184
|
+
var command_protocol_1 = require_command_protocol();
|
|
2183
2185
|
var version_1 = require_version();
|
|
2184
2186
|
var ipv4Agent = new https_1.default.Agent({ family: 4 });
|
|
2185
2187
|
var MAX_RETRY_DURATION = 6 * 60 * 60 * 1e3;
|
|
@@ -2196,6 +2198,7 @@ var require_websocket_client = __commonJS({
|
|
|
2196
2198
|
this.autoReconnectEnabled = true;
|
|
2197
2199
|
this.url = "";
|
|
2198
2200
|
this.token = "";
|
|
2201
|
+
this.protocolVersion = command_protocol_1.DAEMON_PROTOCOL_VERSION;
|
|
2199
2202
|
this.isConnected = false;
|
|
2200
2203
|
this.isDisconnecting = false;
|
|
2201
2204
|
this.isGracefulShutdown = false;
|
|
@@ -2221,11 +2224,15 @@ var require_websocket_client = __commonJS({
|
|
|
2221
2224
|
this.osArch = deviceInfo?.osArch;
|
|
2222
2225
|
this.daemonPid = deviceInfo?.daemonPid;
|
|
2223
2226
|
this.cliVersion = deviceInfo?.cliVersion;
|
|
2227
|
+
this.protocolVersion = deviceInfo?.protocolVersion ?? command_protocol_1.DAEMON_PROTOCOL_VERSION;
|
|
2224
2228
|
this.cliPackageName = deviceInfo?.cliPackageName;
|
|
2225
2229
|
this.capabilities = deviceInfo?.capabilities;
|
|
2230
|
+
this.ptyProviderVersions = deviceInfo?.ptyProviderVersions;
|
|
2226
2231
|
this.environment = deviceInfo?.environment;
|
|
2227
2232
|
this.containerId = deviceInfo?.containerId;
|
|
2233
|
+
this.sessionGeneration = void 0;
|
|
2228
2234
|
this.isDisconnecting = false;
|
|
2235
|
+
this.autoReconnectEnabled = true;
|
|
2229
2236
|
this.isGracefulShutdown = false;
|
|
2230
2237
|
this.isIntentionalDisconnect = false;
|
|
2231
2238
|
this.lastConnectAttemptTime = Date.now();
|
|
@@ -2262,8 +2269,10 @@ var require_websocket_client = __commonJS({
|
|
|
2262
2269
|
type: "auth",
|
|
2263
2270
|
token,
|
|
2264
2271
|
version: this.cliVersion || version_1.VERSION,
|
|
2272
|
+
protocolVersion: this.protocolVersion,
|
|
2265
2273
|
cliPackageName: this.cliPackageName,
|
|
2266
2274
|
capabilities: this.capabilities,
|
|
2275
|
+
ptyProviderVersions: this.ptyProviderVersions,
|
|
2267
2276
|
environment: this.environment,
|
|
2268
2277
|
machineId,
|
|
2269
2278
|
containerId: this.containerId,
|
|
@@ -2295,6 +2304,7 @@ var require_websocket_client = __commonJS({
|
|
|
2295
2304
|
this.ws.on("close", (code, reason) => {
|
|
2296
2305
|
console.log(`[EpisodaClient] WebSocket closed: ${code} ${reason.toString()}`);
|
|
2297
2306
|
this.isConnected = false;
|
|
2307
|
+
this.sessionGeneration = void 0;
|
|
2298
2308
|
const willReconnect = !this.isDisconnecting && this.autoReconnectEnabled;
|
|
2299
2309
|
this.emit({
|
|
2300
2310
|
type: "disconnected",
|
|
@@ -2356,6 +2366,7 @@ var require_websocket_client = __commonJS({
|
|
|
2356
2366
|
this.ws = void 0;
|
|
2357
2367
|
}
|
|
2358
2368
|
this.isConnected = false;
|
|
2369
|
+
this.sessionGeneration = void 0;
|
|
2359
2370
|
}
|
|
2360
2371
|
/**
|
|
2361
2372
|
* Register an event handler
|
|
@@ -2433,7 +2444,8 @@ var require_websocket_client = __commonJS({
|
|
|
2433
2444
|
*/
|
|
2434
2445
|
getStatus() {
|
|
2435
2446
|
return {
|
|
2436
|
-
connected: this.isConnected
|
|
2447
|
+
connected: this.isConnected,
|
|
2448
|
+
sessionGeneration: this.sessionGeneration
|
|
2437
2449
|
};
|
|
2438
2450
|
}
|
|
2439
2451
|
/**
|
|
@@ -2475,6 +2487,9 @@ var require_websocket_client = __commonJS({
|
|
|
2475
2487
|
* Handle incoming message from server
|
|
2476
2488
|
*/
|
|
2477
2489
|
handleMessage(message) {
|
|
2490
|
+
if (message.type === "auth_success") {
|
|
2491
|
+
this.sessionGeneration = message.sessionGeneration;
|
|
2492
|
+
}
|
|
2478
2493
|
if (message.type === "shutdown") {
|
|
2479
2494
|
console.log("[EpisodaClient] Received graceful shutdown message from server");
|
|
2480
2495
|
this.isGracefulShutdown = true;
|
|
@@ -2492,6 +2507,11 @@ var require_websocket_client = __commonJS({
|
|
|
2492
2507
|
this.consecutiveAuthFailures++;
|
|
2493
2508
|
console.warn(`[EpisodaClient] Auth failure (${this.consecutiveAuthFailures}): ${errorMessage.code}`);
|
|
2494
2509
|
}
|
|
2510
|
+
if (errorMessage.code === "DAEMON_UPDATE_REQUIRED" || errorMessage.code === "PROTOCOL_MISMATCH") {
|
|
2511
|
+
this.autoReconnectEnabled = false;
|
|
2512
|
+
const errorText = "message" in errorMessage && typeof errorMessage.message === "string" ? errorMessage.message : "Daemon update required";
|
|
2513
|
+
console.error(`[EpisodaClient] ${errorMessage.code}: ${errorText}`);
|
|
2514
|
+
}
|
|
2495
2515
|
}
|
|
2496
2516
|
const handlers = this.eventHandlers.get(message.type) || [];
|
|
2497
2517
|
handlers.forEach((handler) => {
|
|
@@ -2621,8 +2641,10 @@ var require_websocket_client = __commonJS({
|
|
|
2621
2641
|
osArch: this.osArch,
|
|
2622
2642
|
daemonPid: this.daemonPid,
|
|
2623
2643
|
cliVersion: this.cliVersion,
|
|
2644
|
+
protocolVersion: this.protocolVersion,
|
|
2624
2645
|
cliPackageName: this.cliPackageName,
|
|
2625
2646
|
capabilities: this.capabilities,
|
|
2647
|
+
ptyProviderVersions: this.ptyProviderVersions,
|
|
2626
2648
|
environment: this.environment,
|
|
2627
2649
|
containerId: this.containerId
|
|
2628
2650
|
}).then(() => {
|
|
@@ -3052,7 +3074,7 @@ var require_package = __commonJS({
|
|
|
3052
3074
|
"package.json"(exports2, module2) {
|
|
3053
3075
|
module2.exports = {
|
|
3054
3076
|
name: "@episoda/cli",
|
|
3055
|
-
version: "0.2.
|
|
3077
|
+
version: "0.2.222",
|
|
3056
3078
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
3057
3079
|
main: "dist/index.js",
|
|
3058
3080
|
types: "dist/index.d.ts",
|
|
@@ -13262,7 +13284,8 @@ async function handlePtySpawn(payload, client) {
|
|
|
13262
13284
|
moduleUid,
|
|
13263
13285
|
agent_run_id,
|
|
13264
13286
|
code: -1,
|
|
13265
|
-
durationMs: 0
|
|
13287
|
+
durationMs: 0,
|
|
13288
|
+
sessionGeneration: client.getStatus().sessionGeneration
|
|
13266
13289
|
});
|
|
13267
13290
|
return {
|
|
13268
13291
|
success: false,
|
|
@@ -13328,7 +13351,8 @@ async function handlePtySpawn(payload, client) {
|
|
|
13328
13351
|
moduleUid,
|
|
13329
13352
|
agent_run_id,
|
|
13330
13353
|
code: exitCode,
|
|
13331
|
-
durationMs
|
|
13354
|
+
durationMs,
|
|
13355
|
+
sessionGeneration: client.getStatus().sessionGeneration
|
|
13332
13356
|
}).catch((err) => {
|
|
13333
13357
|
console.error(`[PTY] Failed to send pty_exit for ${agent_run_id}:`, err.message);
|
|
13334
13358
|
});
|
|
@@ -15496,7 +15520,8 @@ var ProjectMessageRouter = class {
|
|
|
15496
15520
|
startupConfirmedAt: result.startupConfirmedAt,
|
|
15497
15521
|
modelUsed: result.modelUsed,
|
|
15498
15522
|
launchConfig: result.launchConfig,
|
|
15499
|
-
authPath: result.authPath
|
|
15523
|
+
authPath: result.authPath,
|
|
15524
|
+
sessionGeneration: client.getStatus().sessionGeneration
|
|
15500
15525
|
});
|
|
15501
15526
|
}
|
|
15502
15527
|
});
|
|
@@ -15524,7 +15549,8 @@ var ProjectMessageRouter = class {
|
|
|
15524
15549
|
requestId: message.id,
|
|
15525
15550
|
agent_run_id: payload.agent_run_id,
|
|
15526
15551
|
success: result.success,
|
|
15527
|
-
error: result.error
|
|
15552
|
+
error: result.error,
|
|
15553
|
+
sessionGeneration: client.getStatus().sessionGeneration
|
|
15528
15554
|
});
|
|
15529
15555
|
if (!result.success) {
|
|
15530
15556
|
console.warn(`[Daemon] EP1476: pty_stdin failed for run ${payload.agent_run_id}: ${result.error}`);
|
|
@@ -15815,6 +15841,69 @@ function collectUnexpectedWorktrees(params) {
|
|
|
15815
15841
|
|
|
15816
15842
|
// src/daemon/daemon-process.ts
|
|
15817
15843
|
var packageJson = require_package();
|
|
15844
|
+
var DAEMON_PROTOCOL_VERSION = 2;
|
|
15845
|
+
function resolveBundledBinaryCandidates(binaryName) {
|
|
15846
|
+
return [
|
|
15847
|
+
path37.join(__dirname, "..", "..", "node_modules", ".bin", binaryName),
|
|
15848
|
+
path37.join(__dirname, "..", "..", "..", "..", "node_modules", ".bin", binaryName),
|
|
15849
|
+
path37.join(__dirname, "..", "..", "..", "..", "..", "node_modules", ".bin", binaryName)
|
|
15850
|
+
];
|
|
15851
|
+
}
|
|
15852
|
+
function tryReadBinaryVersionAsync(binaryPath, versionPattern) {
|
|
15853
|
+
return new Promise((resolve10) => {
|
|
15854
|
+
(0, import_child_process18.execFile)(
|
|
15855
|
+
binaryPath,
|
|
15856
|
+
["--version"],
|
|
15857
|
+
{
|
|
15858
|
+
encoding: "utf-8",
|
|
15859
|
+
timeout: 5e3,
|
|
15860
|
+
windowsHide: true
|
|
15861
|
+
},
|
|
15862
|
+
(error, stdout) => {
|
|
15863
|
+
if (error) {
|
|
15864
|
+
resolve10(void 0);
|
|
15865
|
+
return;
|
|
15866
|
+
}
|
|
15867
|
+
const output = String(stdout ?? "").trim();
|
|
15868
|
+
const match = output.match(versionPattern);
|
|
15869
|
+
resolve10(match?.[1]);
|
|
15870
|
+
}
|
|
15871
|
+
);
|
|
15872
|
+
});
|
|
15873
|
+
}
|
|
15874
|
+
async function detectPtyProviderVersions() {
|
|
15875
|
+
const providers = [
|
|
15876
|
+
{ key: "claude", binaryName: "claude", versionPattern: /(\d+\.\d+(?:\.\d+)?)/ },
|
|
15877
|
+
{ key: "codex", binaryName: "codex", versionPattern: /(\d+\.\d+(?:\.\d+)?)/i }
|
|
15878
|
+
];
|
|
15879
|
+
const versions = {};
|
|
15880
|
+
for (const provider of providers) {
|
|
15881
|
+
const bundledCandidates = resolveBundledBinaryCandidates(provider.binaryName);
|
|
15882
|
+
const candidates = bundledCandidates.filter((candidate, index, arr) => fs35.existsSync(candidate) && arr.indexOf(candidate) === index);
|
|
15883
|
+
for (const candidate of candidates) {
|
|
15884
|
+
const version = await tryReadBinaryVersionAsync(candidate, provider.versionPattern);
|
|
15885
|
+
if (version) {
|
|
15886
|
+
versions[provider.key] = version;
|
|
15887
|
+
break;
|
|
15888
|
+
}
|
|
15889
|
+
}
|
|
15890
|
+
if (versions[provider.key]) {
|
|
15891
|
+
continue;
|
|
15892
|
+
}
|
|
15893
|
+
const globalVersion = await tryReadBinaryVersionAsync(provider.binaryName, provider.versionPattern);
|
|
15894
|
+
if (globalVersion) {
|
|
15895
|
+
versions[provider.key] = globalVersion;
|
|
15896
|
+
}
|
|
15897
|
+
}
|
|
15898
|
+
return versions;
|
|
15899
|
+
}
|
|
15900
|
+
var detectedPtyProviderVersionsPromise = null;
|
|
15901
|
+
function getDetectedPtyProviderVersions() {
|
|
15902
|
+
if (!detectedPtyProviderVersionsPromise) {
|
|
15903
|
+
detectedPtyProviderVersionsPromise = detectPtyProviderVersions().catch(() => ({}));
|
|
15904
|
+
}
|
|
15905
|
+
return detectedPtyProviderVersionsPromise;
|
|
15906
|
+
}
|
|
15818
15907
|
var Daemon = class _Daemon {
|
|
15819
15908
|
constructor() {
|
|
15820
15909
|
this.machineId = "";
|
|
@@ -16787,17 +16876,21 @@ var Daemon = class _Daemon {
|
|
|
16787
16876
|
const environment = modeConfig.mode;
|
|
16788
16877
|
const containerId = process.env.EPISODA_CONTAINER_ID;
|
|
16789
16878
|
const capabilities = ["worktree_create_v1", "pty_v1"];
|
|
16790
|
-
|
|
16879
|
+
const ptyProviderVersions = await getDetectedPtyProviderVersions();
|
|
16880
|
+
const deviceInfo = {
|
|
16791
16881
|
hostname: os16.hostname(),
|
|
16792
16882
|
osPlatform: os16.platform(),
|
|
16793
16883
|
osArch: os16.arch(),
|
|
16794
16884
|
daemonPid,
|
|
16795
16885
|
cliVersion: this.cliRuntimeVersion,
|
|
16886
|
+
protocolVersion: DAEMON_PROTOCOL_VERSION,
|
|
16796
16887
|
cliPackageName: packageJson.name,
|
|
16797
16888
|
capabilities,
|
|
16889
|
+
ptyProviderVersions,
|
|
16798
16890
|
environment,
|
|
16799
16891
|
containerId
|
|
16800
|
-
}
|
|
16892
|
+
};
|
|
16893
|
+
await client.connect(wsEndpoint.wsUrl, config.access_token, this.machineId, deviceInfo);
|
|
16801
16894
|
console.log(`[Daemon] Successfully connected to project ${projectId}`);
|
|
16802
16895
|
this.connectionManager.setState(projectPath, "authenticating");
|
|
16803
16896
|
await this.connectionManager.waitForAuthentication(client, 3e4);
|