episoda 0.2.107 → 0.2.109

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.
@@ -1626,12 +1626,14 @@ var require_git_executor = __commonJS({
1626
1626
  */
1627
1627
  async executeWorktreeAdd(command, cwd, options) {
1628
1628
  try {
1629
- const validation = (0, git_validator_1.validateBranchName)(command.branch);
1630
- if (!validation.valid) {
1631
- return {
1632
- success: false,
1633
- error: validation.error || "UNKNOWN_ERROR"
1634
- };
1629
+ if (!command.detach && command.branch) {
1630
+ const validation = (0, git_validator_1.validateBranchName)(command.branch);
1631
+ if (!validation.valid) {
1632
+ return {
1633
+ success: false,
1634
+ error: validation.error || "UNKNOWN_ERROR"
1635
+ };
1636
+ }
1635
1637
  }
1636
1638
  const fs24 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1637
1639
  try {
@@ -1648,7 +1650,14 @@ var require_git_executor = __commonJS({
1648
1650
  } catch {
1649
1651
  }
1650
1652
  const args = ["worktree", "add"];
1651
- if (command.create) {
1653
+ if (command.detach) {
1654
+ args.push("--detach", command.path);
1655
+ if (command.startPoint) {
1656
+ args.push(command.startPoint);
1657
+ } else {
1658
+ args.push("HEAD");
1659
+ }
1660
+ } else if (command.create) {
1652
1661
  args.push("-b", command.branch, command.path);
1653
1662
  if (command.startPoint) {
1654
1663
  args.push(command.startPoint);
@@ -1658,12 +1667,14 @@ var require_git_executor = __commonJS({
1658
1667
  }
1659
1668
  const result = await this.runGitCommand(args, cwd, options);
1660
1669
  if (result.success) {
1670
+ const outputMsg = command.detach ? `Created detached worktree at ${command.path} from ${command.startPoint || "HEAD"}` : `Created worktree at ${command.path} for branch ${command.branch}`;
1661
1671
  return {
1662
1672
  success: true,
1663
- output: `Created worktree at ${command.path} for branch ${command.branch}`,
1673
+ output: outputMsg,
1664
1674
  details: {
1665
1675
  worktreePath: command.path,
1666
- branchName: command.branch
1676
+ branchName: command.detach ? void 0 : command.branch,
1677
+ detached: command.detach
1667
1678
  }
1668
1679
  };
1669
1680
  }
@@ -2804,7 +2815,7 @@ var require_package = __commonJS({
2804
2815
  "package.json"(exports2, module2) {
2805
2816
  module2.exports = {
2806
2817
  name: "episoda",
2807
- version: "0.2.106",
2818
+ version: "0.2.108",
2808
2819
  description: "CLI tool for Episoda local development workflow orchestration",
2809
2820
  main: "dist/index.js",
2810
2821
  types: "dist/index.d.ts",
@@ -4191,7 +4202,7 @@ var WorktreeManager = class _WorktreeManager {
4191
4202
  * Create a worktree for a module
4192
4203
  * The entire operation is locked to prevent race conditions
4193
4204
  */
4194
- async createWorktree(moduleUid, branchName, createBranch = false) {
4205
+ async createWorktree(moduleUid, branchName, createBranch = false, detachedHead = false) {
4195
4206
  if (!validateModuleUid(moduleUid)) {
4196
4207
  return {
4197
4208
  success: false,
@@ -4230,9 +4241,13 @@ var WorktreeManager = class _WorktreeManager {
4230
4241
  const result = await this.gitExecutor.execute({
4231
4242
  action: "worktree_add",
4232
4243
  path: worktreePath,
4233
- branch: branchName,
4234
- create: createBranch,
4235
- startPoint: createBranch ? "origin/main" : void 0
4244
+ branch: detachedHead ? void 0 : branchName,
4245
+ // No branch for detached HEAD
4246
+ create: detachedHead ? false : createBranch,
4247
+ // Don't create branch for detached
4248
+ detach: detachedHead,
4249
+ // EP1223: Detach flag
4250
+ startPoint: detachedHead ? "origin/main" : createBranch ? "origin/main" : void 0
4236
4251
  }, { cwd: this.bareRepoPath });
4237
4252
  if (!result.success) {
4238
4253
  return {
@@ -7509,11 +7524,13 @@ async function handleWorktreeCreate(request2) {
7509
7524
  createBranch,
7510
7525
  repoUrl,
7511
7526
  envVars,
7512
- setupScript
7527
+ setupScript,
7528
+ detachedHead = false
7529
+ // EP1223: Default to false for backward compatibility
7513
7530
  } = request2;
7514
7531
  console.log(`[Worktree] K1273: Creating worktree for ${moduleUid}`);
7515
7532
  console.log(`[Worktree] Project: ${projectSlug}`);
7516
- console.log(`[Worktree] Branch: ${branchName} (create: ${createBranch})`);
7533
+ console.log(`[Worktree] Branch: ${branchName} (create: ${createBranch}, detached: ${detachedHead})`);
7517
7534
  if (!validateModuleUid(moduleUid)) {
7518
7535
  return {
7519
7536
  success: false,
@@ -7567,7 +7584,7 @@ async function handleWorktreeCreate(request2) {
7567
7584
  error: `Failed to initialize WorktreeManager at ${projectPath}`
7568
7585
  };
7569
7586
  }
7570
- const result = await manager.createWorktree(moduleUid, branchName, createBranch);
7587
+ const result = await manager.createWorktree(moduleUid, branchName, createBranch, detachedHead);
7571
7588
  if (!result.success) {
7572
7589
  return {
7573
7590
  success: false,
@@ -7963,6 +7980,35 @@ async function handleProjectSetup(params) {
7963
7980
  };
7964
7981
  }
7965
7982
  }
7983
+ async function handleFolderCleanup(projectPath, moduleUid) {
7984
+ if (!moduleUid || !UUID_REGEX.test(moduleUid)) {
7985
+ console.error(`[FolderCleanup] EP1226: Invalid moduleUid format: ${moduleUid}`);
7986
+ return { success: false, error: "Invalid moduleUid format" };
7987
+ }
7988
+ const folderPath = path17.join(projectPath, moduleUid);
7989
+ console.log(`[FolderCleanup] EP1226: Cleaning up module folder: ${folderPath}`);
7990
+ try {
7991
+ try {
7992
+ await fs16.promises.access(folderPath);
7993
+ } catch {
7994
+ console.log(`[FolderCleanup] EP1226: Module folder does not exist, nothing to clean: ${folderPath}`);
7995
+ return { success: true, folderPath };
7996
+ }
7997
+ await fs16.promises.rm(folderPath, { recursive: true, force: true });
7998
+ console.log(`[FolderCleanup] EP1226: Module folder removed: ${folderPath}`);
7999
+ return {
8000
+ success: true,
8001
+ folderPath
8002
+ };
8003
+ } catch (error) {
8004
+ const errorMessage = error instanceof Error ? error.message : String(error);
8005
+ console.error(`[FolderCleanup] EP1226: Cleanup failed:`, errorMessage);
8006
+ return {
8007
+ success: false,
8008
+ error: errorMessage
8009
+ };
8010
+ }
8011
+ }
7966
8012
 
7967
8013
  // src/daemon/handlers/stale-commit-cleanup.ts
7968
8014
  var import_child_process9 = require("child_process");
@@ -10433,6 +10479,10 @@ var Daemon = class _Daemon {
10433
10479
  case "project:setup":
10434
10480
  result = await handleProjectSetup(cmd);
10435
10481
  break;
10482
+ // EP1226: Module folder cleanup
10483
+ case "folder:cleanup":
10484
+ result = await handleFolderCleanup(projectPath, cmd.moduleUid);
10485
+ break;
10436
10486
  default:
10437
10487
  result = {
10438
10488
  success: false,
@@ -10611,6 +10661,15 @@ var Daemon = class _Daemon {
10611
10661
  } else {
10612
10662
  console.log(`[Daemon] EP1205: Worktree requested but not found for ${cmd.moduleUid}, using project root`);
10613
10663
  }
10664
+ } else if (cmd.sessionContext === "module_folder" && cmd.moduleUid) {
10665
+ const moduleFolderPath = path24.join(projectPath, cmd.moduleUid);
10666
+ try {
10667
+ await fs23.promises.mkdir(moduleFolderPath, { recursive: true });
10668
+ agentWorkingDir = moduleFolderPath;
10669
+ console.log(`[Daemon] EP1226: Agent for ${cmd.moduleUid} in module folder: ${agentWorkingDir}`);
10670
+ } catch (err) {
10671
+ console.error(`[Daemon] EP1226: Failed to create module folder ${moduleFolderPath}, using project root:`, err);
10672
+ }
10614
10673
  } else if (cmd.sessionContext === "project_root") {
10615
10674
  console.log(`[Daemon] EP1205: Agent for ${cmd.moduleUid || "project"} in project root (sessionContext=project_root)`);
10616
10675
  } else {