@episoda/cli 0.2.213 → 0.2.215

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,10 +3051,17 @@ 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.215",
3055
3055
  description: "CLI tool for Episoda local development workflow orchestration",
3056
3056
  main: "dist/index.js",
3057
3057
  types: "dist/index.d.ts",
3058
+ exports: {
3059
+ ".": {
3060
+ types: "./dist/index.d.ts",
3061
+ require: "./dist/index.js",
3062
+ default: "./dist/index.js"
3063
+ }
3064
+ },
3058
3065
  bin: {
3059
3066
  episoda: "dist/index.js"
3060
3067
  },
@@ -4798,22 +4805,17 @@ async function ensureCodexBinary() {
4798
4805
  // src/agent/providers/codex-config.ts
4799
4806
  var DEFAULT_CODEX_MODEL = "gpt-5.4";
4800
4807
  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
4808
  const tokens = {
4807
4809
  id_token: credentials.idToken || credentials.accessToken,
4808
4810
  // Fallback to access_token if no id_token
4809
4811
  access_token: credentials.accessToken,
4810
- refresh_token: credentials.refreshToken
4811
- // EP1139: Required field
4812
+ refresh_token: ""
4812
4813
  };
4813
4814
  if (credentials.accountId) {
4814
4815
  tokens.account_id = credentials.accountId;
4815
4816
  }
4816
4817
  const authData = {
4818
+ auth_mode: "chatgptAuthTokens",
4817
4819
  OPENAI_API_KEY: null,
4818
4820
  // This null is expected by Codex CLI
4819
4821
  tokens,
@@ -13068,7 +13070,6 @@ async function handlePtySpawn(payload, client) {
13068
13070
  lastOutputAt: Date.now(),
13069
13071
  watchdogTimer: null,
13070
13072
  credentialDirs: bootstrap.cleanupDirs,
13071
- credentialAuthPath: bootstrap.authPath,
13072
13073
  startup: createStartupState(payload)
13073
13074
  };
13074
13075
  sessions.set(agent_run_id, session);
@@ -13118,7 +13119,7 @@ async function handlePtySpawn(payload, client) {
13118
13119
  }).catch((err) => {
13119
13120
  console.error(`[PTY] Failed to send pty_exit for ${agent_run_id}:`, err.message);
13120
13121
  });
13121
- syncCredentialUpdateAfterExit(session, agent_run_id, client);
13122
+ cleanupCredentialDirs(session.credentialDirs);
13122
13123
  });
13123
13124
  if (session.startup) {
13124
13125
  armStartupTimeout(session, proc);
@@ -13191,9 +13192,6 @@ function createCredentialBootstrap(payload, agentRunId) {
13191
13192
  if (!bootstrap?.oauth?.access_token) {
13192
13193
  return { env: {}, cleanupDirs: [] };
13193
13194
  }
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
13195
  const baseDir = fs31.mkdtempSync(path31.join(os14.tmpdir(), `episoda-pty-${agentRunId}-`));
13198
13196
  const cleanupDirs = [baseDir];
13199
13197
  if (bootstrap.provider === "claude") {
@@ -13214,25 +13212,18 @@ function createCredentialBootstrap(payload, agentRunId) {
13214
13212
  }
13215
13213
  const codexHome = path31.join(baseDir, ".codex");
13216
13214
  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 });
13215
+ const configFiles = generateCodexConfig({
13216
+ accessToken: bootstrap.oauth.access_token,
13217
+ idToken: bootstrap.oauth.id_token,
13218
+ accountId: bootstrap.oauth.account_id
13219
+ }, payload.cwd);
13220
+ fs31.writeFileSync(path31.join(codexHome, "auth.json"), configFiles["auth.json"], { mode: 384 });
13221
+ if (configFiles["config.toml"]) {
13222
+ fs31.writeFileSync(path31.join(codexHome, "config.toml"), configFiles["config.toml"], { mode: 384 });
13223
+ }
13232
13224
  return {
13233
13225
  env: { CODEX_HOME: codexHome },
13234
- cleanupDirs,
13235
- authPath
13226
+ cleanupDirs
13236
13227
  };
13237
13228
  }
13238
13229
  function createStartupState(payload) {
@@ -13309,61 +13300,6 @@ function getCodexStartupReadyTimeoutMs() {
13309
13300
  const parsed = Number(process.env.EPISODA_CODEX_READY_TIMEOUT_MS || "8000");
13310
13301
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 8e3;
13311
13302
  }
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
13303
  function cleanupCredentialDirs(dirs) {
13368
13304
  for (const dirPath of dirs) {
13369
13305
  try {