@episoda/cli 0.2.195 → 0.2.197
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.
|
@@ -3046,7 +3046,7 @@ var require_package = __commonJS({
|
|
|
3046
3046
|
"package.json"(exports2, module2) {
|
|
3047
3047
|
module2.exports = {
|
|
3048
3048
|
name: "@episoda/cli",
|
|
3049
|
-
version: "0.2.
|
|
3049
|
+
version: "0.2.197",
|
|
3050
3050
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
3051
3051
|
main: "dist/index.js",
|
|
3052
3052
|
types: "dist/index.d.ts",
|
|
@@ -12891,12 +12891,13 @@ async function handlePtySpawn(payload, client) {
|
|
|
12891
12891
|
const { moduleUid, agent_run_id, command, args, stdin, env, cwd, cols = 220, rows = 50 } = payload;
|
|
12892
12892
|
if (sessions.has(agent_run_id)) {
|
|
12893
12893
|
console.warn(`[PTY] Session already exists for agent_run_id ${agent_run_id}, ignoring spawn`);
|
|
12894
|
-
return;
|
|
12894
|
+
return { success: false, error: "PTY session already exists for this agent run." };
|
|
12895
12895
|
}
|
|
12896
12896
|
console.log(`[PTY] Spawning PTY for ${moduleUid} / ${agent_run_id}: ${command} ${args.join(" ")}`);
|
|
12897
|
-
|
|
12897
|
+
let bootstrap = null;
|
|
12898
12898
|
let proc;
|
|
12899
12899
|
try {
|
|
12900
|
+
bootstrap = createCredentialBootstrap(payload, agent_run_id);
|
|
12900
12901
|
proc = pty.spawn(command, args, {
|
|
12901
12902
|
name: "xterm-256color",
|
|
12902
12903
|
cols,
|
|
@@ -12909,7 +12910,9 @@ async function handlePtySpawn(payload, client) {
|
|
|
12909
12910
|
}
|
|
12910
12911
|
});
|
|
12911
12912
|
} catch (err) {
|
|
12912
|
-
|
|
12913
|
+
if (bootstrap) {
|
|
12914
|
+
cleanupCredentialDirs(bootstrap.cleanupDirs);
|
|
12915
|
+
}
|
|
12913
12916
|
console.error(`[PTY] Failed to spawn PTY for ${agent_run_id}:`, err);
|
|
12914
12917
|
await client.send({
|
|
12915
12918
|
type: "pty_exit",
|
|
@@ -12918,7 +12921,10 @@ async function handlePtySpawn(payload, client) {
|
|
|
12918
12921
|
code: -1,
|
|
12919
12922
|
durationMs: 0
|
|
12920
12923
|
});
|
|
12921
|
-
return
|
|
12924
|
+
return {
|
|
12925
|
+
success: false,
|
|
12926
|
+
error: err?.message || `Failed to spawn PTY command '${command}'`
|
|
12927
|
+
};
|
|
12922
12928
|
}
|
|
12923
12929
|
const session = {
|
|
12924
12930
|
pty: proc,
|
|
@@ -12927,7 +12933,8 @@ async function handlePtySpawn(payload, client) {
|
|
|
12927
12933
|
startedAt: Date.now(),
|
|
12928
12934
|
lastOutputAt: Date.now(),
|
|
12929
12935
|
watchdogTimer: null,
|
|
12930
|
-
credentialDirs: bootstrap.cleanupDirs
|
|
12936
|
+
credentialDirs: bootstrap.cleanupDirs,
|
|
12937
|
+
credentialAuthPath: bootstrap.authPath
|
|
12931
12938
|
};
|
|
12932
12939
|
sessions.set(agent_run_id, session);
|
|
12933
12940
|
const resetWatchdog = () => {
|
|
@@ -12961,7 +12968,6 @@ async function handlePtySpawn(payload, client) {
|
|
|
12961
12968
|
if (session.watchdogTimer) clearTimeout(session.watchdogTimer);
|
|
12962
12969
|
console.log(`[PTY] Process exited for ${agent_run_id} with code ${exitCode} after ${durationMs}ms`);
|
|
12963
12970
|
sessions.delete(agent_run_id);
|
|
12964
|
-
cleanupCredentialDirs(session.credentialDirs);
|
|
12965
12971
|
client.send({
|
|
12966
12972
|
type: "pty_exit",
|
|
12967
12973
|
moduleUid,
|
|
@@ -12971,7 +12977,9 @@ async function handlePtySpawn(payload, client) {
|
|
|
12971
12977
|
}).catch((err) => {
|
|
12972
12978
|
console.error(`[PTY] Failed to send pty_exit for ${agent_run_id}:`, err.message);
|
|
12973
12979
|
});
|
|
12980
|
+
syncCredentialUpdateAfterExit(session, agent_run_id, client);
|
|
12974
12981
|
});
|
|
12982
|
+
return { success: true };
|
|
12975
12983
|
}
|
|
12976
12984
|
function handlePtyResize(payload) {
|
|
12977
12985
|
const { agent_run_id, cols, rows } = payload;
|
|
@@ -12995,11 +13003,13 @@ function handlePtyKill(payload) {
|
|
|
12995
13003
|
}
|
|
12996
13004
|
try {
|
|
12997
13005
|
session.pty.kill();
|
|
13006
|
+
console.log(`[PTY] Kill signal sent for session ${agent_run_id}`);
|
|
12998
13007
|
} catch {
|
|
13008
|
+
if (session.watchdogTimer) clearTimeout(session.watchdogTimer);
|
|
13009
|
+
cleanupCredentialDirs(session.credentialDirs);
|
|
13010
|
+
sessions.delete(agent_run_id);
|
|
13011
|
+
console.warn(`[PTY] Kill failed for ${agent_run_id}; performed fallback cleanup`);
|
|
12999
13012
|
}
|
|
13000
|
-
cleanupCredentialDirs(session.credentialDirs);
|
|
13001
|
-
sessions.delete(agent_run_id);
|
|
13002
|
-
console.log(`[PTY] Killed session ${agent_run_id}`);
|
|
13003
13013
|
}
|
|
13004
13014
|
function createCredentialBootstrap(payload, agentRunId) {
|
|
13005
13015
|
const bootstrap = payload.credential_bootstrap;
|
|
@@ -13040,9 +13050,65 @@ function createCredentialBootstrap(payload, agentRunId) {
|
|
|
13040
13050
|
fs30.writeFileSync(authPath, JSON.stringify(authPayload, null, 2), { mode: 384 });
|
|
13041
13051
|
return {
|
|
13042
13052
|
env: { CODEX_HOME: codexHome },
|
|
13043
|
-
cleanupDirs
|
|
13053
|
+
cleanupDirs,
|
|
13054
|
+
authPath
|
|
13044
13055
|
};
|
|
13045
13056
|
}
|
|
13057
|
+
function syncCredentialUpdateAfterExit(session, agent_run_id, client) {
|
|
13058
|
+
const authPath = session.credentialAuthPath;
|
|
13059
|
+
if (!authPath) {
|
|
13060
|
+
cleanupCredentialDirs(session.credentialDirs);
|
|
13061
|
+
return;
|
|
13062
|
+
}
|
|
13063
|
+
void fs30.promises.readFile(authPath, "utf8").then((raw) => {
|
|
13064
|
+
const tokens = extractCredentialTokens(raw);
|
|
13065
|
+
if (!tokens.access_token) {
|
|
13066
|
+
console.warn(`[PTY] EP1472: No access_token in auth.json for ${agent_run_id}, skipping credential update`);
|
|
13067
|
+
return;
|
|
13068
|
+
}
|
|
13069
|
+
return client.send({
|
|
13070
|
+
type: "pty_credential_update",
|
|
13071
|
+
agent_run_id,
|
|
13072
|
+
provider: "codex",
|
|
13073
|
+
access_token: tokens.access_token,
|
|
13074
|
+
refresh_token: tokens.refresh_token,
|
|
13075
|
+
id_token: tokens.id_token,
|
|
13076
|
+
account_id: tokens.account_id
|
|
13077
|
+
}).then(() => {
|
|
13078
|
+
console.log(`[PTY] EP1472: pty_credential_update sent for ${agent_run_id}`);
|
|
13079
|
+
}).catch((err) => {
|
|
13080
|
+
console.warn(`[PTY] Failed to send pty_credential_update for ${agent_run_id}:`, err.message);
|
|
13081
|
+
});
|
|
13082
|
+
}).catch((err) => {
|
|
13083
|
+
console.warn(`[PTY] EP1472: Failed to read auth.json for ${agent_run_id}:`, getErrorMessage(err));
|
|
13084
|
+
}).finally(() => {
|
|
13085
|
+
cleanupCredentialDirs(session.credentialDirs);
|
|
13086
|
+
});
|
|
13087
|
+
}
|
|
13088
|
+
function extractCredentialTokens(raw) {
|
|
13089
|
+
const parsed = JSON.parse(raw);
|
|
13090
|
+
const authRecord = asRecord(parsed);
|
|
13091
|
+
if (!authRecord) return {};
|
|
13092
|
+
const nestedTokens = asRecord(authRecord.tokens);
|
|
13093
|
+
const source = nestedTokens ?? authRecord;
|
|
13094
|
+
return {
|
|
13095
|
+
access_token: pickString(source, "access_token"),
|
|
13096
|
+
refresh_token: pickString(source, "refresh_token"),
|
|
13097
|
+
id_token: pickString(source, "id_token"),
|
|
13098
|
+
account_id: pickString(source, "account_id")
|
|
13099
|
+
};
|
|
13100
|
+
}
|
|
13101
|
+
function asRecord(value) {
|
|
13102
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
13103
|
+
return value;
|
|
13104
|
+
}
|
|
13105
|
+
function pickString(record, key) {
|
|
13106
|
+
const value = record[key];
|
|
13107
|
+
return typeof value === "string" ? value : void 0;
|
|
13108
|
+
}
|
|
13109
|
+
function getErrorMessage(error) {
|
|
13110
|
+
return error instanceof Error ? error.message : String(error);
|
|
13111
|
+
}
|
|
13046
13112
|
function cleanupCredentialDirs(dirs) {
|
|
13047
13113
|
for (const dirPath of dirs) {
|
|
13048
13114
|
try {
|
|
@@ -15091,18 +15157,35 @@ var ProjectMessageRouter = class {
|
|
|
15091
15157
|
if (message.type === "pty_spawn") {
|
|
15092
15158
|
const payload = message.payload;
|
|
15093
15159
|
let resolvedPayload = payload;
|
|
15094
|
-
|
|
15095
|
-
|
|
15096
|
-
if (
|
|
15097
|
-
|
|
15098
|
-
|
|
15099
|
-
|
|
15100
|
-
|
|
15160
|
+
let result = { success: false, error: "PTY spawn failed" };
|
|
15161
|
+
try {
|
|
15162
|
+
if (!payload.cwd && payload.moduleUid) {
|
|
15163
|
+
const worktreeInfo = await getWorktreeInfoForModule(payload.moduleUid);
|
|
15164
|
+
if (worktreeInfo?.path) {
|
|
15165
|
+
resolvedPayload = {
|
|
15166
|
+
...payload,
|
|
15167
|
+
cwd: worktreeInfo.path
|
|
15168
|
+
};
|
|
15169
|
+
}
|
|
15101
15170
|
}
|
|
15171
|
+
console.log(`[Daemon] EP1441: Received pty_spawn for ${projectId}: ${payload.agent_run_id}`);
|
|
15172
|
+
client.updateActivity();
|
|
15173
|
+
result = await handlePtySpawn(resolvedPayload, client);
|
|
15174
|
+
} catch (error) {
|
|
15175
|
+
result = {
|
|
15176
|
+
success: false,
|
|
15177
|
+
error: error instanceof Error ? error.message : String(error)
|
|
15178
|
+
};
|
|
15179
|
+
console.error(`[Daemon] EP1471: PTY spawn failed for ${payload.agent_run_id}:`, error);
|
|
15102
15180
|
}
|
|
15103
|
-
|
|
15104
|
-
|
|
15105
|
-
|
|
15181
|
+
await client.send({
|
|
15182
|
+
type: "pty_spawn_ack",
|
|
15183
|
+
requestId: message.id,
|
|
15184
|
+
moduleUid: resolvedPayload.moduleUid,
|
|
15185
|
+
agent_run_id: resolvedPayload.agent_run_id,
|
|
15186
|
+
success: result.success,
|
|
15187
|
+
error: result.error
|
|
15188
|
+
});
|
|
15106
15189
|
}
|
|
15107
15190
|
});
|
|
15108
15191
|
client.on("pty_resize", (message) => {
|