episoda 0.2.25 → 0.2.27

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.
@@ -1556,15 +1556,15 @@ var require_git_executor = __commonJS({
1556
1556
  try {
1557
1557
  const { stdout: gitDir } = await execAsync2("git rev-parse --git-dir", { cwd, timeout: 5e3 });
1558
1558
  const gitDirPath = gitDir.trim();
1559
- const fs14 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1559
+ const fs16 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1560
1560
  const rebaseMergePath = `${gitDirPath}/rebase-merge`;
1561
1561
  const rebaseApplyPath = `${gitDirPath}/rebase-apply`;
1562
1562
  try {
1563
- await fs14.access(rebaseMergePath);
1563
+ await fs16.access(rebaseMergePath);
1564
1564
  inRebase = true;
1565
1565
  } catch {
1566
1566
  try {
1567
- await fs14.access(rebaseApplyPath);
1567
+ await fs16.access(rebaseApplyPath);
1568
1568
  inRebase = true;
1569
1569
  } catch {
1570
1570
  inRebase = false;
@@ -1618,9 +1618,9 @@ var require_git_executor = __commonJS({
1618
1618
  error: validation.error || "UNKNOWN_ERROR"
1619
1619
  };
1620
1620
  }
1621
- const fs14 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1621
+ const fs16 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1622
1622
  try {
1623
- await fs14.access(command.path);
1623
+ await fs16.access(command.path);
1624
1624
  return {
1625
1625
  success: false,
1626
1626
  error: "WORKTREE_EXISTS",
@@ -1671,9 +1671,9 @@ var require_git_executor = __commonJS({
1671
1671
  */
1672
1672
  async executeWorktreeRemove(command, cwd, options) {
1673
1673
  try {
1674
- const fs14 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1674
+ const fs16 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1675
1675
  try {
1676
- await fs14.access(command.path);
1676
+ await fs16.access(command.path);
1677
1677
  } catch {
1678
1678
  return {
1679
1679
  success: false,
@@ -1826,10 +1826,10 @@ var require_git_executor = __commonJS({
1826
1826
  */
1827
1827
  async executeCloneBare(command, options) {
1828
1828
  try {
1829
- const fs14 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1830
- const path15 = await Promise.resolve().then(() => __importStar(require("path")));
1829
+ const fs16 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1830
+ const path17 = await Promise.resolve().then(() => __importStar(require("path")));
1831
1831
  try {
1832
- await fs14.access(command.path);
1832
+ await fs16.access(command.path);
1833
1833
  return {
1834
1834
  success: false,
1835
1835
  error: "BRANCH_ALREADY_EXISTS",
@@ -1838,9 +1838,9 @@ var require_git_executor = __commonJS({
1838
1838
  };
1839
1839
  } catch {
1840
1840
  }
1841
- const parentDir = path15.dirname(command.path);
1841
+ const parentDir = path17.dirname(command.path);
1842
1842
  try {
1843
- await fs14.mkdir(parentDir, { recursive: true });
1843
+ await fs16.mkdir(parentDir, { recursive: true });
1844
1844
  } catch {
1845
1845
  }
1846
1846
  const { stdout, stderr } = await execAsync2(
@@ -1883,22 +1883,22 @@ var require_git_executor = __commonJS({
1883
1883
  */
1884
1884
  async executeProjectInfo(cwd, options) {
1885
1885
  try {
1886
- const fs14 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1887
- const path15 = await Promise.resolve().then(() => __importStar(require("path")));
1886
+ const fs16 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1887
+ const path17 = await Promise.resolve().then(() => __importStar(require("path")));
1888
1888
  let currentPath = cwd;
1889
1889
  let projectPath = cwd;
1890
1890
  let bareRepoPath;
1891
1891
  for (let i = 0; i < 10; i++) {
1892
- const bareDir = path15.join(currentPath, ".bare");
1893
- const episodaDir = path15.join(currentPath, ".episoda");
1892
+ const bareDir = path17.join(currentPath, ".bare");
1893
+ const episodaDir = path17.join(currentPath, ".episoda");
1894
1894
  try {
1895
- await fs14.access(bareDir);
1896
- await fs14.access(episodaDir);
1895
+ await fs16.access(bareDir);
1896
+ await fs16.access(episodaDir);
1897
1897
  projectPath = currentPath;
1898
1898
  bareRepoPath = bareDir;
1899
1899
  break;
1900
1900
  } catch {
1901
- const parentPath = path15.dirname(currentPath);
1901
+ const parentPath = path17.dirname(currentPath);
1902
1902
  if (parentPath === currentPath) {
1903
1903
  break;
1904
1904
  }
@@ -2492,31 +2492,31 @@ var require_auth = __commonJS({
2492
2492
  exports2.loadConfig = loadConfig5;
2493
2493
  exports2.saveConfig = saveConfig2;
2494
2494
  exports2.validateToken = validateToken;
2495
- var fs14 = __importStar(require("fs"));
2496
- var path15 = __importStar(require("path"));
2495
+ var fs16 = __importStar(require("fs"));
2496
+ var path17 = __importStar(require("path"));
2497
2497
  var os6 = __importStar(require("os"));
2498
2498
  var child_process_1 = require("child_process");
2499
2499
  var DEFAULT_CONFIG_FILE = "config.json";
2500
2500
  function getConfigDir6() {
2501
- return process.env.EPISODA_CONFIG_DIR || path15.join(os6.homedir(), ".episoda");
2501
+ return process.env.EPISODA_CONFIG_DIR || path17.join(os6.homedir(), ".episoda");
2502
2502
  }
2503
2503
  function getConfigPath(configPath) {
2504
2504
  if (configPath) {
2505
2505
  return configPath;
2506
2506
  }
2507
- return path15.join(getConfigDir6(), DEFAULT_CONFIG_FILE);
2507
+ return path17.join(getConfigDir6(), DEFAULT_CONFIG_FILE);
2508
2508
  }
2509
2509
  function ensureConfigDir(configPath) {
2510
- const dir = path15.dirname(configPath);
2511
- const isNew = !fs14.existsSync(dir);
2510
+ const dir = path17.dirname(configPath);
2511
+ const isNew = !fs16.existsSync(dir);
2512
2512
  if (isNew) {
2513
- fs14.mkdirSync(dir, { recursive: true, mode: 448 });
2513
+ fs16.mkdirSync(dir, { recursive: true, mode: 448 });
2514
2514
  }
2515
2515
  if (process.platform === "darwin") {
2516
- const nosyncPath = path15.join(dir, ".nosync");
2517
- if (isNew || !fs14.existsSync(nosyncPath)) {
2516
+ const nosyncPath = path17.join(dir, ".nosync");
2517
+ if (isNew || !fs16.existsSync(nosyncPath)) {
2518
2518
  try {
2519
- fs14.writeFileSync(nosyncPath, "", { mode: 384 });
2519
+ fs16.writeFileSync(nosyncPath, "", { mode: 384 });
2520
2520
  (0, child_process_1.execSync)(`xattr -w com.apple.fileprovider.ignore 1 "${dir}"`, {
2521
2521
  stdio: "ignore",
2522
2522
  timeout: 5e3
@@ -2528,11 +2528,11 @@ var require_auth = __commonJS({
2528
2528
  }
2529
2529
  async function loadConfig5(configPath) {
2530
2530
  const fullPath = getConfigPath(configPath);
2531
- if (!fs14.existsSync(fullPath)) {
2531
+ if (!fs16.existsSync(fullPath)) {
2532
2532
  return null;
2533
2533
  }
2534
2534
  try {
2535
- const content = fs14.readFileSync(fullPath, "utf8");
2535
+ const content = fs16.readFileSync(fullPath, "utf8");
2536
2536
  const config = JSON.parse(content);
2537
2537
  return config;
2538
2538
  } catch (error) {
@@ -2545,7 +2545,7 @@ var require_auth = __commonJS({
2545
2545
  ensureConfigDir(fullPath);
2546
2546
  try {
2547
2547
  const content = JSON.stringify(config, null, 2);
2548
- fs14.writeFileSync(fullPath, content, { mode: 384 });
2548
+ fs16.writeFileSync(fullPath, content, { mode: 384 });
2549
2549
  } catch (error) {
2550
2550
  throw new Error(`Failed to save config: ${error instanceof Error ? error.message : String(error)}`);
2551
2551
  }
@@ -2696,7 +2696,7 @@ var require_package = __commonJS({
2696
2696
  "package.json"(exports2, module2) {
2697
2697
  module2.exports = {
2698
2698
  name: "episoda",
2699
- version: "0.2.24",
2699
+ version: "0.2.26",
2700
2700
  description: "CLI tool for Episoda local development workflow orchestration",
2701
2701
  main: "dist/index.js",
2702
2702
  types: "dist/index.d.ts",
@@ -6023,20 +6023,39 @@ async function findProjectRoot(startPath) {
6023
6023
  return null;
6024
6024
  }
6025
6025
 
6026
- // src/utils/worktree.ts
6027
- var path13 = __toESM(require("path"));
6026
+ // src/utils/env-setup.ts
6028
6027
  var fs12 = __toESM(require("fs"));
6028
+ var path13 = __toESM(require("path"));
6029
+ function writeEnvFile(targetPath, envVars) {
6030
+ if (Object.keys(envVars).length === 0) {
6031
+ return;
6032
+ }
6033
+ const envContent = Object.entries(envVars).map(([key, value]) => {
6034
+ if (/[\s'"#$`\\]/.test(value) || value.includes("\n")) {
6035
+ const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
6036
+ return `${key}="${escaped}"`;
6037
+ }
6038
+ return `${key}=${value}`;
6039
+ }).join("\n") + "\n";
6040
+ const envPath = path13.join(targetPath, ".env");
6041
+ fs12.writeFileSync(envPath, envContent, { mode: 384 });
6042
+ console.log(`[env-setup] Wrote ${Object.keys(envVars).length} env vars to ${envPath}`);
6043
+ }
6044
+
6045
+ // src/utils/worktree.ts
6046
+ var path14 = __toESM(require("path"));
6047
+ var fs13 = __toESM(require("fs"));
6029
6048
  var os4 = __toESM(require("os"));
6030
6049
  var import_core9 = __toESM(require_dist());
6031
6050
  function getEpisodaRoot2() {
6032
- return process.env.EPISODA_ROOT || path13.join(os4.homedir(), "episoda");
6051
+ return process.env.EPISODA_ROOT || path14.join(os4.homedir(), "episoda");
6033
6052
  }
6034
6053
  function getWorktreeInfo(moduleUid, workspaceSlug, projectSlug) {
6035
6054
  const root = getEpisodaRoot2();
6036
- const worktreePath = path13.join(root, workspaceSlug, projectSlug, moduleUid);
6055
+ const worktreePath = path14.join(root, workspaceSlug, projectSlug, moduleUid);
6037
6056
  return {
6038
6057
  path: worktreePath,
6039
- exists: fs12.existsSync(worktreePath),
6058
+ exists: fs13.existsSync(worktreePath),
6040
6059
  moduleUid
6041
6060
  };
6042
6061
  }
@@ -6053,7 +6072,7 @@ async function getProjectRootPath() {
6053
6072
  if (!config?.workspace_slug || !config?.project_slug) {
6054
6073
  return null;
6055
6074
  }
6056
- return path13.join(
6075
+ return path14.join(
6057
6076
  getEpisodaRoot2(),
6058
6077
  config.workspace_slug,
6059
6078
  config.project_slug
@@ -6102,10 +6121,105 @@ function clearAllPorts() {
6102
6121
  }
6103
6122
  }
6104
6123
 
6124
+ // src/framework-detector.ts
6125
+ var fs14 = __toESM(require("fs"));
6126
+ var path15 = __toESM(require("path"));
6127
+ function getInstallCommand(cwd) {
6128
+ if (fs14.existsSync(path15.join(cwd, "bun.lockb"))) {
6129
+ return {
6130
+ command: ["bun", "install"],
6131
+ description: "Installing dependencies with bun",
6132
+ detectedFrom: "bun.lockb"
6133
+ };
6134
+ }
6135
+ if (fs14.existsSync(path15.join(cwd, "pnpm-lock.yaml"))) {
6136
+ return {
6137
+ command: ["pnpm", "install"],
6138
+ description: "Installing dependencies with pnpm",
6139
+ detectedFrom: "pnpm-lock.yaml"
6140
+ };
6141
+ }
6142
+ if (fs14.existsSync(path15.join(cwd, "yarn.lock"))) {
6143
+ return {
6144
+ command: ["yarn", "install"],
6145
+ description: "Installing dependencies with yarn",
6146
+ detectedFrom: "yarn.lock"
6147
+ };
6148
+ }
6149
+ if (fs14.existsSync(path15.join(cwd, "package-lock.json"))) {
6150
+ return {
6151
+ command: ["npm", "ci"],
6152
+ description: "Installing dependencies with npm ci",
6153
+ detectedFrom: "package-lock.json"
6154
+ };
6155
+ }
6156
+ if (fs14.existsSync(path15.join(cwd, "package.json"))) {
6157
+ return {
6158
+ command: ["npm", "install"],
6159
+ description: "Installing dependencies with npm",
6160
+ detectedFrom: "package.json"
6161
+ };
6162
+ }
6163
+ if (fs14.existsSync(path15.join(cwd, "Pipfile.lock")) || fs14.existsSync(path15.join(cwd, "Pipfile"))) {
6164
+ return {
6165
+ command: ["pipenv", "install"],
6166
+ description: "Installing dependencies with pipenv",
6167
+ detectedFrom: fs14.existsSync(path15.join(cwd, "Pipfile.lock")) ? "Pipfile.lock" : "Pipfile"
6168
+ };
6169
+ }
6170
+ if (fs14.existsSync(path15.join(cwd, "poetry.lock"))) {
6171
+ return {
6172
+ command: ["poetry", "install"],
6173
+ description: "Installing dependencies with poetry",
6174
+ detectedFrom: "poetry.lock"
6175
+ };
6176
+ }
6177
+ if (fs14.existsSync(path15.join(cwd, "pyproject.toml"))) {
6178
+ const pyprojectPath = path15.join(cwd, "pyproject.toml");
6179
+ const content = fs14.readFileSync(pyprojectPath, "utf-8");
6180
+ if (content.includes("[tool.poetry]")) {
6181
+ return {
6182
+ command: ["poetry", "install"],
6183
+ description: "Installing dependencies with poetry",
6184
+ detectedFrom: "pyproject.toml"
6185
+ };
6186
+ }
6187
+ }
6188
+ if (fs14.existsSync(path15.join(cwd, "requirements.txt"))) {
6189
+ return {
6190
+ command: ["pip", "install", "-r", "requirements.txt"],
6191
+ description: "Installing dependencies with pip",
6192
+ detectedFrom: "requirements.txt"
6193
+ };
6194
+ }
6195
+ if (fs14.existsSync(path15.join(cwd, "Gemfile.lock")) || fs14.existsSync(path15.join(cwd, "Gemfile"))) {
6196
+ return {
6197
+ command: ["bundle", "install"],
6198
+ description: "Installing dependencies with bundler",
6199
+ detectedFrom: fs14.existsSync(path15.join(cwd, "Gemfile.lock")) ? "Gemfile.lock" : "Gemfile"
6200
+ };
6201
+ }
6202
+ if (fs14.existsSync(path15.join(cwd, "go.sum")) || fs14.existsSync(path15.join(cwd, "go.mod"))) {
6203
+ return {
6204
+ command: ["go", "mod", "download"],
6205
+ description: "Downloading Go modules",
6206
+ detectedFrom: fs14.existsSync(path15.join(cwd, "go.sum")) ? "go.sum" : "go.mod"
6207
+ };
6208
+ }
6209
+ if (fs14.existsSync(path15.join(cwd, "Cargo.lock")) || fs14.existsSync(path15.join(cwd, "Cargo.toml"))) {
6210
+ return {
6211
+ command: ["cargo", "build"],
6212
+ description: "Building Rust project (downloads dependencies)",
6213
+ detectedFrom: fs14.existsSync(path15.join(cwd, "Cargo.lock")) ? "Cargo.lock" : "Cargo.toml"
6214
+ };
6215
+ }
6216
+ return null;
6217
+ }
6218
+
6105
6219
  // src/daemon/daemon-process.ts
6106
- var fs13 = __toESM(require("fs"));
6220
+ var fs15 = __toESM(require("fs"));
6107
6221
  var os5 = __toESM(require("os"));
6108
- var path14 = __toESM(require("path"));
6222
+ var path16 = __toESM(require("path"));
6109
6223
  var packageJson = require_package();
6110
6224
  async function ensureValidToken(config, bufferMs = 5 * 60 * 1e3) {
6111
6225
  const now = Date.now();
@@ -6602,7 +6716,7 @@ var Daemon = class _Daemon {
6602
6716
  client.updateActivity();
6603
6717
  try {
6604
6718
  const gitCmd = message.command;
6605
- const bareRepoPath = path14.join(projectPath, ".bare");
6719
+ const bareRepoPath = path16.join(projectPath, ".bare");
6606
6720
  const cwd = gitCmd.worktreePath || bareRepoPath;
6607
6721
  if (gitCmd.worktreePath) {
6608
6722
  console.log(`[Daemon] Routing command to worktree: ${gitCmd.worktreePath}`);
@@ -7101,8 +7215,9 @@ var Daemon = class _Daemon {
7101
7215
  const setupConfig = worktreeConfig?.project_settings;
7102
7216
  const envVars = await fetchEnvVars();
7103
7217
  const hasEnvVars = Object.keys(envVars).length > 0;
7104
- if (setupConfig?.worktree_copy_files?.length || setupConfig?.worktree_setup_script || hasEnvVars) {
7105
- console.log(`[Daemon] EP959: Starting async worktree setup for ${moduleUid}`);
7218
+ const hasSetupConfig = setupConfig?.worktree_copy_files?.length || setupConfig?.worktree_setup_script || hasEnvVars;
7219
+ {
7220
+ console.log(`[Daemon] EP986: Starting async worktree setup for ${moduleUid}${hasSetupConfig ? " (with config)" : " (for dependency installation)"}`);
7106
7221
  await worktreeManager.updateWorktreeStatus(moduleUid, "pending");
7107
7222
  this.runWorktreeSetupAsync(
7108
7223
  moduleUid,
@@ -7111,6 +7226,7 @@ var Daemon = class _Daemon {
7111
7226
  setupConfig?.worktree_setup_script,
7112
7227
  worktree.path,
7113
7228
  envVars
7229
+ // EP973: Use server-fetched env vars
7114
7230
  ).then(() => {
7115
7231
  console.log(`[Daemon] EP959: Setup complete for ${moduleUid}, starting tunnel`);
7116
7232
  this.startTunnelForModule(moduleUid, worktree.path);
@@ -7119,7 +7235,8 @@ var Daemon = class _Daemon {
7119
7235
  });
7120
7236
  return;
7121
7237
  }
7122
- } else if (!worktree.exists) {
7238
+ }
7239
+ if (!worktree.exists) {
7123
7240
  console.log(`[Daemon] EP956: No worktree for ${moduleUid} at ${worktree.path}, skipping tunnel`);
7124
7241
  return;
7125
7242
  }
@@ -7209,8 +7326,8 @@ var Daemon = class _Daemon {
7209
7326
  let daemonPid;
7210
7327
  try {
7211
7328
  const pidPath = getPidFilePath();
7212
- if (fs13.existsSync(pidPath)) {
7213
- const pidStr = fs13.readFileSync(pidPath, "utf-8").trim();
7329
+ if (fs15.existsSync(pidPath)) {
7330
+ const pidStr = fs15.readFileSync(pidPath, "utf-8").trim();
7214
7331
  daemonPid = parseInt(pidStr, 10);
7215
7332
  }
7216
7333
  } catch (pidError) {
@@ -7331,27 +7448,27 @@ var Daemon = class _Daemon {
7331
7448
  */
7332
7449
  async installGitHooks(projectPath) {
7333
7450
  const hooks = ["post-checkout", "pre-commit", "post-commit"];
7334
- const hooksDir = path14.join(projectPath, ".git", "hooks");
7335
- if (!fs13.existsSync(hooksDir)) {
7451
+ const hooksDir = path16.join(projectPath, ".git", "hooks");
7452
+ if (!fs15.existsSync(hooksDir)) {
7336
7453
  console.warn(`[Daemon] Hooks directory not found: ${hooksDir}`);
7337
7454
  return;
7338
7455
  }
7339
7456
  for (const hookName of hooks) {
7340
7457
  try {
7341
- const hookPath = path14.join(hooksDir, hookName);
7342
- const bundledHookPath = path14.join(__dirname, "..", "hooks", hookName);
7343
- if (!fs13.existsSync(bundledHookPath)) {
7458
+ const hookPath = path16.join(hooksDir, hookName);
7459
+ const bundledHookPath = path16.join(__dirname, "..", "hooks", hookName);
7460
+ if (!fs15.existsSync(bundledHookPath)) {
7344
7461
  console.warn(`[Daemon] Bundled hook not found: ${bundledHookPath}`);
7345
7462
  continue;
7346
7463
  }
7347
- const hookContent = fs13.readFileSync(bundledHookPath, "utf-8");
7348
- if (fs13.existsSync(hookPath)) {
7349
- const existingContent = fs13.readFileSync(hookPath, "utf-8");
7464
+ const hookContent = fs15.readFileSync(bundledHookPath, "utf-8");
7465
+ if (fs15.existsSync(hookPath)) {
7466
+ const existingContent = fs15.readFileSync(hookPath, "utf-8");
7350
7467
  if (existingContent === hookContent) {
7351
7468
  continue;
7352
7469
  }
7353
7470
  }
7354
- fs13.writeFileSync(hookPath, hookContent, { mode: 493 });
7471
+ fs15.writeFileSync(hookPath, hookContent, { mode: 493 });
7355
7472
  console.log(`[Daemon] Installed git hook: ${hookName}`);
7356
7473
  } catch (error) {
7357
7474
  console.warn(`[Daemon] Failed to install ${hookName} hook:`, error instanceof Error ? error.message : error);
@@ -7471,17 +7588,8 @@ var Daemon = class _Daemon {
7471
7588
  try {
7472
7589
  await worktreeManager.updateWorktreeStatus(moduleUid, "running");
7473
7590
  if (Object.keys(envVars).length > 0) {
7474
- console.log(`[Daemon] EP964: Writing .env with ${Object.keys(envVars).length} variables to ${moduleUid}`);
7475
- const envContent = Object.entries(envVars).map(([key, value]) => {
7476
- if (/[\s'"#$`\\]/.test(value) || value.includes("\n")) {
7477
- const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
7478
- return `${key}="${escaped}"`;
7479
- }
7480
- return `${key}=${value}`;
7481
- }).join("\n") + "\n";
7482
- const envPath = path14.join(worktreePath, ".env");
7483
- fs13.writeFileSync(envPath, envContent, { mode: 384 });
7484
- console.log(`[Daemon] EP964: .env written to ${envPath}`);
7591
+ console.log(`[Daemon] EP988: Writing .env with ${Object.keys(envVars).length} variables to ${moduleUid}`);
7592
+ writeEnvFile(worktreePath, envVars);
7485
7593
  }
7486
7594
  if (copyFiles.length > 0) {
7487
7595
  console.log(`[Daemon] EP964: DEPRECATED - Copying ${copyFiles.length} files to ${moduleUid}`);
@@ -7491,6 +7599,29 @@ var Daemon = class _Daemon {
7491
7599
  console.warn(`[Daemon] EP964: File copy failed (non-fatal): ${copyResult.error}`);
7492
7600
  }
7493
7601
  }
7602
+ const installCmd = getInstallCommand(worktreePath);
7603
+ if (installCmd) {
7604
+ console.log(`[Daemon] EP986: ${installCmd.description} (detected from ${installCmd.detectedFrom})`);
7605
+ console.log(`[Daemon] EP986: Running: ${installCmd.command.join(" ")}`);
7606
+ try {
7607
+ const { execSync: execSync6 } = await import("child_process");
7608
+ execSync6(installCmd.command.join(" "), {
7609
+ cwd: worktreePath,
7610
+ stdio: "inherit",
7611
+ timeout: 10 * 60 * 1e3,
7612
+ // 10 minute timeout
7613
+ env: { ...process.env, CI: "true" }
7614
+ // CI=true for cleaner output
7615
+ });
7616
+ console.log(`[Daemon] EP986: Dependencies installed successfully for ${moduleUid}`);
7617
+ } catch (installError) {
7618
+ const errorMsg = installError instanceof Error ? installError.message : String(installError);
7619
+ console.warn(`[Daemon] EP986: Dependency installation failed (non-fatal): ${errorMsg}`);
7620
+ console.warn(`[Daemon] EP986: You may need to run '${installCmd.command.join(" ")}' manually`);
7621
+ }
7622
+ } else {
7623
+ console.log(`[Daemon] EP986: No package manager detected for ${moduleUid}, skipping dependency installation`);
7624
+ }
7494
7625
  if (setupScript) {
7495
7626
  console.log(`[Daemon] EP959: Running setup script for ${moduleUid}`);
7496
7627
  const scriptResult = await worktreeManager.runSetupScript(moduleUid, setupScript);
@@ -8233,8 +8364,8 @@ var Daemon = class _Daemon {
8233
8364
  await this.shutdown();
8234
8365
  try {
8235
8366
  const pidPath = getPidFilePath();
8236
- if (fs13.existsSync(pidPath)) {
8237
- fs13.unlinkSync(pidPath);
8367
+ if (fs15.existsSync(pidPath)) {
8368
+ fs15.unlinkSync(pidPath);
8238
8369
  console.log("[Daemon] PID file cleaned up");
8239
8370
  }
8240
8371
  } catch (error) {