episoda 0.2.131 → 0.2.132

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.
@@ -2823,7 +2823,7 @@ var require_package = __commonJS({
2823
2823
  "package.json"(exports2, module2) {
2824
2824
  module2.exports = {
2825
2825
  name: "episoda",
2826
- version: "0.2.130",
2826
+ version: "0.2.131",
2827
2827
  description: "CLI tool for Episoda local development workflow orchestration",
2828
2828
  main: "dist/index.js",
2829
2829
  types: "dist/index.d.ts",
@@ -8359,6 +8359,35 @@ function generateCodexConfig(credentials, projectPath) {
8359
8359
  }
8360
8360
  return files;
8361
8361
  }
8362
+ function escapeTomlString(value) {
8363
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
8364
+ }
8365
+ function generateCodexMcpConfigToml(servers, projectPath) {
8366
+ const lines = [];
8367
+ if (projectPath) {
8368
+ const escapedPath = escapeTomlString(projectPath);
8369
+ lines.push(`[projects."${escapedPath}"]`);
8370
+ lines.push('trust_level = "trusted"');
8371
+ lines.push("");
8372
+ }
8373
+ for (const server of servers) {
8374
+ lines.push(`[mcp_servers.${server.name}]`);
8375
+ lines.push(`command = "${escapeTomlString(server.command)}"`);
8376
+ if (server.args && server.args.length > 0) {
8377
+ const argsStr = server.args.map((arg) => `"${escapeTomlString(arg)}"`).join(", ");
8378
+ lines.push(`args = [${argsStr}]`);
8379
+ }
8380
+ if (server.env && Object.keys(server.env).length > 0) {
8381
+ lines.push("");
8382
+ lines.push(`[mcp_servers.${server.name}.env]`);
8383
+ for (const [key, value] of Object.entries(server.env)) {
8384
+ lines.push(`${key} = "${escapeTomlString(value)}"`);
8385
+ }
8386
+ }
8387
+ lines.push("");
8388
+ }
8389
+ return lines.join("\n");
8390
+ }
8362
8391
 
8363
8392
  // src/agent/agent-manager.ts
8364
8393
  var import_child_process12 = require("child_process");
@@ -9282,18 +9311,83 @@ If changes are needed, explain what needs to be done.`;
9282
9311
  idToken: session.credentials.idToken,
9283
9312
  accountId: session.credentials.accountId,
9284
9313
  expiresAt: session.credentials.expiresAt
9285
- }, session.projectPath);
9314
+ });
9286
9315
  const authJsonPath = path20.join(sessionCodexDir, "auth.json");
9287
9316
  fs19.writeFileSync(authJsonPath, codexConfig["auth.json"], { mode: 384 });
9288
9317
  console.log(`[AgentManager] EP1260: Wrote Codex auth.json to ${authJsonPath}`);
9289
- if (codexConfig["config.toml"]) {
9290
- const configTomlPath = path20.join(sessionCodexDir, "config.toml");
9291
- fs19.writeFileSync(configTomlPath, codexConfig["config.toml"], { mode: 420 });
9292
- console.log(`[AgentManager] EP1260: Wrote Codex config.toml to ${configTomlPath}`);
9293
- }
9294
9318
  } else if (useApiKey) {
9295
9319
  console.log("[AgentManager] EP1133: Using Codex with API key (OPENAI_API_KEY)");
9296
9320
  }
9321
+ const mcpServersToRegister = this.getMcpServersForSession(session);
9322
+ if (mcpServersToRegister.length > 0) {
9323
+ const sessionToken = process.env.EPISODA_ACCESS_TOKEN || process.env.EPISODA_SESSION_TOKEN || "";
9324
+ const devEnvId = process.env.EPISODA_CONTAINER_ID || process.env.EPISODA_MACHINE_ID || "";
9325
+ const essentialEnvKeys = [
9326
+ "PATH",
9327
+ "HOME",
9328
+ "USER",
9329
+ "SHELL",
9330
+ "NODE_PATH",
9331
+ "NODE_OPTIONS",
9332
+ "NPM_CONFIG_PREFIX",
9333
+ "LANG",
9334
+ "LC_ALL",
9335
+ "LC_CTYPE",
9336
+ "TERM",
9337
+ "COLORTERM",
9338
+ "XDG_CONFIG_HOME",
9339
+ "XDG_DATA_HOME",
9340
+ "XDG_CACHE_HOME",
9341
+ "TMPDIR",
9342
+ "TMP",
9343
+ "TEMP"
9344
+ ];
9345
+ const baseEnv = {};
9346
+ for (const key of essentialEnvKeys) {
9347
+ const value = process.env[key];
9348
+ if (value !== void 0) {
9349
+ baseEnv[key] = value;
9350
+ }
9351
+ }
9352
+ const codexMcpServers = mcpServersToRegister.map((server) => {
9353
+ const parts = server.command.split(" ");
9354
+ const command = parts[0];
9355
+ const args2 = parts.slice(1);
9356
+ let env;
9357
+ if (server.name === "github") {
9358
+ env = {
9359
+ ...baseEnv,
9360
+ GITHUB_PERSONAL_ACCESS_TOKEN: session.credentials.githubToken || ""
9361
+ };
9362
+ } else {
9363
+ env = {
9364
+ ...baseEnv,
9365
+ EPISODA_API_URL: process.env.EPISODA_API_URL || "https://episoda.dev",
9366
+ EPISODA_SESSION_TOKEN: sessionToken,
9367
+ MODULE_UID: session.moduleUid || "",
9368
+ EPISODA_PROJECT_ID: session.projectId || "",
9369
+ DEV_ENVIRONMENT_ID: devEnvId
9370
+ };
9371
+ }
9372
+ return {
9373
+ name: server.name,
9374
+ command,
9375
+ args: args2.length > 0 ? args2 : void 0,
9376
+ env
9377
+ };
9378
+ });
9379
+ const configTomlContent = generateCodexMcpConfigToml(codexMcpServers, session.projectPath);
9380
+ const configTomlPath = path20.join(sessionCodexDir, "config.toml");
9381
+ fs19.writeFileSync(configTomlPath, configTomlContent, { mode: 384 });
9382
+ console.log(`[AgentManager] EP1278: Wrote Codex config.toml with ${codexMcpServers.length} MCP server(s): ${codexMcpServers.map((s) => s.name).join(", ")}`);
9383
+ } else {
9384
+ const configTomlContent = generateCodexMcpConfigToml([], session.projectPath);
9385
+ if (configTomlContent.trim()) {
9386
+ const configTomlPath = path20.join(sessionCodexDir, "config.toml");
9387
+ fs19.writeFileSync(configTomlPath, configTomlContent, { mode: 420 });
9388
+ console.log(`[AgentManager] EP1260: Wrote Codex config.toml (project trust only)`);
9389
+ }
9390
+ }
9297
9391
  });
9298
9392
  } else {
9299
9393
  await this.withConfigLock(async () => {