episoda 0.2.140 → 0.2.142

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.
@@ -2611,11 +2611,13 @@ var require_auth = __commonJS({
2611
2611
  exports2.validateToken = validateToken;
2612
2612
  var fs24 = __importStar(require("fs"));
2613
2613
  var path25 = __importStar(require("path"));
2614
- var os9 = __importStar(require("os"));
2614
+ var os10 = __importStar(require("os"));
2615
2615
  var child_process_1 = require("child_process");
2616
2616
  var DEFAULT_CONFIG_FILE = "config.json";
2617
+ var hasWarnedMissingProjectId = false;
2618
+ var hasWarnedMissingRequiredFields = false;
2617
2619
  function getConfigDir8() {
2618
- return process.env.EPISODA_CONFIG_DIR || path25.join(os9.homedir(), ".episoda");
2620
+ return process.env.EPISODA_CONFIG_DIR || path25.join(os10.homedir(), ".episoda");
2619
2621
  }
2620
2622
  function getConfigPath(configPath) {
2621
2623
  if (configPath) {
@@ -2705,8 +2707,8 @@ var require_auth = __commonJS({
2705
2707
  user_id: envValue(process.env.EPISODA_USER_ID) || workspaceConfig2.userId,
2706
2708
  workspace_id: envValue(process.env.EPISODA_WORKSPACE_ID) || workspaceConfig2.workspaceId,
2707
2709
  workspace_slug: envValue(process.env.EPISODA_WORKSPACE) || workspaceConfig2.workspaceSlug,
2708
- project_id: envValue(process.env.EPISODA_PROJECT_ID),
2709
- project_slug: envValue(process.env.EPISODA_PROJECT),
2710
+ project_id: envValue(process.env.EPISODA_PROJECT_ID) || workspaceConfig2.projectId || workspaceConfig2.project_id,
2711
+ project_slug: envValue(process.env.EPISODA_PROJECT) || workspaceConfig2.projectSlug || workspaceConfig2.project_slug,
2710
2712
  machine_uuid: envValue(process.env.EPISODA_CONTAINER_ID) || workspaceConfig2.containerId
2711
2713
  };
2712
2714
  } catch (error) {
@@ -2761,8 +2763,33 @@ var require_auth = __commonJS({
2761
2763
  if (Object.keys(mergedConfig).length === 0) {
2762
2764
  return null;
2763
2765
  }
2764
- const hasRequiredFields = Boolean(mergedConfig.project_id && mergedConfig.user_id && mergedConfig.workspace_id && mergedConfig.access_token && mergedConfig.api_url);
2765
- return hasRequiredFields ? mergedConfig : null;
2766
+ const requiredFields = [
2767
+ "access_token",
2768
+ "api_url",
2769
+ "user_id",
2770
+ "workspace_id"
2771
+ ];
2772
+ const missingFields = requiredFields.filter((field) => !mergedConfig[field]);
2773
+ if (missingFields.length > 0) {
2774
+ if (!hasWarnedMissingRequiredFields) {
2775
+ console.warn("[Auth] Cloud config missing required fields", {
2776
+ missing: missingFields,
2777
+ sources: {
2778
+ file: Boolean(fileConfig),
2779
+ workspace: Boolean(workspaceConfig),
2780
+ project: Boolean(projectConfig),
2781
+ env: Boolean(envConfig)
2782
+ }
2783
+ });
2784
+ hasWarnedMissingRequiredFields = true;
2785
+ }
2786
+ return null;
2787
+ }
2788
+ if (!mergedConfig.project_id && !hasWarnedMissingProjectId) {
2789
+ console.warn("[Auth] Cloud config missing project_id; running in workspace mode");
2790
+ hasWarnedMissingProjectId = true;
2791
+ }
2792
+ return mergedConfig;
2766
2793
  }
2767
2794
  async function saveConfig2(config, configPath) {
2768
2795
  const fullPath = getConfigPath(configPath);
@@ -2886,7 +2913,7 @@ var require_package = __commonJS({
2886
2913
  "package.json"(exports2, module2) {
2887
2914
  module2.exports = {
2888
2915
  name: "episoda",
2889
- version: "0.2.139",
2916
+ version: "0.2.141",
2890
2917
  description: "CLI tool for Episoda local development workflow orchestration",
2891
2918
  main: "dist/index.js",
2892
2919
  types: "dist/index.d.ts",
@@ -4142,6 +4169,7 @@ async function handleExec(command, projectPath) {
4142
4169
  // src/daemon/handlers/worktree-handlers.ts
4143
4170
  var path16 = __toESM(require("path"));
4144
4171
  var fs15 = __toESM(require("fs"));
4172
+ var os6 = __toESM(require("os"));
4145
4173
  var import_child_process8 = require("child_process");
4146
4174
  var import_util = require("util");
4147
4175
 
@@ -7641,6 +7669,41 @@ async function getConfigForApi() {
7641
7669
  return (0, import_core9.loadConfig)();
7642
7670
  }
7643
7671
  var execAsync = (0, import_util.promisify)(import_child_process8.exec);
7672
+ function persistWorkspaceProjectContext(workspaceSlug, projectSlug, projectId) {
7673
+ if (process.env.EPISODA_MODE !== "cloud") {
7674
+ return;
7675
+ }
7676
+ const homeDir = process.env.HOME || os6.homedir();
7677
+ const workspaceConfigPath = path16.join(
7678
+ homeDir,
7679
+ "episoda",
7680
+ workspaceSlug,
7681
+ ".episoda",
7682
+ "config.json"
7683
+ );
7684
+ if (!fs15.existsSync(workspaceConfigPath)) {
7685
+ return;
7686
+ }
7687
+ try {
7688
+ const content = fs15.readFileSync(workspaceConfigPath, "utf8");
7689
+ const workspaceConfig = JSON.parse(content);
7690
+ let changed = false;
7691
+ if (projectId && workspaceConfig.projectId !== projectId && workspaceConfig.project_id !== projectId) {
7692
+ workspaceConfig.projectId = projectId;
7693
+ changed = true;
7694
+ }
7695
+ if (projectSlug && workspaceConfig.projectSlug !== projectSlug && workspaceConfig.project_slug !== projectSlug) {
7696
+ workspaceConfig.projectSlug = projectSlug;
7697
+ changed = true;
7698
+ }
7699
+ if (changed) {
7700
+ fs15.writeFileSync(workspaceConfigPath, JSON.stringify(workspaceConfig, null, 2), "utf8");
7701
+ console.log("[Worktree] Updated workspace config with project context");
7702
+ }
7703
+ } catch (error) {
7704
+ console.warn("[Worktree] Failed to update workspace config:", error instanceof Error ? error.message : error);
7705
+ }
7706
+ }
7644
7707
  async function autoDetectSetupScript(worktreePath) {
7645
7708
  const detection = detectPackageManager(worktreePath);
7646
7709
  if (!detection.detected || !detection.packageManager) {
@@ -7682,6 +7745,7 @@ async function handleWorktreeCreate(request2) {
7682
7745
  console.log(`[Worktree] K1273: Creating worktree for ${moduleUid}`);
7683
7746
  console.log(`[Worktree] Project: ${projectSlug}`);
7684
7747
  console.log(`[Worktree] Branch: ${branchName} (create: ${createBranch})`);
7748
+ persistWorkspaceProjectContext(workspaceSlug, projectSlug, projectId);
7685
7749
  if (!validateModuleUid(moduleUid)) {
7686
7750
  return {
7687
7751
  success: false,
@@ -8456,7 +8520,7 @@ function generateCodexMcpConfigToml(servers, projectPath) {
8456
8520
  var import_child_process12 = require("child_process");
8457
8521
  var path20 = __toESM(require("path"));
8458
8522
  var fs19 = __toESM(require("fs"));
8459
- var os6 = __toESM(require("os"));
8523
+ var os7 = __toESM(require("os"));
8460
8524
 
8461
8525
  // src/agent/claude-config.ts
8462
8526
  var import_crypto = require("crypto");
@@ -8774,7 +8838,7 @@ var AgentManager = class {
8774
8838
  this.initialized = false;
8775
8839
  // EP1133: Lock for config file writes to prevent race conditions
8776
8840
  this.configWriteLock = Promise.resolve();
8777
- this.pidDir = path20.join(os6.homedir(), ".episoda", "agent-pids");
8841
+ this.pidDir = path20.join(os7.homedir(), ".episoda", "agent-pids");
8778
8842
  }
8779
8843
  /**
8780
8844
  * EP1133: Acquire lock for config file writes
@@ -8916,7 +8980,7 @@ var AgentManager = class {
8916
8980
  if (sessionProjectPath) {
8917
8981
  candidates.push(path20.join(sessionProjectPath, ".codex", "requirements.toml"));
8918
8982
  }
8919
- const codexHome = process.env.CODEX_HOME || path20.join(os6.homedir(), ".codex");
8983
+ const codexHome = process.env.CODEX_HOME || path20.join(os7.homedir(), ".codex");
8920
8984
  candidates.push(path20.join(codexHome, "requirements.toml"));
8921
8985
  candidates.push("/etc/codex/requirements.toml");
8922
8986
  for (const p of candidates) {
@@ -9440,10 +9504,10 @@ If changes are needed, explain what needs to be done.`;
9440
9504
  }
9441
9505
  const useOAuth = !!session.credentials.oauthToken;
9442
9506
  const useApiKey = !useOAuth && !!session.credentials.apiKey;
9443
- const sessionCodexDir = path20.join(os6.homedir(), ".codex", "sessions", sessionId);
9444
- const sessionClaudeDir = path20.join(os6.homedir(), ".claude", "sessions", sessionId);
9445
- const legacyCodexDir = path20.join(os6.homedir(), ".codex");
9446
- const legacyClaudeDir = path20.join(os6.homedir(), ".claude");
9507
+ const sessionCodexDir = path20.join(os7.homedir(), ".codex", "sessions", sessionId);
9508
+ const sessionClaudeDir = path20.join(os7.homedir(), ".claude", "sessions", sessionId);
9509
+ const legacyCodexDir = path20.join(os7.homedir(), ".codex");
9510
+ const legacyClaudeDir = path20.join(os7.homedir(), ".claude");
9447
9511
  const sessionConfigDir = provider === "codex" ? sessionCodexDir : sessionClaudeDir;
9448
9512
  const legacyConfigDir = provider === "codex" ? legacyCodexDir : legacyClaudeDir;
9449
9513
  if (useOAuth) {
@@ -9936,7 +10000,7 @@ If changes are needed, explain what needs to be done.`;
9936
10000
  cleanupSessionCredentials(sessionId, provider) {
9937
10001
  const providers = provider ? [provider] : ["claude", "codex"];
9938
10002
  for (const p of providers) {
9939
- const sessionDir = p === "codex" ? path20.join(os6.homedir(), ".codex", "sessions", sessionId) : path20.join(os6.homedir(), ".claude", "sessions", sessionId);
10003
+ const sessionDir = p === "codex" ? path20.join(os7.homedir(), ".codex", "sessions", sessionId) : path20.join(os7.homedir(), ".claude", "sessions", sessionId);
9940
10004
  try {
9941
10005
  if (fs19.existsSync(sessionDir)) {
9942
10006
  fs19.rmSync(sessionDir, { recursive: true, force: true });
@@ -10605,7 +10669,7 @@ function getDevServerStatus() {
10605
10669
  // src/utils/worktree.ts
10606
10670
  var path22 = __toESM(require("path"));
10607
10671
  var fs21 = __toESM(require("fs"));
10608
- var os7 = __toESM(require("os"));
10672
+ var os8 = __toESM(require("os"));
10609
10673
  var import_core13 = __toESM(require_dist());
10610
10674
  function getEpisodaRoot2() {
10611
10675
  if (process.env.EPISODA_ROOT) {
@@ -10614,7 +10678,7 @@ function getEpisodaRoot2() {
10614
10678
  if (process.env.EPISODA_MODE === "cloud") {
10615
10679
  return process.env.HOME || "/home/episoda";
10616
10680
  }
10617
- return path22.join(os7.homedir(), "episoda");
10681
+ return path22.join(os8.homedir(), "episoda");
10618
10682
  }
10619
10683
  function getWorktreeInfo(moduleUid, workspaceSlug, projectSlug) {
10620
10684
  const root = getEpisodaRoot2();
@@ -10757,7 +10821,7 @@ function getInstallCommand2(cwd) {
10757
10821
  // src/daemon/daemon-process.ts
10758
10822
  var fs23 = __toESM(require("fs"));
10759
10823
  var http2 = __toESM(require("http"));
10760
- var os8 = __toESM(require("os"));
10824
+ var os9 = __toESM(require("os"));
10761
10825
  var path24 = __toESM(require("path"));
10762
10826
  var packageJson = require_package();
10763
10827
  function getBuildPackagesCommand2(installCmd) {
@@ -11130,9 +11194,9 @@ var Daemon = class _Daemon {
11130
11194
  // EP726: Kept for backward compatibility
11131
11195
  machineName: this.deviceName,
11132
11196
  // EP1186: User-friendly machine name from server
11133
- hostname: os8.hostname(),
11134
- platform: os8.platform(),
11135
- arch: os8.arch(),
11197
+ hostname: os9.hostname(),
11198
+ platform: os9.platform(),
11199
+ arch: os9.arch(),
11136
11200
  projects
11137
11201
  };
11138
11202
  });
@@ -12151,9 +12215,9 @@ var Daemon = class _Daemon {
12151
12215
  const environment = modeConfig.mode;
12152
12216
  const containerId = process.env.EPISODA_CONTAINER_ID;
12153
12217
  await client.connect(wsUrl, config.access_token, this.machineId, {
12154
- hostname: os8.hostname(),
12155
- osPlatform: os8.platform(),
12156
- osArch: os8.arch(),
12218
+ hostname: os9.hostname(),
12219
+ osPlatform: os9.platform(),
12220
+ osArch: os9.arch(),
12157
12221
  daemonPid,
12158
12222
  environment,
12159
12223
  containerId