episoda 0.2.119 → 0.2.121

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.
@@ -2815,7 +2815,7 @@ var require_package = __commonJS({
2815
2815
  "package.json"(exports2, module2) {
2816
2816
  module2.exports = {
2817
2817
  name: "episoda",
2818
- version: "0.2.118",
2818
+ version: "0.2.120",
2819
2819
  description: "CLI tool for Episoda local development workflow orchestration",
2820
2820
  main: "dist/index.js",
2821
2821
  types: "dist/index.d.ts",
@@ -8279,8 +8279,16 @@ function generateSettings(options = {}) {
8279
8279
  "Glob",
8280
8280
  "Grep",
8281
8281
  "WebFetch",
8282
+ // EP1251: Allow all MCP tools (Episoda + GitHub)
8283
+ // These correspond to MCP servers registered via --mcp-config
8284
+ "mcp__workflow",
8285
+ // Episoda workflow MCP (tasks, modules, knowledge)
8286
+ "mcp__git",
8287
+ // Episoda git MCP (git operations via API)
8288
+ "mcp__dev",
8289
+ // Episoda dev MCP (file/exec operations)
8282
8290
  "mcp__github"
8283
- // EP1146: Allow GitHub MCP tools
8291
+ // GitHub MCP (PRs, issues, etc.)
8284
8292
  ],
8285
8293
  deny: [],
8286
8294
  ask: [],
@@ -8288,19 +8296,6 @@ function generateSettings(options = {}) {
8288
8296
  },
8289
8297
  alwaysThinkingEnabled: true
8290
8298
  };
8291
- if (options.githubToken) {
8292
- const mcpEnv = {
8293
- GITHUB_PERSONAL_ACCESS_TOKEN: options.githubToken
8294
- };
8295
- settings.mcpServers = {
8296
- github: {
8297
- command: "npx",
8298
- args: ["-y", "@modelcontextprotocol/server-github"],
8299
- env: mcpEnv
8300
- }
8301
- };
8302
- console.log("[ClaudeConfig] EP1146: GitHub MCP server configured");
8303
- }
8304
8299
  return settings;
8305
8300
  }
8306
8301
  function generateStableId() {
@@ -8601,52 +8596,64 @@ var AgentManager = class {
8601
8596
  }
8602
8597
  /**
8603
8598
  * EP1233: Get list of MCP servers to register for a session
8599
+ * EP1251: Added GitHub MCP for consolidated MCP configuration
8604
8600
  *
8605
8601
  * Returns MCP server configurations based on:
8606
8602
  * - mcpMode: 'full' includes dev-server, 'standard' does not
8607
8603
  * - DEV_ENVIRONMENT_ID: Required for git-server and dev-server
8604
+ * - githubToken: Required for GitHub MCP
8608
8605
  *
8609
8606
  * MCP servers provide:
8610
8607
  * - workflow-server: Task/module/knowledge operations
8611
8608
  * - git-server: Git operations via API (requires DEV_ENVIRONMENT_ID)
8612
8609
  * - dev-server: File/exec operations via API (requires DEV_ENVIRONMENT_ID, only in 'full' mode)
8610
+ * - github: GitHub operations (PRs, issues, etc.) via @modelcontextprotocol/server-github
8613
8611
  */
8614
8612
  getMcpServersForSession(session) {
8615
8613
  const servers = [];
8616
8614
  const mcpDir = this.getMcpServerDir();
8617
8615
  if (!mcpDir) {
8618
- console.warn("[AgentManager] EP1233: MCP server directory not found, skipping MCP registration");
8619
- return servers;
8620
- }
8621
- const workflowServerPath = path20.join(mcpDir, "workflow-server.ts");
8622
- const gitServerPath = path20.join(mcpDir, "git-server.ts");
8623
- const devServerPath = path20.join(mcpDir, "dev-server.ts");
8624
- const hasDevEnvId = !!process.env.DEV_ENVIRONMENT_ID || !!process.env.EPISODA_CONTAINER_ID;
8625
- if (fs19.existsSync(workflowServerPath)) {
8626
- servers.push({
8627
- name: "workflow",
8628
- command: `tsx ${workflowServerPath}`
8629
- });
8616
+ console.warn("[AgentManager] EP1233: MCP server directory not found, skipping Episoda MCP registration");
8630
8617
  } else {
8631
- console.warn(`[AgentManager] EP1233: workflow-server.ts not found at ${workflowServerPath}`);
8632
- }
8633
- if (hasDevEnvId && fs19.existsSync(gitServerPath)) {
8634
- servers.push({
8635
- name: "git",
8636
- command: `tsx ${gitServerPath}`
8637
- });
8638
- } else if (!hasDevEnvId) {
8639
- console.log("[AgentManager] EP1233: git-server not registered (DEV_ENVIRONMENT_ID not set)");
8618
+ const workflowServerPath = path20.join(mcpDir, "workflow-server.ts");
8619
+ const gitServerPath = path20.join(mcpDir, "git-server.ts");
8620
+ const devServerPath = path20.join(mcpDir, "dev-server.ts");
8621
+ const hasDevEnvId = !!process.env.DEV_ENVIRONMENT_ID || !!process.env.EPISODA_CONTAINER_ID;
8622
+ if (fs19.existsSync(workflowServerPath)) {
8623
+ servers.push({
8624
+ name: "workflow",
8625
+ command: `tsx ${workflowServerPath}`
8626
+ });
8627
+ } else {
8628
+ console.warn(`[AgentManager] EP1233: workflow-server.ts not found at ${workflowServerPath}`);
8629
+ }
8630
+ if (hasDevEnvId && fs19.existsSync(gitServerPath)) {
8631
+ servers.push({
8632
+ name: "git",
8633
+ command: `tsx ${gitServerPath}`
8634
+ });
8635
+ } else if (!hasDevEnvId) {
8636
+ console.log("[AgentManager] EP1233: git-server not registered (DEV_ENVIRONMENT_ID not set)");
8637
+ }
8638
+ if (session.mcpMode === "full" && hasDevEnvId && fs19.existsSync(devServerPath)) {
8639
+ servers.push({
8640
+ name: "dev",
8641
+ command: `tsx ${devServerPath}`
8642
+ });
8643
+ } else if (session.mcpMode !== "full") {
8644
+ console.log(`[AgentManager] EP1233: dev-server not registered (mcpMode=${session.mcpMode})`);
8645
+ }
8640
8646
  }
8641
- if (session.mcpMode === "full" && hasDevEnvId && fs19.existsSync(devServerPath)) {
8647
+ if (session.credentials.githubToken) {
8642
8648
  servers.push({
8643
- name: "dev",
8644
- command: `tsx ${devServerPath}`
8649
+ name: "github",
8650
+ command: "npx -y @modelcontextprotocol/server-github"
8645
8651
  });
8646
- } else if (session.mcpMode !== "full") {
8647
- console.log(`[AgentManager] EP1233: dev-server not registered (mcpMode=${session.mcpMode})`);
8652
+ console.log("[AgentManager] EP1251: GitHub MCP server registered");
8653
+ } else {
8654
+ console.log("[AgentManager] EP1251: GitHub MCP not registered (no githubToken in credentials)");
8648
8655
  }
8649
- console.log(`[AgentManager] EP1233: MCP servers to register: ${servers.map((s) => s.name).join(", ") || "none"}`);
8656
+ console.log(`[AgentManager] EP1251: MCP servers to register: ${servers.map((s) => s.name).join(", ") || "none"}`);
8650
8657
  return servers;
8651
8658
  }
8652
8659
  /**
@@ -8801,9 +8808,10 @@ var AgentManager = class {
8801
8808
  *
8802
8809
  * Spawns a new agent CLI process for each message.
8803
8810
  * EP1133: Supports both Claude Code and Codex CLI with provider-specific handling.
8811
+ * EP1251: Supports credentials refresh for GitHub token on resume.
8804
8812
  */
8805
8813
  async sendMessage(options) {
8806
- const { sessionId, message, isFirstMessage, canWrite, readOnlyReason, agentSessionId, claudeSessionId, onChunk, onToolUse, onComplete, onError } = options;
8814
+ const { sessionId, message, isFirstMessage, canWrite, readOnlyReason, agentSessionId, claudeSessionId, credentials, onChunk, onToolUse, onComplete, onError } = options;
8807
8815
  const session = this.sessions.get(sessionId);
8808
8816
  if (!session) {
8809
8817
  return { success: false, error: "Session not found" };
@@ -8814,6 +8822,11 @@ var AgentManager = class {
8814
8822
  session.canWrite = canWrite;
8815
8823
  session.readOnlyReason = readOnlyReason;
8816
8824
  }
8825
+ if (credentials?.githubToken) {
8826
+ session.credentials.githubToken = credentials.githubToken;
8827
+ session.credentials.githubTokenExpiresAt = credentials.githubTokenExpiresAt;
8828
+ console.log("[AgentManager] EP1251: Updated GitHub token from message credentials");
8829
+ }
8817
8830
  const resumeSessionId = agentSessionId || claudeSessionId;
8818
8831
  try {
8819
8832
  const provider = session.provider || "claude";
@@ -8868,9 +8881,9 @@ Violations will result in errors and may affect your ability to assist.
8868
8881
  session.projectPath
8869
8882
  // Working directory
8870
8883
  ];
8871
- if (session.autonomousMode && session.canWrite !== false) {
8884
+ if (session.autonomousMode) {
8872
8885
  args.push("--full-auto");
8873
- console.log(`[AgentManager] EP1173: Codex autonomous mode enabled - using --full-auto`);
8886
+ console.log(`[AgentManager] EP1251: Codex autonomous mode enabled - using --full-auto`);
8874
8887
  }
8875
8888
  if (session.canWrite === false) {
8876
8889
  args.push("--sandbox", "read-only");
@@ -8919,11 +8932,9 @@ If changes are needed, explain what needs to be done but do not execute.
8919
8932
  args.push("--model", session.credentials.preferredModel);
8920
8933
  console.log(`[AgentManager] EP1152: Using user preferred model: ${session.credentials.preferredModel}`);
8921
8934
  }
8922
- if (session.autonomousMode && session.canWrite !== false) {
8935
+ if (session.autonomousMode) {
8923
8936
  args.push("--dangerously-skip-permissions");
8924
- console.log(`[AgentManager] EP1173: Autonomous mode enabled - skipping permission prompts`);
8925
- } else if (session.autonomousMode && session.canWrite === false) {
8926
- console.log(`[AgentManager] EP1205: Autonomous mode with read-only - NOT skipping permissions (safety net)`);
8937
+ console.log(`[AgentManager] EP1251: Autonomous mode enabled - skipping permission prompts`);
8927
8938
  }
8928
8939
  if (isFirstMessage && effectiveSystemPrompt) {
8929
8940
  args.push("--system-prompt", effectiveSystemPrompt);
@@ -8948,17 +8959,36 @@ If changes are needed, explain what needs to be done.`;
8948
8959
  const mcpServersToRegister = this.getMcpServersForSession(session);
8949
8960
  if (mcpServersToRegister.length > 0) {
8950
8961
  const mcpConfig = {};
8962
+ const sessionToken = process.env.EPISODA_ACCESS_TOKEN || process.env.EPISODA_SESSION_TOKEN || "";
8963
+ const devEnvId = process.env.EPISODA_CONTAINER_ID || process.env.EPISODA_MACHINE_ID || "";
8964
+ const episodaMcpEnv = {
8965
+ EPISODA_API_URL: process.env.EPISODA_API_URL || "https://episoda.dev",
8966
+ EPISODA_SESSION_TOKEN: sessionToken,
8967
+ MODULE_UID: session.moduleUid,
8968
+ DEV_ENVIRONMENT_ID: devEnvId
8969
+ };
8951
8970
  for (const mcpServer of mcpServersToRegister) {
8952
8971
  const parts = mcpServer.command.split(" ");
8953
- mcpConfig[mcpServer.name] = {
8954
- command: parts[0],
8955
- args: parts.slice(1)
8956
- };
8957
- console.log(`[AgentManager] EP1233: Registering MCP server: ${mcpServer.name}`);
8972
+ if (mcpServer.name === "github") {
8973
+ mcpConfig[mcpServer.name] = {
8974
+ command: parts[0],
8975
+ args: parts.slice(1),
8976
+ env: {
8977
+ GITHUB_PERSONAL_ACCESS_TOKEN: session.credentials.githubToken || ""
8978
+ }
8979
+ };
8980
+ } else {
8981
+ mcpConfig[mcpServer.name] = {
8982
+ command: parts[0],
8983
+ args: parts.slice(1),
8984
+ env: episodaMcpEnv
8985
+ };
8986
+ }
8987
+ console.log(`[AgentManager] EP1253: Registering MCP server: ${mcpServer.name} with explicit env`);
8958
8988
  }
8959
8989
  const mcpConfigJson = JSON.stringify({ mcpServers: mcpConfig });
8960
8990
  args.push("--mcp-config", mcpConfigJson);
8961
- console.log(`[AgentManager] EP1233: MCP config: ${mcpConfigJson}`);
8991
+ console.log(`[AgentManager] EP1253: MCP config with env: ${mcpConfigJson.substring(0, 200)}...`);
8962
8992
  }
8963
8993
  args.push("--", message);
8964
8994
  }
@@ -9056,9 +9086,6 @@ If changes are needed, explain what needs to be done.`;
9056
9086
  const filePath = path20.join(statsigDir, filename);
9057
9087
  fs19.writeFileSync(filePath, content, { mode: 420 });
9058
9088
  }
9059
- if (session.credentials.githubToken) {
9060
- console.log("[AgentManager] EP1146: GitHub MCP server enabled with installation token");
9061
- }
9062
9089
  console.log("[AgentManager] Wrote Claude config files");
9063
9090
  } catch (configError) {
9064
9091
  console.warn("[AgentManager] Failed to write Claude config files:", configError instanceof Error ? configError.message : configError);
@@ -9091,6 +9118,10 @@ If changes are needed, explain what needs to be done.`;
9091
9118
  console.warn("[AgentManager] EP1233: No session token available for MCP servers");
9092
9119
  }
9093
9120
  }
9121
+ if (session.credentials.githubToken) {
9122
+ envVars.GITHUB_PERSONAL_ACCESS_TOKEN = session.credentials.githubToken;
9123
+ console.log("[AgentManager] EP1251: Set GITHUB_PERSONAL_ACCESS_TOKEN for GitHub MCP");
9124
+ }
9094
9125
  if (useApiKey && session.credentials.apiKey) {
9095
9126
  if (provider === "codex") {
9096
9127
  envVars.OPENAI_API_KEY = session.credentials.apiKey;
@@ -11108,6 +11139,8 @@ var Daemon = class _Daemon {
11108
11139
  agentSessionId: cmd.agentSessionId || cmd.claudeSessionId,
11109
11140
  claudeSessionId: cmd.claudeSessionId,
11110
11141
  // Backward compat
11142
+ credentials: cmd.credentials,
11143
+ // EP1251: Pass credentials for token refresh
11111
11144
  ...callbacks
11112
11145
  });
11113
11146
  result = {