episoda 0.2.105 → 0.2.106

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.
@@ -1571,15 +1571,15 @@ var require_git_executor = __commonJS({
1571
1571
  try {
1572
1572
  const { stdout: gitDir } = await execAsync3("git rev-parse --git-dir", { cwd, timeout: 5e3 });
1573
1573
  const gitDirPath = gitDir.trim();
1574
- const fs22 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1574
+ const fs23 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1575
1575
  const rebaseMergePath = `${gitDirPath}/rebase-merge`;
1576
1576
  const rebaseApplyPath = `${gitDirPath}/rebase-apply`;
1577
1577
  try {
1578
- await fs22.access(rebaseMergePath);
1578
+ await fs23.access(rebaseMergePath);
1579
1579
  inRebase = true;
1580
1580
  } catch {
1581
1581
  try {
1582
- await fs22.access(rebaseApplyPath);
1582
+ await fs23.access(rebaseApplyPath);
1583
1583
  inRebase = true;
1584
1584
  } catch {
1585
1585
  inRebase = false;
@@ -1633,9 +1633,9 @@ var require_git_executor = __commonJS({
1633
1633
  error: validation.error || "UNKNOWN_ERROR"
1634
1634
  };
1635
1635
  }
1636
- const fs22 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1636
+ const fs23 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1637
1637
  try {
1638
- await fs22.access(command.path);
1638
+ await fs23.access(command.path);
1639
1639
  return {
1640
1640
  success: false,
1641
1641
  error: "WORKTREE_EXISTS",
@@ -1689,9 +1689,9 @@ var require_git_executor = __commonJS({
1689
1689
  */
1690
1690
  async executeWorktreeRemove(command, cwd, options) {
1691
1691
  try {
1692
- const fs22 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1692
+ const fs23 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1693
1693
  try {
1694
- await fs22.access(command.path);
1694
+ await fs23.access(command.path);
1695
1695
  } catch {
1696
1696
  return {
1697
1697
  success: false,
@@ -1726,7 +1726,7 @@ var require_git_executor = __commonJS({
1726
1726
  const result = await this.runGitCommand(args, cwd, options);
1727
1727
  if (result.success) {
1728
1728
  try {
1729
- await fs22.rm(command.path, { recursive: true, force: true });
1729
+ await fs23.rm(command.path, { recursive: true, force: true });
1730
1730
  } catch {
1731
1731
  }
1732
1732
  return {
@@ -1860,10 +1860,10 @@ var require_git_executor = __commonJS({
1860
1860
  */
1861
1861
  async executeCloneBare(command, options) {
1862
1862
  try {
1863
- const fs22 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1864
- const path23 = await Promise.resolve().then(() => __importStar(require("path")));
1863
+ const fs23 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1864
+ const path24 = await Promise.resolve().then(() => __importStar(require("path")));
1865
1865
  try {
1866
- await fs22.access(command.path);
1866
+ await fs23.access(command.path);
1867
1867
  return {
1868
1868
  success: false,
1869
1869
  error: "BRANCH_ALREADY_EXISTS",
@@ -1872,9 +1872,9 @@ var require_git_executor = __commonJS({
1872
1872
  };
1873
1873
  } catch {
1874
1874
  }
1875
- const parentDir = path23.dirname(command.path);
1875
+ const parentDir = path24.dirname(command.path);
1876
1876
  try {
1877
- await fs22.mkdir(parentDir, { recursive: true });
1877
+ await fs23.mkdir(parentDir, { recursive: true });
1878
1878
  } catch {
1879
1879
  }
1880
1880
  const { stdout, stderr } = await execAsync3(
@@ -1922,22 +1922,22 @@ var require_git_executor = __commonJS({
1922
1922
  */
1923
1923
  async executeProjectInfo(cwd, options) {
1924
1924
  try {
1925
- const fs22 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1926
- const path23 = await Promise.resolve().then(() => __importStar(require("path")));
1925
+ const fs23 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1926
+ const path24 = await Promise.resolve().then(() => __importStar(require("path")));
1927
1927
  let currentPath = cwd;
1928
1928
  let projectPath = cwd;
1929
1929
  let bareRepoPath;
1930
1930
  for (let i = 0; i < 10; i++) {
1931
- const bareDir = path23.join(currentPath, ".bare");
1932
- const episodaDir = path23.join(currentPath, ".episoda");
1931
+ const bareDir = path24.join(currentPath, ".bare");
1932
+ const episodaDir = path24.join(currentPath, ".episoda");
1933
1933
  try {
1934
- await fs22.access(bareDir);
1935
- await fs22.access(episodaDir);
1934
+ await fs23.access(bareDir);
1935
+ await fs23.access(episodaDir);
1936
1936
  projectPath = currentPath;
1937
1937
  bareRepoPath = bareDir;
1938
1938
  break;
1939
1939
  } catch {
1940
- const parentPath = path23.dirname(currentPath);
1940
+ const parentPath = path24.dirname(currentPath);
1941
1941
  if (parentPath === currentPath) {
1942
1942
  break;
1943
1943
  }
@@ -2590,31 +2590,31 @@ var require_auth = __commonJS({
2590
2590
  exports2.loadConfig = loadConfig8;
2591
2591
  exports2.saveConfig = saveConfig2;
2592
2592
  exports2.validateToken = validateToken;
2593
- var fs22 = __importStar(require("fs"));
2594
- var path23 = __importStar(require("path"));
2593
+ var fs23 = __importStar(require("fs"));
2594
+ var path24 = __importStar(require("path"));
2595
2595
  var os9 = __importStar(require("os"));
2596
2596
  var child_process_1 = require("child_process");
2597
2597
  var DEFAULT_CONFIG_FILE = "config.json";
2598
2598
  function getConfigDir8() {
2599
- return process.env.EPISODA_CONFIG_DIR || path23.join(os9.homedir(), ".episoda");
2599
+ return process.env.EPISODA_CONFIG_DIR || path24.join(os9.homedir(), ".episoda");
2600
2600
  }
2601
2601
  function getConfigPath(configPath) {
2602
2602
  if (configPath) {
2603
2603
  return configPath;
2604
2604
  }
2605
- return path23.join(getConfigDir8(), DEFAULT_CONFIG_FILE);
2605
+ return path24.join(getConfigDir8(), DEFAULT_CONFIG_FILE);
2606
2606
  }
2607
2607
  function ensureConfigDir(configPath) {
2608
- const dir = path23.dirname(configPath);
2609
- const isNew = !fs22.existsSync(dir);
2608
+ const dir = path24.dirname(configPath);
2609
+ const isNew = !fs23.existsSync(dir);
2610
2610
  if (isNew) {
2611
- fs22.mkdirSync(dir, { recursive: true, mode: 448 });
2611
+ fs23.mkdirSync(dir, { recursive: true, mode: 448 });
2612
2612
  }
2613
2613
  if (process.platform === "darwin") {
2614
- const nosyncPath = path23.join(dir, ".nosync");
2615
- if (isNew || !fs22.existsSync(nosyncPath)) {
2614
+ const nosyncPath = path24.join(dir, ".nosync");
2615
+ if (isNew || !fs23.existsSync(nosyncPath)) {
2616
2616
  try {
2617
- fs22.writeFileSync(nosyncPath, "", { mode: 384 });
2617
+ fs23.writeFileSync(nosyncPath, "", { mode: 384 });
2618
2618
  (0, child_process_1.execSync)(`xattr -w com.apple.fileprovider.ignore 1 "${dir}"`, {
2619
2619
  stdio: "ignore",
2620
2620
  timeout: 5e3
@@ -2626,9 +2626,9 @@ var require_auth = __commonJS({
2626
2626
  }
2627
2627
  async function loadConfig8(configPath) {
2628
2628
  const fullPath = getConfigPath(configPath);
2629
- if (fs22.existsSync(fullPath)) {
2629
+ if (fs23.existsSync(fullPath)) {
2630
2630
  try {
2631
- const content = fs22.readFileSync(fullPath, "utf8");
2631
+ const content = fs23.readFileSync(fullPath, "utf8");
2632
2632
  const config = JSON.parse(content);
2633
2633
  return config;
2634
2634
  } catch (error) {
@@ -2638,9 +2638,9 @@ var require_auth = __commonJS({
2638
2638
  if (process.env.EPISODA_MODE === "cloud" && process.env.EPISODA_WORKSPACE) {
2639
2639
  const homeDir = process.env.HOME || require("os").homedir();
2640
2640
  const workspaceConfigPath = require("path").join(homeDir, "episoda", process.env.EPISODA_WORKSPACE, ".episoda", "config.json");
2641
- if (fs22.existsSync(workspaceConfigPath)) {
2641
+ if (fs23.existsSync(workspaceConfigPath)) {
2642
2642
  try {
2643
- const content = fs22.readFileSync(workspaceConfigPath, "utf8");
2643
+ const content = fs23.readFileSync(workspaceConfigPath, "utf8");
2644
2644
  const workspaceConfig = JSON.parse(content);
2645
2645
  return {
2646
2646
  access_token: process.env.EPISODA_ACCESS_TOKEN || workspaceConfig.accessToken,
@@ -2687,7 +2687,7 @@ var require_auth = __commonJS({
2687
2687
  ensureConfigDir(fullPath);
2688
2688
  try {
2689
2689
  const content = JSON.stringify(config, null, 2);
2690
- fs22.writeFileSync(fullPath, content, { mode: 384 });
2690
+ fs23.writeFileSync(fullPath, content, { mode: 384 });
2691
2691
  } catch (error) {
2692
2692
  throw new Error(`Failed to save config: ${error instanceof Error ? error.message : String(error)}`);
2693
2693
  }
@@ -2804,7 +2804,7 @@ var require_package = __commonJS({
2804
2804
  "package.json"(exports2, module2) {
2805
2805
  module2.exports = {
2806
2806
  name: "episoda",
2807
- version: "0.2.105",
2807
+ version: "0.2.106",
2808
2808
  description: "CLI tool for Episoda local development workflow orchestration",
2809
2809
  main: "dist/index.js",
2810
2810
  types: "dist/index.d.ts",
@@ -4781,7 +4781,13 @@ var WorktreeManager = class _WorktreeManager {
4781
4781
  }
4782
4782
  };
4783
4783
  function getEpisodaRoot() {
4784
- return process.env.EPISODA_ROOT || path7.join(require("os").homedir(), "episoda");
4784
+ if (process.env.EPISODA_ROOT) {
4785
+ return process.env.EPISODA_ROOT;
4786
+ }
4787
+ if (process.env.EPISODA_MODE === "cloud") {
4788
+ return process.env.HOME || "/home/episoda";
4789
+ }
4790
+ return path7.join(require("os").homedir(), "episoda");
4785
4791
  }
4786
4792
  function getProjectPath(workspaceSlug, projectSlug) {
4787
4793
  return path7.join(getEpisodaRoot(), workspaceSlug, projectSlug);
@@ -7730,6 +7736,85 @@ async function persistArtifactsBeforeEject(artifactsPath, projectId, projectSlug
7730
7736
  }
7731
7737
  }
7732
7738
 
7739
+ // src/daemon/handlers/project-handlers.ts
7740
+ var path16 = __toESM(require("path"));
7741
+ var fs15 = __toESM(require("fs"));
7742
+ function validateSlug(slug, fieldName) {
7743
+ if (!slug || typeof slug !== "string") {
7744
+ return `${fieldName} is required`;
7745
+ }
7746
+ const trimmed = slug.trim();
7747
+ if (!trimmed) {
7748
+ return `${fieldName} cannot be empty`;
7749
+ }
7750
+ if (trimmed.includes("..") || trimmed.includes("/") || trimmed.includes("\\")) {
7751
+ return `${fieldName} contains invalid characters`;
7752
+ }
7753
+ if (trimmed.includes("\0")) {
7754
+ return `${fieldName} contains invalid characters`;
7755
+ }
7756
+ if (trimmed.startsWith(".")) {
7757
+ return `${fieldName} cannot start with a dot`;
7758
+ }
7759
+ return null;
7760
+ }
7761
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7762
+ async function handleProjectSetup(params) {
7763
+ const { workspaceSlug, projectSlug, projectId } = params;
7764
+ const workspaceError = validateSlug(workspaceSlug, "workspaceSlug");
7765
+ if (workspaceError) {
7766
+ console.error(`[ProjectSetup] EP1199: Validation failed: ${workspaceError}`);
7767
+ return { success: false, error: workspaceError };
7768
+ }
7769
+ const projectError = validateSlug(projectSlug, "projectSlug");
7770
+ if (projectError) {
7771
+ console.error(`[ProjectSetup] EP1199: Validation failed: ${projectError}`);
7772
+ return { success: false, error: projectError };
7773
+ }
7774
+ if (!UUID_REGEX.test(projectId)) {
7775
+ console.error(`[ProjectSetup] EP1199: Invalid projectId format: ${projectId}`);
7776
+ return { success: false, error: "Invalid projectId format" };
7777
+ }
7778
+ console.log(`[ProjectSetup] EP1199: Setting up project ${workspaceSlug}/${projectSlug}`);
7779
+ try {
7780
+ const projectPath = getProjectPath(workspaceSlug, projectSlug);
7781
+ const artifactsPath = path16.join(projectPath, "artifacts");
7782
+ const configDir = path16.join(projectPath, ".episoda");
7783
+ const configPath = path16.join(configDir, "config.json");
7784
+ await fs15.promises.mkdir(artifactsPath, { recursive: true });
7785
+ await fs15.promises.mkdir(configDir, { recursive: true });
7786
+ let existingConfig = {};
7787
+ try {
7788
+ const existing = await fs15.promises.readFile(configPath, "utf-8");
7789
+ existingConfig = JSON.parse(existing);
7790
+ } catch {
7791
+ }
7792
+ const config = {
7793
+ ...existingConfig,
7794
+ project_id: projectId,
7795
+ workspace_slug: workspaceSlug,
7796
+ project_slug: projectSlug,
7797
+ updated_at: (/* @__PURE__ */ new Date()).toISOString(),
7798
+ // Only set created_at if not already present
7799
+ created_at: existingConfig.created_at || (/* @__PURE__ */ new Date()).toISOString()
7800
+ };
7801
+ await fs15.promises.writeFile(configPath, JSON.stringify(config, null, 2));
7802
+ console.log(`[ProjectSetup] EP1199: Project setup complete at ${projectPath}`);
7803
+ return {
7804
+ success: true,
7805
+ projectPath,
7806
+ artifactsPath
7807
+ };
7808
+ } catch (error) {
7809
+ const errorMessage = error instanceof Error ? error.message : String(error);
7810
+ console.error(`[ProjectSetup] EP1199: Setup failed:`, errorMessage);
7811
+ return {
7812
+ success: false,
7813
+ error: errorMessage
7814
+ };
7815
+ }
7816
+ }
7817
+
7733
7818
  // src/daemon/handlers/stale-commit-cleanup.ts
7734
7819
  var import_child_process9 = require("child_process");
7735
7820
  var import_util2 = require("util");
@@ -7827,12 +7912,12 @@ async function cleanupStaleCommits(projectPath) {
7827
7912
 
7828
7913
  // src/agent/claude-binary.ts
7829
7914
  var import_child_process10 = require("child_process");
7830
- var path16 = __toESM(require("path"));
7831
- var fs15 = __toESM(require("fs"));
7915
+ var path17 = __toESM(require("path"));
7916
+ var fs16 = __toESM(require("fs"));
7832
7917
  var cachedBinaryPath = null;
7833
7918
  function isValidClaudeBinary(binaryPath) {
7834
7919
  try {
7835
- fs15.accessSync(binaryPath, fs15.constants.X_OK);
7920
+ fs16.accessSync(binaryPath, fs16.constants.X_OK);
7836
7921
  const version = (0, import_child_process10.execSync)(`"${binaryPath}" --version`, {
7837
7922
  encoding: "utf-8",
7838
7923
  timeout: 5e3,
@@ -7865,14 +7950,14 @@ async function ensureClaudeBinary() {
7865
7950
  }
7866
7951
  const bundledPaths = [
7867
7952
  // In production: node_modules/.bin/claude
7868
- path16.join(__dirname, "..", "..", "node_modules", ".bin", "claude"),
7953
+ path17.join(__dirname, "..", "..", "node_modules", ".bin", "claude"),
7869
7954
  // In monorepo development: packages/episoda/node_modules/.bin/claude
7870
- path16.join(__dirname, "..", "..", "..", "..", "node_modules", ".bin", "claude"),
7955
+ path17.join(__dirname, "..", "..", "..", "..", "node_modules", ".bin", "claude"),
7871
7956
  // Root monorepo node_modules
7872
- path16.join(__dirname, "..", "..", "..", "..", "..", "node_modules", ".bin", "claude")
7957
+ path17.join(__dirname, "..", "..", "..", "..", "..", "node_modules", ".bin", "claude")
7873
7958
  ];
7874
7959
  for (const bundledPath of bundledPaths) {
7875
- if (fs15.existsSync(bundledPath) && isValidClaudeBinary(bundledPath)) {
7960
+ if (fs16.existsSync(bundledPath) && isValidClaudeBinary(bundledPath)) {
7876
7961
  cachedBinaryPath = bundledPath;
7877
7962
  return cachedBinaryPath;
7878
7963
  }
@@ -7898,12 +7983,12 @@ async function ensureClaudeBinary() {
7898
7983
 
7899
7984
  // src/agent/codex-binary.ts
7900
7985
  var import_child_process11 = require("child_process");
7901
- var path17 = __toESM(require("path"));
7902
- var fs16 = __toESM(require("fs"));
7986
+ var path18 = __toESM(require("path"));
7987
+ var fs17 = __toESM(require("fs"));
7903
7988
  var cachedBinaryPath2 = null;
7904
7989
  function isValidCodexBinary(binaryPath) {
7905
7990
  try {
7906
- fs16.accessSync(binaryPath, fs16.constants.X_OK);
7991
+ fs17.accessSync(binaryPath, fs17.constants.X_OK);
7907
7992
  const version = (0, import_child_process11.execSync)(`"${binaryPath}" --version`, {
7908
7993
  encoding: "utf-8",
7909
7994
  timeout: 5e3,
@@ -7936,14 +8021,14 @@ async function ensureCodexBinary() {
7936
8021
  }
7937
8022
  const bundledPaths = [
7938
8023
  // In production: node_modules/.bin/codex
7939
- path17.join(__dirname, "..", "..", "node_modules", ".bin", "codex"),
8024
+ path18.join(__dirname, "..", "..", "node_modules", ".bin", "codex"),
7940
8025
  // In monorepo development: packages/episoda/node_modules/.bin/codex
7941
- path17.join(__dirname, "..", "..", "..", "..", "node_modules", ".bin", "codex"),
8026
+ path18.join(__dirname, "..", "..", "..", "..", "node_modules", ".bin", "codex"),
7942
8027
  // Root monorepo node_modules
7943
- path17.join(__dirname, "..", "..", "..", "..", "..", "node_modules", ".bin", "codex")
8028
+ path18.join(__dirname, "..", "..", "..", "..", "..", "node_modules", ".bin", "codex")
7944
8029
  ];
7945
8030
  for (const bundledPath of bundledPaths) {
7946
- if (fs16.existsSync(bundledPath) && isValidCodexBinary(bundledPath)) {
8031
+ if (fs17.existsSync(bundledPath) && isValidCodexBinary(bundledPath)) {
7947
8032
  cachedBinaryPath2 = bundledPath;
7948
8033
  return cachedBinaryPath2;
7949
8034
  }
@@ -8010,8 +8095,8 @@ function generateCodexConfig(credentials, projectPath) {
8010
8095
 
8011
8096
  // src/agent/agent-manager.ts
8012
8097
  var import_child_process12 = require("child_process");
8013
- var path18 = __toESM(require("path"));
8014
- var fs17 = __toESM(require("fs"));
8098
+ var path19 = __toESM(require("path"));
8099
+ var fs18 = __toESM(require("fs"));
8015
8100
  var os6 = __toESM(require("os"));
8016
8101
 
8017
8102
  // src/agent/claude-config.ts
@@ -8334,7 +8419,7 @@ var AgentManager = class {
8334
8419
  this.initialized = false;
8335
8420
  // EP1133: Lock for config file writes to prevent race conditions
8336
8421
  this.configWriteLock = Promise.resolve();
8337
- this.pidDir = path18.join(os6.homedir(), ".episoda", "agent-pids");
8422
+ this.pidDir = path19.join(os6.homedir(), ".episoda", "agent-pids");
8338
8423
  }
8339
8424
  /**
8340
8425
  * EP1133: Acquire lock for config file writes
@@ -8363,8 +8448,8 @@ var AgentManager = class {
8363
8448
  return;
8364
8449
  }
8365
8450
  console.log("[AgentManager] Initializing...");
8366
- if (!fs17.existsSync(this.pidDir)) {
8367
- fs17.mkdirSync(this.pidDir, { recursive: true });
8451
+ if (!fs18.existsSync(this.pidDir)) {
8452
+ fs18.mkdirSync(this.pidDir, { recursive: true });
8368
8453
  }
8369
8454
  await this.cleanupOrphanedProcesses();
8370
8455
  try {
@@ -8611,9 +8696,9 @@ If changes are needed, explain what needs to be done.`;
8611
8696
  const useApiKey = !useOAuth && !!session.credentials.apiKey;
8612
8697
  if (provider === "codex") {
8613
8698
  await this.withConfigLock(async () => {
8614
- const codexDir = path18.join(os6.homedir(), ".codex");
8615
- if (!fs17.existsSync(codexDir)) {
8616
- fs17.mkdirSync(codexDir, { recursive: true });
8699
+ const codexDir = path19.join(os6.homedir(), ".codex");
8700
+ if (!fs18.existsSync(codexDir)) {
8701
+ fs18.mkdirSync(codexDir, { recursive: true });
8617
8702
  }
8618
8703
  if (useOAuth) {
8619
8704
  const codexConfig = generateCodexConfig({
@@ -8623,21 +8708,21 @@ If changes are needed, explain what needs to be done.`;
8623
8708
  accountId: session.credentials.accountId,
8624
8709
  expiresAt: session.credentials.expiresAt
8625
8710
  }, session.projectPath);
8626
- const authJsonPath = path18.join(codexDir, "auth.json");
8627
- fs17.writeFileSync(authJsonPath, codexConfig["auth.json"], { mode: 384 });
8711
+ const authJsonPath = path19.join(codexDir, "auth.json");
8712
+ fs18.writeFileSync(authJsonPath, codexConfig["auth.json"], { mode: 384 });
8628
8713
  console.log("[AgentManager] EP1133: Wrote Codex auth.json to ~/.codex/auth.json");
8629
8714
  if (codexConfig["config.toml"]) {
8630
- const configTomlPath = path18.join(codexDir, "config.toml");
8715
+ const configTomlPath = path19.join(codexDir, "config.toml");
8631
8716
  let existingConfig = "";
8632
8717
  try {
8633
- existingConfig = fs17.readFileSync(configTomlPath, "utf-8");
8718
+ existingConfig = fs18.readFileSync(configTomlPath, "utf-8");
8634
8719
  } catch {
8635
8720
  }
8636
8721
  const escapedPathForRegex = session.projectPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8637
8722
  const projectKeyPattern = new RegExp(`\\[projects\\."${escapedPathForRegex}"\\]`);
8638
8723
  const projectAlreadyTrusted = projectKeyPattern.test(existingConfig);
8639
8724
  if (!projectAlreadyTrusted) {
8640
- fs17.writeFileSync(configTomlPath, existingConfig + "\n" + codexConfig["config.toml"], { mode: 420 });
8725
+ fs18.writeFileSync(configTomlPath, existingConfig + "\n" + codexConfig["config.toml"], { mode: 420 });
8641
8726
  console.log("[AgentManager] EP1133: Updated Codex config.toml with project trust");
8642
8727
  }
8643
8728
  }
@@ -8647,14 +8732,14 @@ If changes are needed, explain what needs to be done.`;
8647
8732
  });
8648
8733
  } else {
8649
8734
  await this.withConfigLock(async () => {
8650
- const claudeDir = path18.join(os6.homedir(), ".claude");
8651
- const credentialsPath = path18.join(claudeDir, ".credentials.json");
8652
- const statsigDir = path18.join(claudeDir, "statsig");
8653
- if (!fs17.existsSync(claudeDir)) {
8654
- fs17.mkdirSync(claudeDir, { recursive: true });
8735
+ const claudeDir = path19.join(os6.homedir(), ".claude");
8736
+ const credentialsPath = path19.join(claudeDir, ".credentials.json");
8737
+ const statsigDir = path19.join(claudeDir, "statsig");
8738
+ if (!fs18.existsSync(claudeDir)) {
8739
+ fs18.mkdirSync(claudeDir, { recursive: true });
8655
8740
  }
8656
- if (!fs17.existsSync(statsigDir)) {
8657
- fs17.mkdirSync(statsigDir, { recursive: true });
8741
+ if (!fs18.existsSync(statsigDir)) {
8742
+ fs18.mkdirSync(statsigDir, { recursive: true });
8658
8743
  }
8659
8744
  if (useOAuth) {
8660
8745
  const oauthCredentials = {
@@ -8672,7 +8757,7 @@ If changes are needed, explain what needs to be done.`;
8672
8757
  const credentialsContent = JSON.stringify({
8673
8758
  claudeAiOauth: oauthCredentials
8674
8759
  }, null, 2);
8675
- fs17.writeFileSync(credentialsPath, credentialsContent, { mode: 384 });
8760
+ fs18.writeFileSync(credentialsPath, credentialsContent, { mode: 384 });
8676
8761
  console.log("[AgentManager] Wrote OAuth credentials to ~/.claude/.credentials.json");
8677
8762
  try {
8678
8763
  const claudeConfig = generateClaudeConfig({
@@ -8684,11 +8769,11 @@ If changes are needed, explain what needs to be done.`;
8684
8769
  if (!hasEvaluations || !hasStableId) {
8685
8770
  throw new Error(`Invalid statsig config: missing required files`);
8686
8771
  }
8687
- const settingsPath = path18.join(claudeDir, "settings.json");
8688
- fs17.writeFileSync(settingsPath, claudeConfig["settings.json"], { mode: 384 });
8772
+ const settingsPath = path19.join(claudeDir, "settings.json");
8773
+ fs18.writeFileSync(settingsPath, claudeConfig["settings.json"], { mode: 384 });
8689
8774
  for (const [filename, content] of Object.entries(claudeConfig.statsig)) {
8690
- const filePath = path18.join(statsigDir, filename);
8691
- fs17.writeFileSync(filePath, content, { mode: 420 });
8775
+ const filePath = path19.join(statsigDir, filename);
8776
+ fs18.writeFileSync(filePath, content, { mode: 420 });
8692
8777
  }
8693
8778
  if (session.credentials.githubToken) {
8694
8779
  console.log("[AgentManager] EP1146: GitHub MCP server enabled with installation token");
@@ -8958,14 +9043,14 @@ If changes are needed, explain what needs to be done.`;
8958
9043
  */
8959
9044
  async cleanupOrphanedProcesses() {
8960
9045
  let cleaned = 0;
8961
- if (!fs17.existsSync(this.pidDir)) {
9046
+ if (!fs18.existsSync(this.pidDir)) {
8962
9047
  return { cleaned };
8963
9048
  }
8964
- const pidFiles = fs17.readdirSync(this.pidDir).filter((f) => f.endsWith(".pid"));
9049
+ const pidFiles = fs18.readdirSync(this.pidDir).filter((f) => f.endsWith(".pid"));
8965
9050
  for (const pidFile of pidFiles) {
8966
- const pidPath = path18.join(this.pidDir, pidFile);
9051
+ const pidPath = path19.join(this.pidDir, pidFile);
8967
9052
  try {
8968
- const pidStr = fs17.readFileSync(pidPath, "utf-8").trim();
9053
+ const pidStr = fs18.readFileSync(pidPath, "utf-8").trim();
8969
9054
  const pid = parseInt(pidStr, 10);
8970
9055
  if (!isNaN(pid)) {
8971
9056
  try {
@@ -8976,7 +9061,7 @@ If changes are needed, explain what needs to be done.`;
8976
9061
  } catch {
8977
9062
  }
8978
9063
  }
8979
- fs17.unlinkSync(pidPath);
9064
+ fs18.unlinkSync(pidPath);
8980
9065
  } catch (error) {
8981
9066
  console.warn(`[AgentManager] Error cleaning PID file ${pidFile}:`, error);
8982
9067
  }
@@ -8990,17 +9075,17 @@ If changes are needed, explain what needs to be done.`;
8990
9075
  * Write PID file for session tracking
8991
9076
  */
8992
9077
  writePidFile(sessionId, pid) {
8993
- const pidPath = path18.join(this.pidDir, `${sessionId}.pid`);
8994
- fs17.writeFileSync(pidPath, pid.toString());
9078
+ const pidPath = path19.join(this.pidDir, `${sessionId}.pid`);
9079
+ fs18.writeFileSync(pidPath, pid.toString());
8995
9080
  }
8996
9081
  /**
8997
9082
  * Remove PID file for session
8998
9083
  */
8999
9084
  removePidFile(sessionId) {
9000
- const pidPath = path18.join(this.pidDir, `${sessionId}.pid`);
9085
+ const pidPath = path19.join(this.pidDir, `${sessionId}.pid`);
9001
9086
  try {
9002
- if (fs17.existsSync(pidPath)) {
9003
- fs17.unlinkSync(pidPath);
9087
+ if (fs18.existsSync(pidPath)) {
9088
+ fs18.unlinkSync(pidPath);
9004
9089
  }
9005
9090
  } catch {
9006
9091
  }
@@ -9010,8 +9095,8 @@ If changes are needed, explain what needs to be done.`;
9010
9095
  // src/utils/dev-server.ts
9011
9096
  var import_child_process13 = require("child_process");
9012
9097
  var import_core11 = __toESM(require_dist());
9013
- var fs18 = __toESM(require("fs"));
9014
- var path19 = __toESM(require("path"));
9098
+ var fs19 = __toESM(require("fs"));
9099
+ var path20 = __toESM(require("path"));
9015
9100
  var MAX_RESTART_ATTEMPTS = 5;
9016
9101
  var INITIAL_RESTART_DELAY_MS = 2e3;
9017
9102
  var MAX_RESTART_DELAY_MS = 3e4;
@@ -9019,26 +9104,26 @@ var MAX_LOG_SIZE_BYTES = 5 * 1024 * 1024;
9019
9104
  var NODE_MEMORY_LIMIT_MB = 2048;
9020
9105
  var activeServers = /* @__PURE__ */ new Map();
9021
9106
  function getLogsDir() {
9022
- const logsDir = path19.join((0, import_core11.getConfigDir)(), "logs");
9023
- if (!fs18.existsSync(logsDir)) {
9024
- fs18.mkdirSync(logsDir, { recursive: true });
9107
+ const logsDir = path20.join((0, import_core11.getConfigDir)(), "logs");
9108
+ if (!fs19.existsSync(logsDir)) {
9109
+ fs19.mkdirSync(logsDir, { recursive: true });
9025
9110
  }
9026
9111
  return logsDir;
9027
9112
  }
9028
9113
  function getLogFilePath(moduleUid) {
9029
- return path19.join(getLogsDir(), `dev-${moduleUid}.log`);
9114
+ return path20.join(getLogsDir(), `dev-${moduleUid}.log`);
9030
9115
  }
9031
9116
  function rotateLogIfNeeded(logPath) {
9032
9117
  try {
9033
- if (fs18.existsSync(logPath)) {
9034
- const stats = fs18.statSync(logPath);
9118
+ if (fs19.existsSync(logPath)) {
9119
+ const stats = fs19.statSync(logPath);
9035
9120
  if (stats.size > MAX_LOG_SIZE_BYTES) {
9036
9121
  const backupPath = `${logPath}.1`;
9037
- if (fs18.existsSync(backupPath)) {
9038
- fs18.unlinkSync(backupPath);
9122
+ if (fs19.existsSync(backupPath)) {
9123
+ fs19.unlinkSync(backupPath);
9039
9124
  }
9040
- fs18.renameSync(logPath, backupPath);
9041
- console.log(`[DevServer] EP932: Rotated log file for ${path19.basename(logPath)}`);
9125
+ fs19.renameSync(logPath, backupPath);
9126
+ console.log(`[DevServer] EP932: Rotated log file for ${path20.basename(logPath)}`);
9042
9127
  }
9043
9128
  }
9044
9129
  } catch (error) {
@@ -9051,7 +9136,7 @@ function writeToLog(logPath, line, isError = false) {
9051
9136
  const prefix = isError ? "ERR" : "OUT";
9052
9137
  const logLine = `[${timestamp}] [${prefix}] ${line}
9053
9138
  `;
9054
- fs18.appendFileSync(logPath, logLine);
9139
+ fs19.appendFileSync(logPath, logLine);
9055
9140
  } catch {
9056
9141
  }
9057
9142
  }
@@ -9230,8 +9315,8 @@ async function startDevServer(projectPath, port = 3e3, moduleUid = "default", op
9230
9315
  });
9231
9316
  injectedEnvVars = result.envVars;
9232
9317
  console.log(`[DevServer] EP998: Loaded ${Object.keys(injectedEnvVars).length} env vars (from ${result.fromCache ? "cache" : "server"})`);
9233
- const envFilePath = path19.join(projectPath, ".env");
9234
- if (!fs18.existsSync(envFilePath) && Object.keys(injectedEnvVars).length > 0) {
9318
+ const envFilePath = path20.join(projectPath, ".env");
9319
+ if (!fs19.existsSync(envFilePath) && Object.keys(injectedEnvVars).length > 0) {
9235
9320
  console.log(`[DevServer] EP1004: .env file missing, writing ${Object.keys(injectedEnvVars).length} vars to ${envFilePath}`);
9236
9321
  writeEnvFile(projectPath, injectedEnvVars);
9237
9322
  }
@@ -9337,19 +9422,19 @@ function getDevServerStatus() {
9337
9422
  }
9338
9423
 
9339
9424
  // src/utils/worktree.ts
9340
- var path20 = __toESM(require("path"));
9341
- var fs19 = __toESM(require("fs"));
9425
+ var path21 = __toESM(require("path"));
9426
+ var fs20 = __toESM(require("fs"));
9342
9427
  var os7 = __toESM(require("os"));
9343
9428
  var import_core12 = __toESM(require_dist());
9344
9429
  function getEpisodaRoot2() {
9345
- return process.env.EPISODA_ROOT || path20.join(os7.homedir(), "episoda");
9430
+ return process.env.EPISODA_ROOT || path21.join(os7.homedir(), "episoda");
9346
9431
  }
9347
9432
  function getWorktreeInfo(moduleUid, workspaceSlug, projectSlug) {
9348
9433
  const root = getEpisodaRoot2();
9349
- const worktreePath = path20.join(root, workspaceSlug, projectSlug, moduleUid);
9434
+ const worktreePath = path21.join(root, workspaceSlug, projectSlug, moduleUid);
9350
9435
  return {
9351
9436
  path: worktreePath,
9352
- exists: fs19.existsSync(worktreePath),
9437
+ exists: fs20.existsSync(worktreePath),
9353
9438
  moduleUid
9354
9439
  };
9355
9440
  }
@@ -9363,15 +9448,15 @@ async function getWorktreeInfoForModule(moduleUid) {
9363
9448
  return null;
9364
9449
  }
9365
9450
  const root = getEpisodaRoot2();
9366
- const workspaceRoot = path20.join(root, config.workspace_slug);
9451
+ const workspaceRoot = path21.join(root, config.workspace_slug);
9367
9452
  try {
9368
- const entries = fs19.readdirSync(workspaceRoot, { withFileTypes: true });
9453
+ const entries = fs20.readdirSync(workspaceRoot, { withFileTypes: true });
9369
9454
  for (const entry of entries) {
9370
9455
  if (!entry.isDirectory()) {
9371
9456
  continue;
9372
9457
  }
9373
- const worktreePath = path20.join(workspaceRoot, entry.name, moduleUid);
9374
- if (fs19.existsSync(worktreePath)) {
9458
+ const worktreePath = path21.join(workspaceRoot, entry.name, moduleUid);
9459
+ if (fs20.existsSync(worktreePath)) {
9375
9460
  return {
9376
9461
  path: worktreePath,
9377
9462
  exists: true,
@@ -9388,61 +9473,61 @@ async function getWorktreeInfoForModule(moduleUid) {
9388
9473
  }
9389
9474
 
9390
9475
  // src/framework-detector.ts
9391
- var fs20 = __toESM(require("fs"));
9392
- var path21 = __toESM(require("path"));
9476
+ var fs21 = __toESM(require("fs"));
9477
+ var path22 = __toESM(require("path"));
9393
9478
  function getInstallCommand(cwd) {
9394
- if (fs20.existsSync(path21.join(cwd, "bun.lockb"))) {
9479
+ if (fs21.existsSync(path22.join(cwd, "bun.lockb"))) {
9395
9480
  return {
9396
9481
  command: ["bun", "install"],
9397
9482
  description: "Installing dependencies with bun",
9398
9483
  detectedFrom: "bun.lockb"
9399
9484
  };
9400
9485
  }
9401
- if (fs20.existsSync(path21.join(cwd, "pnpm-lock.yaml"))) {
9486
+ if (fs21.existsSync(path22.join(cwd, "pnpm-lock.yaml"))) {
9402
9487
  return {
9403
9488
  command: ["pnpm", "install"],
9404
9489
  description: "Installing dependencies with pnpm",
9405
9490
  detectedFrom: "pnpm-lock.yaml"
9406
9491
  };
9407
9492
  }
9408
- if (fs20.existsSync(path21.join(cwd, "yarn.lock"))) {
9493
+ if (fs21.existsSync(path22.join(cwd, "yarn.lock"))) {
9409
9494
  return {
9410
9495
  command: ["yarn", "install"],
9411
9496
  description: "Installing dependencies with yarn",
9412
9497
  detectedFrom: "yarn.lock"
9413
9498
  };
9414
9499
  }
9415
- if (fs20.existsSync(path21.join(cwd, "package-lock.json"))) {
9500
+ if (fs21.existsSync(path22.join(cwd, "package-lock.json"))) {
9416
9501
  return {
9417
9502
  command: ["npm", "ci"],
9418
9503
  description: "Installing dependencies with npm ci",
9419
9504
  detectedFrom: "package-lock.json"
9420
9505
  };
9421
9506
  }
9422
- if (fs20.existsSync(path21.join(cwd, "package.json"))) {
9507
+ if (fs21.existsSync(path22.join(cwd, "package.json"))) {
9423
9508
  return {
9424
9509
  command: ["npm", "install"],
9425
9510
  description: "Installing dependencies with npm",
9426
9511
  detectedFrom: "package.json"
9427
9512
  };
9428
9513
  }
9429
- if (fs20.existsSync(path21.join(cwd, "Pipfile.lock")) || fs20.existsSync(path21.join(cwd, "Pipfile"))) {
9514
+ if (fs21.existsSync(path22.join(cwd, "Pipfile.lock")) || fs21.existsSync(path22.join(cwd, "Pipfile"))) {
9430
9515
  return {
9431
9516
  command: ["pipenv", "install"],
9432
9517
  description: "Installing dependencies with pipenv",
9433
- detectedFrom: fs20.existsSync(path21.join(cwd, "Pipfile.lock")) ? "Pipfile.lock" : "Pipfile"
9518
+ detectedFrom: fs21.existsSync(path22.join(cwd, "Pipfile.lock")) ? "Pipfile.lock" : "Pipfile"
9434
9519
  };
9435
9520
  }
9436
- if (fs20.existsSync(path21.join(cwd, "poetry.lock"))) {
9521
+ if (fs21.existsSync(path22.join(cwd, "poetry.lock"))) {
9437
9522
  return {
9438
9523
  command: ["poetry", "install"],
9439
9524
  description: "Installing dependencies with poetry",
9440
9525
  detectedFrom: "poetry.lock"
9441
9526
  };
9442
9527
  }
9443
- if (fs20.existsSync(path21.join(cwd, "pyproject.toml"))) {
9444
- const pyprojectPath = path21.join(cwd, "pyproject.toml");
9445
- const content = fs20.readFileSync(pyprojectPath, "utf-8");
9528
+ if (fs21.existsSync(path22.join(cwd, "pyproject.toml"))) {
9529
+ const pyprojectPath = path22.join(cwd, "pyproject.toml");
9530
+ const content = fs21.readFileSync(pyprojectPath, "utf-8");
9446
9531
  if (content.includes("[tool.poetry]")) {
9447
9532
  return {
9448
9533
  command: ["poetry", "install"],
@@ -9451,42 +9536,42 @@ function getInstallCommand(cwd) {
9451
9536
  };
9452
9537
  }
9453
9538
  }
9454
- if (fs20.existsSync(path21.join(cwd, "requirements.txt"))) {
9539
+ if (fs21.existsSync(path22.join(cwd, "requirements.txt"))) {
9455
9540
  return {
9456
9541
  command: ["pip", "install", "-r", "requirements.txt"],
9457
9542
  description: "Installing dependencies with pip",
9458
9543
  detectedFrom: "requirements.txt"
9459
9544
  };
9460
9545
  }
9461
- if (fs20.existsSync(path21.join(cwd, "Gemfile.lock")) || fs20.existsSync(path21.join(cwd, "Gemfile"))) {
9546
+ if (fs21.existsSync(path22.join(cwd, "Gemfile.lock")) || fs21.existsSync(path22.join(cwd, "Gemfile"))) {
9462
9547
  return {
9463
9548
  command: ["bundle", "install"],
9464
9549
  description: "Installing dependencies with bundler",
9465
- detectedFrom: fs20.existsSync(path21.join(cwd, "Gemfile.lock")) ? "Gemfile.lock" : "Gemfile"
9550
+ detectedFrom: fs21.existsSync(path22.join(cwd, "Gemfile.lock")) ? "Gemfile.lock" : "Gemfile"
9466
9551
  };
9467
9552
  }
9468
- if (fs20.existsSync(path21.join(cwd, "go.sum")) || fs20.existsSync(path21.join(cwd, "go.mod"))) {
9553
+ if (fs21.existsSync(path22.join(cwd, "go.sum")) || fs21.existsSync(path22.join(cwd, "go.mod"))) {
9469
9554
  return {
9470
9555
  command: ["go", "mod", "download"],
9471
9556
  description: "Downloading Go modules",
9472
- detectedFrom: fs20.existsSync(path21.join(cwd, "go.sum")) ? "go.sum" : "go.mod"
9557
+ detectedFrom: fs21.existsSync(path22.join(cwd, "go.sum")) ? "go.sum" : "go.mod"
9473
9558
  };
9474
9559
  }
9475
- if (fs20.existsSync(path21.join(cwd, "Cargo.lock")) || fs20.existsSync(path21.join(cwd, "Cargo.toml"))) {
9560
+ if (fs21.existsSync(path22.join(cwd, "Cargo.lock")) || fs21.existsSync(path22.join(cwd, "Cargo.toml"))) {
9476
9561
  return {
9477
9562
  command: ["cargo", "build"],
9478
9563
  description: "Building Rust project (downloads dependencies)",
9479
- detectedFrom: fs20.existsSync(path21.join(cwd, "Cargo.lock")) ? "Cargo.lock" : "Cargo.toml"
9564
+ detectedFrom: fs21.existsSync(path22.join(cwd, "Cargo.lock")) ? "Cargo.lock" : "Cargo.toml"
9480
9565
  };
9481
9566
  }
9482
9567
  return null;
9483
9568
  }
9484
9569
 
9485
9570
  // src/daemon/daemon-process.ts
9486
- var fs21 = __toESM(require("fs"));
9571
+ var fs22 = __toESM(require("fs"));
9487
9572
  var http2 = __toESM(require("http"));
9488
9573
  var os8 = __toESM(require("os"));
9489
- var path22 = __toESM(require("path"));
9574
+ var path23 = __toESM(require("path"));
9490
9575
  var packageJson = require_package();
9491
9576
  async function ensureValidToken(config, bufferMs = 5 * 60 * 1e3) {
9492
9577
  const now = Date.now();
@@ -9707,9 +9792,9 @@ var Daemon = class _Daemon {
9707
9792
  this.healthServer = http2.createServer((req, res) => {
9708
9793
  if (req.url === "/health" || req.url === "/") {
9709
9794
  const isConnected = this.liveConnections.size > 0;
9710
- const projects = Array.from(this.connections.entries()).map(([path23, conn]) => ({
9711
- path: path23,
9712
- connected: this.liveConnections.has(path23)
9795
+ const projects = Array.from(this.connections.entries()).map(([path24, conn]) => ({
9796
+ path: path24,
9797
+ connected: this.liveConnections.has(path24)
9713
9798
  }));
9714
9799
  const status = {
9715
9800
  status: isConnected ? "healthy" : "degraded",
@@ -9939,9 +10024,12 @@ var Daemon = class _Daemon {
9939
10024
  this.ipcServer.on("worktree-list", async (params) => {
9940
10025
  return handleWorktreeList(params.workspaceSlug, params.projectSlug);
9941
10026
  });
9942
- this.ipcServer.on("project-eject", async (params) => {
10027
+ this.ipcServer.on("project:eject", async (params) => {
9943
10028
  return handleProjectEject(params);
9944
10029
  });
10030
+ this.ipcServer.on("project:setup", async (params) => {
10031
+ return handleProjectSetup(params);
10032
+ });
9945
10033
  }
9946
10034
  /**
9947
10035
  * Restore WebSocket connections for tracked projects
@@ -10074,7 +10162,7 @@ var Daemon = class _Daemon {
10074
10162
  client.updateActivity();
10075
10163
  try {
10076
10164
  const gitCmd = message.command;
10077
- const bareRepoPath = path22.join(projectPath, ".bare");
10165
+ const bareRepoPath = path23.join(projectPath, ".bare");
10078
10166
  const cwd = gitCmd.worktreePath || bareRepoPath;
10079
10167
  if (gitCmd.worktreePath) {
10080
10168
  console.log(`[Daemon] Routing command to worktree: ${gitCmd.worktreePath}`);
@@ -10188,9 +10276,14 @@ var Daemon = class _Daemon {
10188
10276
  );
10189
10277
  break;
10190
10278
  // EP1144: Project ejection for Tier 1 cleanup
10191
- case "eject_project":
10279
+ // EP1199: Renamed from eject_project to project:eject for naming consistency
10280
+ case "project:eject":
10192
10281
  result = await handleProjectEject(cmd);
10193
10282
  break;
10283
+ // EP1199: Project setup for cloud containers
10284
+ case "project:setup":
10285
+ result = await handleProjectSetup(cmd);
10286
+ break;
10194
10287
  default:
10195
10288
  result = {
10196
10289
  success: false,
@@ -10654,8 +10747,8 @@ var Daemon = class _Daemon {
10654
10747
  let daemonPid;
10655
10748
  try {
10656
10749
  const pidPath = getPidFilePath();
10657
- if (fs21.existsSync(pidPath)) {
10658
- const pidStr = fs21.readFileSync(pidPath, "utf-8").trim();
10750
+ if (fs22.existsSync(pidPath)) {
10751
+ const pidStr = fs22.readFileSync(pidPath, "utf-8").trim();
10659
10752
  daemonPid = parseInt(pidStr, 10);
10660
10753
  }
10661
10754
  } catch (pidError) {
@@ -10736,28 +10829,28 @@ var Daemon = class _Daemon {
10736
10829
  * - workDir: The directory to run git commands in (cwd)
10737
10830
  */
10738
10831
  getGitDirs(projectPath) {
10739
- const bareDir = path22.join(projectPath, ".bare");
10740
- const gitPath = path22.join(projectPath, ".git");
10741
- if (fs21.existsSync(bareDir) && fs21.statSync(bareDir).isDirectory()) {
10832
+ const bareDir = path23.join(projectPath, ".bare");
10833
+ const gitPath = path23.join(projectPath, ".git");
10834
+ if (fs22.existsSync(bareDir) && fs22.statSync(bareDir).isDirectory()) {
10742
10835
  return { gitDir: bareDir, workDir: projectPath };
10743
10836
  }
10744
- if (fs21.existsSync(gitPath) && fs21.statSync(gitPath).isDirectory()) {
10837
+ if (fs22.existsSync(gitPath) && fs22.statSync(gitPath).isDirectory()) {
10745
10838
  return { gitDir: null, workDir: projectPath };
10746
10839
  }
10747
- if (fs21.existsSync(gitPath) && fs21.statSync(gitPath).isFile()) {
10840
+ if (fs22.existsSync(gitPath) && fs22.statSync(gitPath).isFile()) {
10748
10841
  return { gitDir: null, workDir: projectPath };
10749
10842
  }
10750
- const entries = fs21.readdirSync(projectPath, { withFileTypes: true });
10843
+ const entries = fs22.readdirSync(projectPath, { withFileTypes: true });
10751
10844
  for (const entry of entries) {
10752
10845
  if (entry.isDirectory() && entry.name.startsWith("EP")) {
10753
- const worktreePath = path22.join(projectPath, entry.name);
10754
- const worktreeGit = path22.join(worktreePath, ".git");
10755
- if (fs21.existsSync(worktreeGit)) {
10846
+ const worktreePath = path23.join(projectPath, entry.name);
10847
+ const worktreeGit = path23.join(worktreePath, ".git");
10848
+ if (fs22.existsSync(worktreeGit)) {
10756
10849
  return { gitDir: null, workDir: worktreePath };
10757
10850
  }
10758
10851
  }
10759
10852
  }
10760
- if (fs21.existsSync(bareDir)) {
10853
+ if (fs22.existsSync(bareDir)) {
10761
10854
  return { gitDir: bareDir, workDir: projectPath };
10762
10855
  }
10763
10856
  return { gitDir: null, workDir: projectPath };
@@ -10821,24 +10914,24 @@ var Daemon = class _Daemon {
10821
10914
  async installGitHooks(projectPath) {
10822
10915
  const hooks = ["post-checkout", "pre-commit", "post-commit"];
10823
10916
  let hooksDir;
10824
- const bareHooksDir = path22.join(projectPath, ".bare", "hooks");
10825
- const gitHooksDir = path22.join(projectPath, ".git", "hooks");
10826
- if (fs21.existsSync(bareHooksDir)) {
10917
+ const bareHooksDir = path23.join(projectPath, ".bare", "hooks");
10918
+ const gitHooksDir = path23.join(projectPath, ".git", "hooks");
10919
+ if (fs22.existsSync(bareHooksDir)) {
10827
10920
  hooksDir = bareHooksDir;
10828
- } else if (fs21.existsSync(gitHooksDir) && fs21.statSync(path22.join(projectPath, ".git")).isDirectory()) {
10921
+ } else if (fs22.existsSync(gitHooksDir) && fs22.statSync(path23.join(projectPath, ".git")).isDirectory()) {
10829
10922
  hooksDir = gitHooksDir;
10830
10923
  } else {
10831
- const parentBareHooks = path22.join(projectPath, "..", ".bare", "hooks");
10832
- if (fs21.existsSync(parentBareHooks)) {
10924
+ const parentBareHooks = path23.join(projectPath, "..", ".bare", "hooks");
10925
+ if (fs22.existsSync(parentBareHooks)) {
10833
10926
  hooksDir = parentBareHooks;
10834
10927
  } else {
10835
10928
  console.warn(`[Daemon] Hooks directory not found for: ${projectPath}`);
10836
10929
  return;
10837
10930
  }
10838
10931
  }
10839
- if (!fs21.existsSync(hooksDir)) {
10932
+ if (!fs22.existsSync(hooksDir)) {
10840
10933
  try {
10841
- fs21.mkdirSync(hooksDir, { recursive: true });
10934
+ fs22.mkdirSync(hooksDir, { recursive: true });
10842
10935
  } catch (error) {
10843
10936
  console.warn(`[Daemon] Hooks directory not found and could not create: ${hooksDir}`);
10844
10937
  return;
@@ -10846,20 +10939,20 @@ var Daemon = class _Daemon {
10846
10939
  }
10847
10940
  for (const hookName of hooks) {
10848
10941
  try {
10849
- const hookPath = path22.join(hooksDir, hookName);
10850
- const bundledHookPath = path22.join(__dirname, "..", "hooks", hookName);
10851
- if (!fs21.existsSync(bundledHookPath)) {
10942
+ const hookPath = path23.join(hooksDir, hookName);
10943
+ const bundledHookPath = path23.join(__dirname, "..", "hooks", hookName);
10944
+ if (!fs22.existsSync(bundledHookPath)) {
10852
10945
  console.warn(`[Daemon] Bundled hook not found: ${bundledHookPath}`);
10853
10946
  continue;
10854
10947
  }
10855
- const hookContent = fs21.readFileSync(bundledHookPath, "utf-8");
10856
- if (fs21.existsSync(hookPath)) {
10857
- const existingContent = fs21.readFileSync(hookPath, "utf-8");
10948
+ const hookContent = fs22.readFileSync(bundledHookPath, "utf-8");
10949
+ if (fs22.existsSync(hookPath)) {
10950
+ const existingContent = fs22.readFileSync(hookPath, "utf-8");
10858
10951
  if (existingContent === hookContent) {
10859
10952
  continue;
10860
10953
  }
10861
10954
  }
10862
- fs21.writeFileSync(hookPath, hookContent, { mode: 493 });
10955
+ fs22.writeFileSync(hookPath, hookContent, { mode: 493 });
10863
10956
  console.log(`[Daemon] Installed git hook: ${hookName}`);
10864
10957
  } catch (error) {
10865
10958
  console.warn(`[Daemon] Failed to install ${hookName} hook:`, error instanceof Error ? error.message : error);
@@ -11863,8 +11956,8 @@ var Daemon = class _Daemon {
11863
11956
  await this.shutdown();
11864
11957
  try {
11865
11958
  const pidPath = getPidFilePath();
11866
- if (fs21.existsSync(pidPath)) {
11867
- fs21.unlinkSync(pidPath);
11959
+ if (fs22.existsSync(pidPath)) {
11960
+ fs22.unlinkSync(pidPath);
11868
11961
  console.log("[Daemon] PID file cleaned up");
11869
11962
  }
11870
11963
  } catch (error) {