@episoda/cli 0.2.213 → 0.2.214

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.
@@ -3051,7 +3051,7 @@ var require_package = __commonJS({
3051
3051
  "package.json"(exports2, module2) {
3052
3052
  module2.exports = {
3053
3053
  name: "@episoda/cli",
3054
- version: "0.2.213",
3054
+ version: "0.2.214",
3055
3055
  description: "CLI tool for Episoda local development workflow orchestration",
3056
3056
  main: "dist/index.js",
3057
3057
  types: "dist/index.d.ts",
@@ -4798,22 +4798,17 @@ async function ensureCodexBinary() {
4798
4798
  // src/agent/providers/codex-config.ts
4799
4799
  var DEFAULT_CODEX_MODEL = "gpt-5.4";
4800
4800
  function generateCodexAuthJson(credentials) {
4801
- if (!credentials.refreshToken) {
4802
- throw new Error(
4803
- "Codex refresh token is missing. Please re-authenticate with Codex in Settings > AI Providers."
4804
- );
4805
- }
4806
4801
  const tokens = {
4807
4802
  id_token: credentials.idToken || credentials.accessToken,
4808
4803
  // Fallback to access_token if no id_token
4809
4804
  access_token: credentials.accessToken,
4810
- refresh_token: credentials.refreshToken
4811
- // EP1139: Required field
4805
+ refresh_token: ""
4812
4806
  };
4813
4807
  if (credentials.accountId) {
4814
4808
  tokens.account_id = credentials.accountId;
4815
4809
  }
4816
4810
  const authData = {
4811
+ auth_mode: "chatgptAuthTokens",
4817
4812
  OPENAI_API_KEY: null,
4818
4813
  // This null is expected by Codex CLI
4819
4814
  tokens,
@@ -13068,7 +13063,6 @@ async function handlePtySpawn(payload, client) {
13068
13063
  lastOutputAt: Date.now(),
13069
13064
  watchdogTimer: null,
13070
13065
  credentialDirs: bootstrap.cleanupDirs,
13071
- credentialAuthPath: bootstrap.authPath,
13072
13066
  startup: createStartupState(payload)
13073
13067
  };
13074
13068
  sessions.set(agent_run_id, session);
@@ -13118,7 +13112,7 @@ async function handlePtySpawn(payload, client) {
13118
13112
  }).catch((err) => {
13119
13113
  console.error(`[PTY] Failed to send pty_exit for ${agent_run_id}:`, err.message);
13120
13114
  });
13121
- syncCredentialUpdateAfterExit(session, agent_run_id, client);
13115
+ cleanupCredentialDirs(session.credentialDirs);
13122
13116
  });
13123
13117
  if (session.startup) {
13124
13118
  armStartupTimeout(session, proc);
@@ -13191,9 +13185,6 @@ function createCredentialBootstrap(payload, agentRunId) {
13191
13185
  if (!bootstrap?.oauth?.access_token) {
13192
13186
  return { env: {}, cleanupDirs: [] };
13193
13187
  }
13194
- if (bootstrap.provider === "codex" && !bootstrap.oauth.refresh_token) {
13195
- throw new Error("Codex PTY spawn aborted: refresh_token is missing from credential bundle. Please reconnect Codex in Settings.");
13196
- }
13197
13188
  const baseDir = fs31.mkdtempSync(path31.join(os14.tmpdir(), `episoda-pty-${agentRunId}-`));
13198
13189
  const cleanupDirs = [baseDir];
13199
13190
  if (bootstrap.provider === "claude") {
@@ -13214,25 +13205,18 @@ function createCredentialBootstrap(payload, agentRunId) {
13214
13205
  }
13215
13206
  const codexHome = path31.join(baseDir, ".codex");
13216
13207
  fs31.mkdirSync(codexHome, { recursive: true });
13217
- const authPath = path31.join(codexHome, "auth.json");
13218
- const authPayload = {
13219
- auth_mode: "chatgpt",
13220
- OPENAI_API_KEY: null,
13221
- // EP1473: Codex CLI 0.104.0+ requires last_refresh during token/model bootstrap.
13222
- // Without it, Codex fails with "Token data is not available" before any work begins.
13223
- last_refresh: (/* @__PURE__ */ new Date()).toISOString(),
13224
- tokens: {
13225
- access_token: bootstrap.oauth.access_token,
13226
- refresh_token: bootstrap.oauth.refresh_token,
13227
- id_token: bootstrap.oauth.id_token,
13228
- account_id: bootstrap.oauth.account_id
13229
- }
13230
- };
13231
- fs31.writeFileSync(authPath, JSON.stringify(authPayload, null, 2), { mode: 384 });
13208
+ const configFiles = generateCodexConfig({
13209
+ accessToken: bootstrap.oauth.access_token,
13210
+ idToken: bootstrap.oauth.id_token,
13211
+ accountId: bootstrap.oauth.account_id
13212
+ }, payload.cwd);
13213
+ fs31.writeFileSync(path31.join(codexHome, "auth.json"), configFiles["auth.json"], { mode: 384 });
13214
+ if (configFiles["config.toml"]) {
13215
+ fs31.writeFileSync(path31.join(codexHome, "config.toml"), configFiles["config.toml"], { mode: 384 });
13216
+ }
13232
13217
  return {
13233
13218
  env: { CODEX_HOME: codexHome },
13234
- cleanupDirs,
13235
- authPath
13219
+ cleanupDirs
13236
13220
  };
13237
13221
  }
13238
13222
  function createStartupState(payload) {
@@ -13309,61 +13293,6 @@ function getCodexStartupReadyTimeoutMs() {
13309
13293
  const parsed = Number(process.env.EPISODA_CODEX_READY_TIMEOUT_MS || "8000");
13310
13294
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 8e3;
13311
13295
  }
13312
- function syncCredentialUpdateAfterExit(session, agent_run_id, client) {
13313
- const authPath = session.credentialAuthPath;
13314
- if (!authPath) {
13315
- cleanupCredentialDirs(session.credentialDirs);
13316
- return;
13317
- }
13318
- void fs31.promises.readFile(authPath, "utf8").then((raw) => {
13319
- const tokens = extractCredentialTokens(raw);
13320
- if (!tokens.access_token) {
13321
- console.warn(`[PTY] EP1472: No access_token in auth.json for ${agent_run_id}, skipping credential update`);
13322
- return;
13323
- }
13324
- return client.send({
13325
- type: "pty_credential_update",
13326
- agent_run_id,
13327
- provider: "codex",
13328
- access_token: tokens.access_token,
13329
- refresh_token: tokens.refresh_token,
13330
- id_token: tokens.id_token,
13331
- account_id: tokens.account_id
13332
- }).then(() => {
13333
- console.log(`[PTY] EP1472: pty_credential_update sent for ${agent_run_id}`);
13334
- }).catch((err) => {
13335
- console.warn(`[PTY] Failed to send pty_credential_update for ${agent_run_id}:`, err.message);
13336
- });
13337
- }).catch((err) => {
13338
- console.warn(`[PTY] EP1472: Failed to read auth.json for ${agent_run_id}:`, getErrorMessage(err));
13339
- }).finally(() => {
13340
- cleanupCredentialDirs(session.credentialDirs);
13341
- });
13342
- }
13343
- function extractCredentialTokens(raw) {
13344
- const parsed = JSON.parse(raw);
13345
- const authRecord = asRecord(parsed);
13346
- if (!authRecord) return {};
13347
- const nestedTokens = asRecord(authRecord.tokens);
13348
- const source = nestedTokens ?? authRecord;
13349
- return {
13350
- access_token: pickString(source, "access_token"),
13351
- refresh_token: pickString(source, "refresh_token"),
13352
- id_token: pickString(source, "id_token"),
13353
- account_id: pickString(source, "account_id")
13354
- };
13355
- }
13356
- function asRecord(value) {
13357
- if (!value || typeof value !== "object" || Array.isArray(value)) return null;
13358
- return value;
13359
- }
13360
- function pickString(record, key) {
13361
- const value = record[key];
13362
- return typeof value === "string" ? value : void 0;
13363
- }
13364
- function getErrorMessage(error) {
13365
- return error instanceof Error ? error.message : String(error);
13366
- }
13367
13296
  function cleanupCredentialDirs(dirs) {
13368
13297
  for (const dirPath of dirs) {
13369
13298
  try {