@episoda/cli 0.2.189 → 0.2.190

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.
@@ -1640,15 +1640,15 @@ var require_git_executor = __commonJS({
1640
1640
  try {
1641
1641
  const { stdout: gitDir } = await execAsync3("git rev-parse --git-dir", { cwd, timeout: 5e3 });
1642
1642
  const gitDirPath = gitDir.trim();
1643
- const fs35 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1643
+ const fs36 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1644
1644
  const rebaseMergePath = `${gitDirPath}/rebase-merge`;
1645
1645
  const rebaseApplyPath = `${gitDirPath}/rebase-apply`;
1646
1646
  try {
1647
- await fs35.access(rebaseMergePath);
1647
+ await fs36.access(rebaseMergePath);
1648
1648
  inRebase = true;
1649
1649
  } catch {
1650
1650
  try {
1651
- await fs35.access(rebaseApplyPath);
1651
+ await fs36.access(rebaseApplyPath);
1652
1652
  inRebase = true;
1653
1653
  } catch {
1654
1654
  inRebase = false;
@@ -1704,9 +1704,9 @@ var require_git_executor = __commonJS({
1704
1704
  };
1705
1705
  }
1706
1706
  }
1707
- const fs35 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1707
+ const fs36 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1708
1708
  try {
1709
- await fs35.access(command.path);
1709
+ await fs36.access(command.path);
1710
1710
  return {
1711
1711
  success: false,
1712
1712
  error: "WORKTREE_EXISTS",
@@ -1765,9 +1765,9 @@ var require_git_executor = __commonJS({
1765
1765
  */
1766
1766
  async executeWorktreeRemove(command, cwd, options) {
1767
1767
  try {
1768
- const fs35 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1768
+ const fs36 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1769
1769
  try {
1770
- await fs35.access(command.path);
1770
+ await fs36.access(command.path);
1771
1771
  } catch {
1772
1772
  return {
1773
1773
  success: false,
@@ -1802,7 +1802,7 @@ var require_git_executor = __commonJS({
1802
1802
  const result = await this.runGitCommand(args, cwd, options);
1803
1803
  if (result.success) {
1804
1804
  try {
1805
- await fs35.rm(command.path, { recursive: true, force: true });
1805
+ await fs36.rm(command.path, { recursive: true, force: true });
1806
1806
  } catch {
1807
1807
  }
1808
1808
  return {
@@ -1936,10 +1936,10 @@ var require_git_executor = __commonJS({
1936
1936
  */
1937
1937
  async executeCloneBare(command, options) {
1938
1938
  try {
1939
- const fs35 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1940
- const path37 = await Promise.resolve().then(() => __importStar(require("path")));
1939
+ const fs36 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1940
+ const path38 = await Promise.resolve().then(() => __importStar(require("path")));
1941
1941
  try {
1942
- await fs35.access(command.path);
1942
+ await fs36.access(command.path);
1943
1943
  return {
1944
1944
  success: false,
1945
1945
  error: "BRANCH_ALREADY_EXISTS",
@@ -1948,9 +1948,9 @@ var require_git_executor = __commonJS({
1948
1948
  };
1949
1949
  } catch {
1950
1950
  }
1951
- const parentDir = path37.dirname(command.path);
1951
+ const parentDir = path38.dirname(command.path);
1952
1952
  try {
1953
- await fs35.mkdir(parentDir, { recursive: true });
1953
+ await fs36.mkdir(parentDir, { recursive: true });
1954
1954
  } catch {
1955
1955
  }
1956
1956
  const { stdout, stderr } = await execAsync3(
@@ -1998,22 +1998,22 @@ var require_git_executor = __commonJS({
1998
1998
  */
1999
1999
  async executeProjectInfo(cwd, options) {
2000
2000
  try {
2001
- const fs35 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
2002
- const path37 = await Promise.resolve().then(() => __importStar(require("path")));
2001
+ const fs36 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
2002
+ const path38 = await Promise.resolve().then(() => __importStar(require("path")));
2003
2003
  let currentPath = cwd;
2004
2004
  let projectPath = cwd;
2005
2005
  let bareRepoPath;
2006
2006
  for (let i = 0; i < 10; i++) {
2007
- const bareDir = path37.join(currentPath, ".bare");
2008
- const episodaDir = path37.join(currentPath, ".episoda");
2007
+ const bareDir = path38.join(currentPath, ".bare");
2008
+ const episodaDir = path38.join(currentPath, ".episoda");
2009
2009
  try {
2010
- await fs35.access(bareDir);
2011
- await fs35.access(episodaDir);
2010
+ await fs36.access(bareDir);
2011
+ await fs36.access(episodaDir);
2012
2012
  projectPath = currentPath;
2013
2013
  bareRepoPath = bareDir;
2014
2014
  break;
2015
2015
  } catch {
2016
- const parentPath = path37.dirname(currentPath);
2016
+ const parentPath = path38.dirname(currentPath);
2017
2017
  if (parentPath === currentPath) {
2018
2018
  break;
2019
2019
  }
@@ -2724,33 +2724,33 @@ var require_auth = __commonJS({
2724
2724
  exports2.loadConfig = loadConfig16;
2725
2725
  exports2.saveConfig = saveConfig4;
2726
2726
  exports2.validateToken = validateToken;
2727
- var fs35 = __importStar(require("fs"));
2728
- var path37 = __importStar(require("path"));
2729
- var os16 = __importStar(require("os"));
2727
+ var fs36 = __importStar(require("fs"));
2728
+ var path38 = __importStar(require("path"));
2729
+ var os17 = __importStar(require("os"));
2730
2730
  var child_process_1 = require("child_process");
2731
2731
  var DEFAULT_CONFIG_FILE = "config.json";
2732
2732
  var hasWarnedMissingProjectId = false;
2733
2733
  var hasWarnedMissingRequiredFields = false;
2734
2734
  function getConfigDir10() {
2735
- return process.env.EPISODA_CONFIG_DIR || path37.join(os16.homedir(), ".episoda");
2735
+ return process.env.EPISODA_CONFIG_DIR || path38.join(os17.homedir(), ".episoda");
2736
2736
  }
2737
2737
  function getConfigPath(configPath) {
2738
2738
  if (configPath) {
2739
2739
  return configPath;
2740
2740
  }
2741
- return path37.join(getConfigDir10(), DEFAULT_CONFIG_FILE);
2741
+ return path38.join(getConfigDir10(), DEFAULT_CONFIG_FILE);
2742
2742
  }
2743
2743
  function ensureConfigDir(configPath) {
2744
- const dir = path37.dirname(configPath);
2745
- const isNew = !fs35.existsSync(dir);
2744
+ const dir = path38.dirname(configPath);
2745
+ const isNew = !fs36.existsSync(dir);
2746
2746
  if (isNew) {
2747
- fs35.mkdirSync(dir, { recursive: true, mode: 448 });
2747
+ fs36.mkdirSync(dir, { recursive: true, mode: 448 });
2748
2748
  }
2749
2749
  if (process.platform === "darwin") {
2750
- const nosyncPath = path37.join(dir, ".nosync");
2751
- if (isNew || !fs35.existsSync(nosyncPath)) {
2750
+ const nosyncPath = path38.join(dir, ".nosync");
2751
+ if (isNew || !fs36.existsSync(nosyncPath)) {
2752
2752
  try {
2753
- fs35.writeFileSync(nosyncPath, "", { mode: 384 });
2753
+ fs36.writeFileSync(nosyncPath, "", { mode: 384 });
2754
2754
  (0, child_process_1.execSync)(`xattr -w com.apple.fileprovider.ignore 1 "${dir}"`, {
2755
2755
  stdio: "ignore",
2756
2756
  timeout: 5e3
@@ -2764,11 +2764,11 @@ var require_auth = __commonJS({
2764
2764
  const fullPath = getConfigPath(configPath);
2765
2765
  const isCloudMode = process.env.EPISODA_MODE === "cloud";
2766
2766
  const readConfigFile = (pathToFile) => {
2767
- if (!fs35.existsSync(pathToFile)) {
2767
+ if (!fs36.existsSync(pathToFile)) {
2768
2768
  return null;
2769
2769
  }
2770
2770
  try {
2771
- const content = fs35.readFileSync(pathToFile, "utf8");
2771
+ const content = fs36.readFileSync(pathToFile, "utf8");
2772
2772
  return JSON.parse(content);
2773
2773
  } catch (error) {
2774
2774
  console.error("Error loading config:", error);
@@ -2807,11 +2807,11 @@ var require_auth = __commonJS({
2807
2807
  }
2808
2808
  const homeDir = process.env.HOME || require("os").homedir();
2809
2809
  const workspaceConfigPath = require("path").join(homeDir, "episoda", process.env.EPISODA_WORKSPACE, ".episoda", "config.json");
2810
- if (!fs35.existsSync(workspaceConfigPath)) {
2810
+ if (!fs36.existsSync(workspaceConfigPath)) {
2811
2811
  return null;
2812
2812
  }
2813
2813
  try {
2814
- const content = fs35.readFileSync(workspaceConfigPath, "utf8");
2814
+ const content = fs36.readFileSync(workspaceConfigPath, "utf8");
2815
2815
  const workspaceConfig2 = JSON.parse(content);
2816
2816
  const expiresAtEnv = envValue(process.env.EPISODA_ACCESS_TOKEN_EXPIRES_AT);
2817
2817
  return {
@@ -2839,11 +2839,11 @@ var require_auth = __commonJS({
2839
2839
  }
2840
2840
  const homeDir = process.env.HOME || require("os").homedir();
2841
2841
  const projectConfigPath = require("path").join(homeDir, "episoda", workspaceSlug, projectSlug, ".episoda", "config.json");
2842
- if (!fs35.existsSync(projectConfigPath)) {
2842
+ if (!fs36.existsSync(projectConfigPath)) {
2843
2843
  return null;
2844
2844
  }
2845
2845
  try {
2846
- const content = fs35.readFileSync(projectConfigPath, "utf8");
2846
+ const content = fs36.readFileSync(projectConfigPath, "utf8");
2847
2847
  const projectConfig2 = JSON.parse(content);
2848
2848
  return {
2849
2849
  project_id: projectConfig2.projectId || projectConfig2.project_id,
@@ -2911,7 +2911,7 @@ var require_auth = __commonJS({
2911
2911
  ensureConfigDir(fullPath);
2912
2912
  try {
2913
2913
  const content = JSON.stringify(config, null, 2);
2914
- fs35.writeFileSync(fullPath, content, { mode: 384 });
2914
+ fs36.writeFileSync(fullPath, content, { mode: 384 });
2915
2915
  } catch (error) {
2916
2916
  throw new Error(`Failed to save config: ${error instanceof Error ? error.message : String(error)}`);
2917
2917
  }
@@ -3046,7 +3046,7 @@ var require_package = __commonJS({
3046
3046
  "package.json"(exports2, module2) {
3047
3047
  module2.exports = {
3048
3048
  name: "@episoda/cli",
3049
- version: "0.2.189",
3049
+ version: "0.2.190",
3050
3050
  description: "CLI tool for Episoda local development workflow orchestration",
3051
3051
  main: "dist/index.js",
3052
3052
  types: "dist/index.d.ts",
@@ -9663,14 +9663,14 @@ function getInstallCommand(cwd) {
9663
9663
  }
9664
9664
 
9665
9665
  // src/daemon/daemon-process.ts
9666
- var fs34 = __toESM(require("fs"));
9666
+ var fs35 = __toESM(require("fs"));
9667
9667
  var http2 = __toESM(require("http"));
9668
- var os15 = __toESM(require("os"));
9669
- var path36 = __toESM(require("path"));
9668
+ var os16 = __toESM(require("os"));
9669
+ var path37 = __toESM(require("path"));
9670
9670
  var import_child_process19 = require("child_process");
9671
9671
 
9672
9672
  // src/daemon/ipc-router.ts
9673
- var os14 = __toESM(require("os"));
9673
+ var os15 = __toESM(require("os"));
9674
9674
  var import_core15 = __toESM(require_dist());
9675
9675
 
9676
9676
  // src/daemon/handlers/file-handlers.ts
@@ -12873,6 +12873,9 @@ async function handleProjectSetup(params) {
12873
12873
 
12874
12874
  // src/daemon/handlers/pty-handler.ts
12875
12875
  var pty = __toESM(require("@lydell/node-pty"));
12876
+ var fs30 = __toESM(require("fs"));
12877
+ var os14 = __toESM(require("os"));
12878
+ var path30 = __toESM(require("path"));
12876
12879
  var INACTIVITY_TIMEOUT_MS3 = 30 * 60 * 1e3;
12877
12880
  var sessions = /* @__PURE__ */ new Map();
12878
12881
  async function handlePtySpawn(payload, client) {
@@ -12882,6 +12885,7 @@ async function handlePtySpawn(payload, client) {
12882
12885
  return;
12883
12886
  }
12884
12887
  console.log(`[PTY] Spawning PTY for ${moduleUid} / ${agent_run_id}: ${command} ${args.join(" ")}`);
12888
+ const bootstrap = createCredentialBootstrap(payload, agent_run_id);
12885
12889
  let proc;
12886
12890
  try {
12887
12891
  proc = pty.spawn(command, args, {
@@ -12889,9 +12893,14 @@ async function handlePtySpawn(payload, client) {
12889
12893
  cols,
12890
12894
  rows,
12891
12895
  cwd: cwd || process.cwd(),
12892
- env: { ...process.env, ...env || {} }
12896
+ env: {
12897
+ ...process.env,
12898
+ ...env || {},
12899
+ ...bootstrap.env
12900
+ }
12893
12901
  });
12894
12902
  } catch (err) {
12903
+ cleanupCredentialDirs(bootstrap.cleanupDirs);
12895
12904
  console.error(`[PTY] Failed to spawn PTY for ${agent_run_id}:`, err);
12896
12905
  await client.send({
12897
12906
  type: "pty_exit",
@@ -12908,7 +12917,8 @@ async function handlePtySpawn(payload, client) {
12908
12917
  agent_run_id,
12909
12918
  startedAt: Date.now(),
12910
12919
  lastOutputAt: Date.now(),
12911
- watchdogTimer: null
12920
+ watchdogTimer: null,
12921
+ credentialDirs: bootstrap.cleanupDirs
12912
12922
  };
12913
12923
  sessions.set(agent_run_id, session);
12914
12924
  const resetWatchdog = () => {
@@ -12942,6 +12952,7 @@ async function handlePtySpawn(payload, client) {
12942
12952
  if (session.watchdogTimer) clearTimeout(session.watchdogTimer);
12943
12953
  console.log(`[PTY] Process exited for ${agent_run_id} with code ${exitCode} after ${durationMs}ms`);
12944
12954
  sessions.delete(agent_run_id);
12955
+ cleanupCredentialDirs(session.credentialDirs);
12945
12956
  client.send({
12946
12957
  type: "pty_exit",
12947
12958
  moduleUid,
@@ -12977,15 +12988,67 @@ function handlePtyKill(payload) {
12977
12988
  session.pty.kill();
12978
12989
  } catch {
12979
12990
  }
12991
+ cleanupCredentialDirs(session.credentialDirs);
12980
12992
  sessions.delete(agent_run_id);
12981
12993
  console.log(`[PTY] Killed session ${agent_run_id}`);
12982
12994
  }
12995
+ function createCredentialBootstrap(payload, agentRunId) {
12996
+ const bootstrap = payload.credential_bootstrap;
12997
+ if (!bootstrap?.oauth?.access_token) {
12998
+ return { env: {}, cleanupDirs: [] };
12999
+ }
13000
+ const baseDir = fs30.mkdtempSync(path30.join(os14.tmpdir(), `episoda-pty-${agentRunId}-`));
13001
+ const cleanupDirs = [baseDir];
13002
+ if (bootstrap.provider === "claude") {
13003
+ const claudeConfigDir = path30.join(baseDir, ".claude");
13004
+ fs30.mkdirSync(claudeConfigDir, { recursive: true });
13005
+ const credentialsPath = path30.join(claudeConfigDir, ".credentials.json");
13006
+ const claudeAiOauth = {
13007
+ accessToken: bootstrap.oauth.access_token
13008
+ };
13009
+ if (bootstrap.oauth.refresh_token) claudeAiOauth.refreshToken = bootstrap.oauth.refresh_token;
13010
+ if (bootstrap.oauth.expires_at) claudeAiOauth.expiresAt = new Date(bootstrap.oauth.expires_at).getTime();
13011
+ if (bootstrap.oauth.scopes) claudeAiOauth.scopes = bootstrap.oauth.scopes;
13012
+ fs30.writeFileSync(credentialsPath, JSON.stringify({ claudeAiOauth }, null, 2), { mode: 384 });
13013
+ return {
13014
+ env: { CLAUDE_CONFIG_DIR: claudeConfigDir },
13015
+ cleanupDirs
13016
+ };
13017
+ }
13018
+ const codexHome = path30.join(baseDir, ".codex");
13019
+ fs30.mkdirSync(codexHome, { recursive: true });
13020
+ const authPath = path30.join(codexHome, "auth.json");
13021
+ const authPayload = {
13022
+ tokens: {
13023
+ access_token: bootstrap.oauth.access_token,
13024
+ refresh_token: bootstrap.oauth.refresh_token,
13025
+ id_token: bootstrap.oauth.id_token,
13026
+ account_id: bootstrap.oauth.account_id
13027
+ }
13028
+ };
13029
+ fs30.writeFileSync(authPath, JSON.stringify(authPayload, null, 2), { mode: 384 });
13030
+ return {
13031
+ env: { CODEX_HOME: codexHome },
13032
+ cleanupDirs
13033
+ };
13034
+ }
13035
+ function cleanupCredentialDirs(dirs) {
13036
+ for (const dirPath of dirs) {
13037
+ try {
13038
+ if (fs30.existsSync(dirPath)) {
13039
+ fs30.rmSync(dirPath, { recursive: true, force: true });
13040
+ }
13041
+ } catch (error) {
13042
+ console.warn(`[PTY] Failed to cleanup credential dir ${dirPath}:`, error);
13043
+ }
13044
+ }
13045
+ }
12983
13046
 
12984
13047
  // src/utils/dev-server.ts
12985
13048
  var import_child_process15 = require("child_process");
12986
13049
  var import_core14 = __toESM(require_dist());
12987
- var fs30 = __toESM(require("fs"));
12988
- var path30 = __toESM(require("path"));
13050
+ var fs31 = __toESM(require("fs"));
13051
+ var path31 = __toESM(require("path"));
12989
13052
  var MAX_RESTART_ATTEMPTS = 5;
12990
13053
  var INITIAL_RESTART_DELAY_MS = 2e3;
12991
13054
  var MAX_RESTART_DELAY_MS = 3e4;
@@ -12993,26 +13056,26 @@ var MAX_LOG_SIZE_BYTES2 = 5 * 1024 * 1024;
12993
13056
  var NODE_MEMORY_LIMIT_MB = 2048;
12994
13057
  var activeServers = /* @__PURE__ */ new Map();
12995
13058
  function getLogsDir() {
12996
- const logsDir = path30.join((0, import_core14.getConfigDir)(), "logs");
12997
- if (!fs30.existsSync(logsDir)) {
12998
- fs30.mkdirSync(logsDir, { recursive: true });
13059
+ const logsDir = path31.join((0, import_core14.getConfigDir)(), "logs");
13060
+ if (!fs31.existsSync(logsDir)) {
13061
+ fs31.mkdirSync(logsDir, { recursive: true });
12999
13062
  }
13000
13063
  return logsDir;
13001
13064
  }
13002
13065
  function getLogFilePath(moduleUid) {
13003
- return path30.join(getLogsDir(), `dev-${moduleUid}.log`);
13066
+ return path31.join(getLogsDir(), `dev-${moduleUid}.log`);
13004
13067
  }
13005
13068
  function rotateLogIfNeeded(logPath) {
13006
13069
  try {
13007
- if (fs30.existsSync(logPath)) {
13008
- const stats = fs30.statSync(logPath);
13070
+ if (fs31.existsSync(logPath)) {
13071
+ const stats = fs31.statSync(logPath);
13009
13072
  if (stats.size > MAX_LOG_SIZE_BYTES2) {
13010
13073
  const backupPath = `${logPath}.1`;
13011
- if (fs30.existsSync(backupPath)) {
13012
- fs30.unlinkSync(backupPath);
13074
+ if (fs31.existsSync(backupPath)) {
13075
+ fs31.unlinkSync(backupPath);
13013
13076
  }
13014
- fs30.renameSync(logPath, backupPath);
13015
- console.log(`[DevServer] EP932: Rotated log file for ${path30.basename(logPath)}`);
13077
+ fs31.renameSync(logPath, backupPath);
13078
+ console.log(`[DevServer] EP932: Rotated log file for ${path31.basename(logPath)}`);
13016
13079
  }
13017
13080
  }
13018
13081
  } catch (error) {
@@ -13025,7 +13088,7 @@ function writeToLog(logPath, line, isError = false) {
13025
13088
  const prefix = isError ? "ERR" : "OUT";
13026
13089
  const logLine = `[${timestamp}] [${prefix}] ${line}
13027
13090
  `;
13028
- fs30.appendFileSync(logPath, logLine);
13091
+ fs31.appendFileSync(logPath, logLine);
13029
13092
  } catch {
13030
13093
  }
13031
13094
  }
@@ -13204,8 +13267,8 @@ async function startDevServer(projectPath, port = 3e3, moduleUid = "default", op
13204
13267
  });
13205
13268
  injectedEnvVars = result.envVars;
13206
13269
  console.log(`[DevServer] EP998: Loaded ${Object.keys(injectedEnvVars).length} env vars (from ${result.fromCache ? "cache" : "server"})`);
13207
- const envFilePath = path30.join(projectPath, ".env");
13208
- if (!fs30.existsSync(envFilePath) && Object.keys(injectedEnvVars).length > 0) {
13270
+ const envFilePath = path31.join(projectPath, ".env");
13271
+ if (!fs31.existsSync(envFilePath) && Object.keys(injectedEnvVars).length > 0) {
13209
13272
  console.log(`[DevServer] EP1004: .env file missing, writing ${Object.keys(injectedEnvVars).length} vars to ${envFilePath}`);
13210
13273
  writeEnvFile(projectPath, injectedEnvVars);
13211
13274
  }
@@ -13343,9 +13406,9 @@ var IPCRouter = class {
13343
13406
  // EP726: Kept for backward compatibility
13344
13407
  machineName: this.host.deviceName,
13345
13408
  // EP1186: User-friendly machine name from server
13346
- hostname: os14.hostname(),
13347
- platform: os14.platform(),
13348
- arch: os14.arch(),
13409
+ hostname: os15.hostname(),
13410
+ platform: os15.platform(),
13411
+ arch: os15.arch(),
13349
13412
  projects
13350
13413
  };
13351
13414
  });
@@ -13547,8 +13610,8 @@ var IPCRouter = class {
13547
13610
  };
13548
13611
 
13549
13612
  // src/daemon/update-manager.ts
13550
- var fs31 = __toESM(require("fs"));
13551
- var path31 = __toESM(require("path"));
13613
+ var fs32 = __toESM(require("fs"));
13614
+ var path32 = __toESM(require("path"));
13552
13615
  var import_child_process17 = require("child_process");
13553
13616
  var import_core17 = __toESM(require_dist());
13554
13617
  var semver2 = __toESM(require("semver"));
@@ -13806,8 +13869,8 @@ var UpdateManager = class _UpdateManager {
13806
13869
  console.log(`[Daemon] EP1324: Update to ${targetVersion} installed, restarting daemon...`);
13807
13870
  await this.host.shutdown();
13808
13871
  const configDir = (0, import_core17.getConfigDir)();
13809
- const logPath = path31.join(configDir, "daemon.log");
13810
- const logFd = fs31.openSync(logPath, "a");
13872
+ const logPath = path32.join(configDir, "daemon.log");
13873
+ const logFd = fs32.openSync(logPath, "a");
13811
13874
  const child = (0, import_child_process17.spawn)("node", [this.daemonEntryFile], {
13812
13875
  detached: true,
13813
13876
  stdio: ["ignore", logFd, logFd],
@@ -13817,7 +13880,7 @@ var UpdateManager = class _UpdateManager {
13817
13880
  });
13818
13881
  if (!child.pid) {
13819
13882
  try {
13820
- fs31.closeSync(logFd);
13883
+ fs32.closeSync(logFd);
13821
13884
  } catch {
13822
13885
  }
13823
13886
  this.recordUpdateFailure(targetVersion, "Failed to spawn replacement daemon (missing pid)");
@@ -13825,7 +13888,7 @@ var UpdateManager = class _UpdateManager {
13825
13888
  }
13826
13889
  child.unref();
13827
13890
  const pidPath = getPidFilePath();
13828
- fs31.writeFileSync(pidPath, child.pid.toString(), "utf-8");
13891
+ fs32.writeFileSync(pidPath, child.pid.toString(), "utf-8");
13829
13892
  console.log(`[Daemon] EP1324: New daemon spawned (PID: ${child.pid}), exiting old process`);
13830
13893
  process.exit(0);
13831
13894
  } catch (error) {
@@ -13876,8 +13939,8 @@ var UpdateManager = class _UpdateManager {
13876
13939
  };
13877
13940
 
13878
13941
  // src/daemon/health-orchestrator.ts
13879
- var fs32 = __toESM(require("fs"));
13880
- var path32 = __toESM(require("path"));
13942
+ var fs33 = __toESM(require("fs"));
13943
+ var path33 = __toESM(require("path"));
13881
13944
  var import_core18 = __toESM(require_dist());
13882
13945
  var HealthOrchestrator = class _HealthOrchestrator {
13883
13946
  constructor(host) {
@@ -14137,26 +14200,26 @@ var HealthOrchestrator = class _HealthOrchestrator {
14137
14200
  checkAndRotateLog() {
14138
14201
  try {
14139
14202
  const configDir = (0, import_core18.getConfigDir)();
14140
- const logPath = path32.join(configDir, "daemon.log");
14141
- if (!fs32.existsSync(logPath)) return;
14142
- const stats = fs32.statSync(logPath);
14203
+ const logPath = path33.join(configDir, "daemon.log");
14204
+ if (!fs33.existsSync(logPath)) return;
14205
+ const stats = fs33.statSync(logPath);
14143
14206
  if (stats.size < _HealthOrchestrator.MAX_LOG_SIZE_BYTES) return;
14144
14207
  console.log(`[Daemon] EP1351: daemon.log is ${Math.round(stats.size / 1024 / 1024)}MB, rotating...`);
14145
14208
  for (let i = _HealthOrchestrator.MAX_LOG_FILES - 1; i >= 1; i--) {
14146
14209
  const src = `${logPath}.${i}`;
14147
14210
  const dst = `${logPath}.${i + 1}`;
14148
- if (fs32.existsSync(src)) {
14211
+ if (fs33.existsSync(src)) {
14149
14212
  try {
14150
- fs32.renameSync(src, dst);
14213
+ fs33.renameSync(src, dst);
14151
14214
  } catch {
14152
14215
  }
14153
14216
  }
14154
14217
  }
14155
14218
  try {
14156
- fs32.copyFileSync(logPath, `${logPath}.1`);
14219
+ fs33.copyFileSync(logPath, `${logPath}.1`);
14157
14220
  } catch {
14158
14221
  }
14159
- fs32.truncateSync(logPath, 0);
14222
+ fs33.truncateSync(logPath, 0);
14160
14223
  console.log("[Daemon] EP1351: Log rotated successfully");
14161
14224
  } catch (error) {
14162
14225
  console.warn("[Daemon] EP1351: Log rotation failed:", error instanceof Error ? error.message : error);
@@ -14205,9 +14268,9 @@ var HealthOrchestrator = class _HealthOrchestrator {
14205
14268
  if (Number.isFinite(lastAccessedMs)) {
14206
14269
  referenceTimestampMs = lastAccessedMs;
14207
14270
  fallbackAgeSource.push(`${w.moduleUid}(lastAccessed)`);
14208
- } else if (w.worktreePath && fs32.existsSync(w.worktreePath)) {
14271
+ } else if (w.worktreePath && fs33.existsSync(w.worktreePath)) {
14209
14272
  try {
14210
- const stats = fs32.statSync(w.worktreePath);
14273
+ const stats = fs33.statSync(w.worktreePath);
14211
14274
  referenceTimestampMs = stats.mtimeMs;
14212
14275
  fallbackAgeSource.push(`${w.moduleUid}(fs.mtime)`);
14213
14276
  } catch {
@@ -14753,7 +14816,7 @@ function resolveDaemonWsEndpoint(config, env = process.env) {
14753
14816
 
14754
14817
  // src/daemon/project-message-router.ts
14755
14818
  var import_core19 = __toESM(require_dist());
14756
- var path33 = __toESM(require("path"));
14819
+ var path34 = __toESM(require("path"));
14757
14820
  var ProjectMessageRouter = class {
14758
14821
  constructor(host) {
14759
14822
  this.host = host;
@@ -14771,7 +14834,7 @@ var ProjectMessageRouter = class {
14771
14834
  client.updateActivity();
14772
14835
  try {
14773
14836
  const gitCmd = message.command;
14774
- const bareRepoPath = path33.join(projectPath, ".bare");
14837
+ const bareRepoPath = path34.join(projectPath, ".bare");
14775
14838
  const cwd = gitCmd.worktreePath || bareRepoPath;
14776
14839
  if (gitCmd.worktreePath) {
14777
14840
  console.log(`[Daemon] Routing command to worktree: ${gitCmd.worktreePath}`);
@@ -15145,32 +15208,32 @@ async function fetchEnvVars2(projectId) {
15145
15208
  }
15146
15209
 
15147
15210
  // src/daemon/project-git-config.ts
15148
- var fs33 = __toESM(require("fs"));
15149
- var path34 = __toESM(require("path"));
15211
+ var fs34 = __toESM(require("fs"));
15212
+ var path35 = __toESM(require("path"));
15150
15213
  var import_core21 = __toESM(require_dist());
15151
15214
  function getGitDirs(projectPath) {
15152
- const bareDir = path34.join(projectPath, ".bare");
15153
- const gitPath = path34.join(projectPath, ".git");
15154
- if (fs33.existsSync(bareDir) && fs33.statSync(bareDir).isDirectory()) {
15215
+ const bareDir = path35.join(projectPath, ".bare");
15216
+ const gitPath = path35.join(projectPath, ".git");
15217
+ if (fs34.existsSync(bareDir) && fs34.statSync(bareDir).isDirectory()) {
15155
15218
  return { gitDir: bareDir, workDir: projectPath };
15156
15219
  }
15157
- if (fs33.existsSync(gitPath) && fs33.statSync(gitPath).isDirectory()) {
15220
+ if (fs34.existsSync(gitPath) && fs34.statSync(gitPath).isDirectory()) {
15158
15221
  return { gitDir: null, workDir: projectPath };
15159
15222
  }
15160
- if (fs33.existsSync(gitPath) && fs33.statSync(gitPath).isFile()) {
15223
+ if (fs34.existsSync(gitPath) && fs34.statSync(gitPath).isFile()) {
15161
15224
  return { gitDir: null, workDir: projectPath };
15162
15225
  }
15163
- const entries = fs33.readdirSync(projectPath, { withFileTypes: true });
15226
+ const entries = fs34.readdirSync(projectPath, { withFileTypes: true });
15164
15227
  for (const entry of entries) {
15165
15228
  if (entry.isDirectory() && entry.name.startsWith("EP")) {
15166
- const worktreePath = path34.join(projectPath, entry.name);
15167
- const worktreeGit = path34.join(worktreePath, ".git");
15168
- if (fs33.existsSync(worktreeGit)) {
15229
+ const worktreePath = path35.join(projectPath, entry.name);
15230
+ const worktreeGit = path35.join(worktreePath, ".git");
15231
+ if (fs34.existsSync(worktreeGit)) {
15169
15232
  return { gitDir: null, workDir: worktreePath };
15170
15233
  }
15171
15234
  }
15172
15235
  }
15173
- if (fs33.existsSync(bareDir)) {
15236
+ if (fs34.existsSync(bareDir)) {
15174
15237
  return { gitDir: bareDir, workDir: projectPath };
15175
15238
  }
15176
15239
  return { gitDir: null, workDir: projectPath };
@@ -15215,24 +15278,24 @@ async function configureGitUser(projectPath, userId, workspaceId, machineId, pro
15215
15278
  async function installGitHooks(projectPath) {
15216
15279
  const hooks = ["post-checkout", "pre-commit", "post-commit"];
15217
15280
  let hooksDir;
15218
- const bareHooksDir = path34.join(projectPath, ".bare", "hooks");
15219
- const gitHooksDir = path34.join(projectPath, ".git", "hooks");
15220
- if (fs33.existsSync(bareHooksDir)) {
15281
+ const bareHooksDir = path35.join(projectPath, ".bare", "hooks");
15282
+ const gitHooksDir = path35.join(projectPath, ".git", "hooks");
15283
+ if (fs34.existsSync(bareHooksDir)) {
15221
15284
  hooksDir = bareHooksDir;
15222
- } else if (fs33.existsSync(gitHooksDir) && fs33.statSync(path34.join(projectPath, ".git")).isDirectory()) {
15285
+ } else if (fs34.existsSync(gitHooksDir) && fs34.statSync(path35.join(projectPath, ".git")).isDirectory()) {
15223
15286
  hooksDir = gitHooksDir;
15224
15287
  } else {
15225
- const parentBareHooks = path34.join(projectPath, "..", ".bare", "hooks");
15226
- if (fs33.existsSync(parentBareHooks)) {
15288
+ const parentBareHooks = path35.join(projectPath, "..", ".bare", "hooks");
15289
+ if (fs34.existsSync(parentBareHooks)) {
15227
15290
  hooksDir = parentBareHooks;
15228
15291
  } else {
15229
15292
  console.warn(`[Daemon] Hooks directory not found for: ${projectPath}`);
15230
15293
  return;
15231
15294
  }
15232
15295
  }
15233
- if (!fs33.existsSync(hooksDir)) {
15296
+ if (!fs34.existsSync(hooksDir)) {
15234
15297
  try {
15235
- fs33.mkdirSync(hooksDir, { recursive: true });
15298
+ fs34.mkdirSync(hooksDir, { recursive: true });
15236
15299
  } catch {
15237
15300
  console.warn(`[Daemon] Hooks directory not found and could not create: ${hooksDir}`);
15238
15301
  return;
@@ -15240,20 +15303,20 @@ async function installGitHooks(projectPath) {
15240
15303
  }
15241
15304
  for (const hookName of hooks) {
15242
15305
  try {
15243
- const hookPath = path34.join(hooksDir, hookName);
15244
- const bundledHookPath = path34.join(__dirname, "..", "hooks", hookName);
15245
- if (!fs33.existsSync(bundledHookPath)) {
15306
+ const hookPath = path35.join(hooksDir, hookName);
15307
+ const bundledHookPath = path35.join(__dirname, "..", "hooks", hookName);
15308
+ if (!fs34.existsSync(bundledHookPath)) {
15246
15309
  console.warn(`[Daemon] Bundled hook not found: ${bundledHookPath}`);
15247
15310
  continue;
15248
15311
  }
15249
- const hookContent = fs33.readFileSync(bundledHookPath, "utf-8");
15250
- if (fs33.existsSync(hookPath)) {
15251
- const existingContent = fs33.readFileSync(hookPath, "utf-8");
15312
+ const hookContent = fs34.readFileSync(bundledHookPath, "utf-8");
15313
+ if (fs34.existsSync(hookPath)) {
15314
+ const existingContent = fs34.readFileSync(hookPath, "utf-8");
15252
15315
  if (existingContent === hookContent) {
15253
15316
  continue;
15254
15317
  }
15255
15318
  }
15256
- fs33.writeFileSync(hookPath, hookContent, { mode: 493 });
15319
+ fs34.writeFileSync(hookPath, hookContent, { mode: 493 });
15257
15320
  console.log(`[Daemon] Installed git hook: ${hookName}`);
15258
15321
  } catch (error) {
15259
15322
  console.warn(`[Daemon] Failed to install ${hookName} hook:`, error instanceof Error ? error.message : error);
@@ -15284,21 +15347,21 @@ async function cacheMachineUuid(machineUuid, machineId) {
15284
15347
  }
15285
15348
 
15286
15349
  // src/daemon/reconciliation-utils.ts
15287
- var path35 = __toESM(require("path"));
15350
+ var path36 = __toESM(require("path"));
15288
15351
  function isPathUnderRoot(candidatePath, projectRoot) {
15289
- const relative4 = path35.relative(projectRoot, candidatePath);
15290
- return relative4 !== "" && !relative4.startsWith("..") && !path35.isAbsolute(relative4);
15352
+ const relative4 = path36.relative(projectRoot, candidatePath);
15353
+ return relative4 !== "" && !relative4.startsWith("..") && !path36.isAbsolute(relative4);
15291
15354
  }
15292
15355
  function collectUnexpectedWorktrees(params) {
15293
- const projectRootResolved = path35.resolve(params.projectRoot);
15294
- const bareRepoPathResolved = path35.resolve(params.bareRepoPath);
15356
+ const projectRootResolved = path36.resolve(params.projectRoot);
15357
+ const bareRepoPathResolved = path36.resolve(params.bareRepoPath);
15295
15358
  const unexpectedWorktrees = [];
15296
15359
  for (const worktree of params.worktrees) {
15297
- const worktreePathResolved = path35.resolve(worktree.path);
15360
+ const worktreePathResolved = path36.resolve(worktree.path);
15298
15361
  if (worktreePathResolved === bareRepoPathResolved) continue;
15299
15362
  if (worktree.prunable || worktree.locked) continue;
15300
15363
  if (!isPathUnderRoot(worktreePathResolved, projectRootResolved)) continue;
15301
- const moduleUid = path35.basename(worktreePathResolved);
15364
+ const moduleUid = path36.basename(worktreePathResolved);
15302
15365
  if (!validateModuleUid(moduleUid)) continue;
15303
15366
  if (!/^EP\d+$/.test(moduleUid)) continue;
15304
15367
  if (params.expectedModuleUids.has(moduleUid)) continue;
@@ -15515,9 +15578,9 @@ var Daemon = class _Daemon {
15515
15578
  this.healthServer = http2.createServer((req, res) => {
15516
15579
  if (req.url === "/health" || req.url === "/") {
15517
15580
  const isConnected = this.connectionManager.liveConnectionCount() > 0;
15518
- const projects = Array.from(this.connectionManager.entries()).map(([path37, conn]) => ({
15519
- path: path37,
15520
- connected: this.connectionManager.hasLiveConnection(path37)
15581
+ const projects = Array.from(this.connectionManager.entries()).map(([path38, conn]) => ({
15582
+ path: path38,
15583
+ connected: this.connectionManager.hasLiveConnection(path38)
15521
15584
  }));
15522
15585
  const status = {
15523
15586
  status: isConnected ? "healthy" : "degraded",
@@ -15590,8 +15653,8 @@ var Daemon = class _Daemon {
15590
15653
  await this.shutdown();
15591
15654
  try {
15592
15655
  const pidPath = getPidFilePath();
15593
- if (fs34.existsSync(pidPath)) {
15594
- fs34.unlinkSync(pidPath);
15656
+ if (fs35.existsSync(pidPath)) {
15657
+ fs35.unlinkSync(pidPath);
15595
15658
  console.log("[Daemon] PID file cleaned up (watchdog)");
15596
15659
  }
15597
15660
  } catch (error) {
@@ -16269,8 +16332,8 @@ var Daemon = class _Daemon {
16269
16332
  let daemonPid;
16270
16333
  try {
16271
16334
  const pidPath = getPidFilePath();
16272
- if (fs34.existsSync(pidPath)) {
16273
- const pidStr = fs34.readFileSync(pidPath, "utf-8").trim();
16335
+ if (fs35.existsSync(pidPath)) {
16336
+ const pidStr = fs35.readFileSync(pidPath, "utf-8").trim();
16274
16337
  daemonPid = parseInt(pidStr, 10);
16275
16338
  }
16276
16339
  } catch (pidError) {
@@ -16281,9 +16344,9 @@ var Daemon = class _Daemon {
16281
16344
  const containerId = process.env.EPISODA_CONTAINER_ID;
16282
16345
  const capabilities = ["worktree_create_v1"];
16283
16346
  await client.connect(wsEndpoint.wsUrl, config.access_token, this.machineId, {
16284
- hostname: os15.hostname(),
16285
- osPlatform: os15.platform(),
16286
- osArch: os15.arch(),
16347
+ hostname: os16.hostname(),
16348
+ osPlatform: os16.platform(),
16349
+ osArch: os16.arch(),
16287
16350
  daemonPid,
16288
16351
  cliVersion: this.cliRuntimeVersion,
16289
16352
  cliPackageName: packageJson.name,
@@ -16520,7 +16583,7 @@ var Daemon = class _Daemon {
16520
16583
  await tunnelManager.initialize();
16521
16584
  const moduleStatuses = [];
16522
16585
  const expectedModuleUids = new Set(modules.map((m) => m.uid));
16523
- const bareRepoPath = path36.join(projectPath, ".bare");
16586
+ const bareRepoPath = path37.join(projectPath, ".bare");
16524
16587
  for (const mod of modules) {
16525
16588
  const moduleUid = mod.uid;
16526
16589
  const worktree = await getWorktreeInfoForModule(moduleUid);
@@ -16963,8 +17026,8 @@ var Daemon = class _Daemon {
16963
17026
  await this.shutdown();
16964
17027
  try {
16965
17028
  const pidPath = getPidFilePath();
16966
- if (fs34.existsSync(pidPath)) {
16967
- fs34.unlinkSync(pidPath);
17029
+ if (fs35.existsSync(pidPath)) {
17030
+ fs35.unlinkSync(pidPath);
16968
17031
  console.log("[Daemon] PID file cleaned up");
16969
17032
  }
16970
17033
  } catch (error) {