episoda 0.2.24 → 0.2.26

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.
package/dist/index.js CHANGED
@@ -1549,15 +1549,15 @@ var require_git_executor = __commonJS({
1549
1549
  try {
1550
1550
  const { stdout: gitDir } = await execAsync("git rev-parse --git-dir", { cwd, timeout: 5e3 });
1551
1551
  const gitDirPath = gitDir.trim();
1552
- const fs11 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1552
+ const fs12 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1553
1553
  const rebaseMergePath = `${gitDirPath}/rebase-merge`;
1554
1554
  const rebaseApplyPath = `${gitDirPath}/rebase-apply`;
1555
1555
  try {
1556
- await fs11.access(rebaseMergePath);
1556
+ await fs12.access(rebaseMergePath);
1557
1557
  inRebase = true;
1558
1558
  } catch {
1559
1559
  try {
1560
- await fs11.access(rebaseApplyPath);
1560
+ await fs12.access(rebaseApplyPath);
1561
1561
  inRebase = true;
1562
1562
  } catch {
1563
1563
  inRebase = false;
@@ -1611,9 +1611,9 @@ var require_git_executor = __commonJS({
1611
1611
  error: validation.error || "UNKNOWN_ERROR"
1612
1612
  };
1613
1613
  }
1614
- const fs11 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1614
+ const fs12 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1615
1615
  try {
1616
- await fs11.access(command.path);
1616
+ await fs12.access(command.path);
1617
1617
  return {
1618
1618
  success: false,
1619
1619
  error: "WORKTREE_EXISTS",
@@ -1664,9 +1664,9 @@ var require_git_executor = __commonJS({
1664
1664
  */
1665
1665
  async executeWorktreeRemove(command, cwd, options) {
1666
1666
  try {
1667
- const fs11 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1667
+ const fs12 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1668
1668
  try {
1669
- await fs11.access(command.path);
1669
+ await fs12.access(command.path);
1670
1670
  } catch {
1671
1671
  return {
1672
1672
  success: false,
@@ -1819,10 +1819,10 @@ var require_git_executor = __commonJS({
1819
1819
  */
1820
1820
  async executeCloneBare(command, options) {
1821
1821
  try {
1822
- const fs11 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1823
- const path13 = await Promise.resolve().then(() => __importStar(require("path")));
1822
+ const fs12 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1823
+ const path14 = await Promise.resolve().then(() => __importStar(require("path")));
1824
1824
  try {
1825
- await fs11.access(command.path);
1825
+ await fs12.access(command.path);
1826
1826
  return {
1827
1827
  success: false,
1828
1828
  error: "BRANCH_ALREADY_EXISTS",
@@ -1831,9 +1831,9 @@ var require_git_executor = __commonJS({
1831
1831
  };
1832
1832
  } catch {
1833
1833
  }
1834
- const parentDir = path13.dirname(command.path);
1834
+ const parentDir = path14.dirname(command.path);
1835
1835
  try {
1836
- await fs11.mkdir(parentDir, { recursive: true });
1836
+ await fs12.mkdir(parentDir, { recursive: true });
1837
1837
  } catch {
1838
1838
  }
1839
1839
  const { stdout, stderr } = await execAsync(
@@ -1876,22 +1876,22 @@ var require_git_executor = __commonJS({
1876
1876
  */
1877
1877
  async executeProjectInfo(cwd, options) {
1878
1878
  try {
1879
- const fs11 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1880
- const path13 = await Promise.resolve().then(() => __importStar(require("path")));
1879
+ const fs12 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
1880
+ const path14 = await Promise.resolve().then(() => __importStar(require("path")));
1881
1881
  let currentPath = cwd;
1882
1882
  let projectPath = cwd;
1883
1883
  let bareRepoPath;
1884
1884
  for (let i = 0; i < 10; i++) {
1885
- const bareDir = path13.join(currentPath, ".bare");
1886
- const episodaDir = path13.join(currentPath, ".episoda");
1885
+ const bareDir = path14.join(currentPath, ".bare");
1886
+ const episodaDir = path14.join(currentPath, ".episoda");
1887
1887
  try {
1888
- await fs11.access(bareDir);
1889
- await fs11.access(episodaDir);
1888
+ await fs12.access(bareDir);
1889
+ await fs12.access(episodaDir);
1890
1890
  projectPath = currentPath;
1891
1891
  bareRepoPath = bareDir;
1892
1892
  break;
1893
1893
  } catch {
1894
- const parentPath = path13.dirname(currentPath);
1894
+ const parentPath = path14.dirname(currentPath);
1895
1895
  if (parentPath === currentPath) {
1896
1896
  break;
1897
1897
  }
@@ -2485,31 +2485,31 @@ var require_auth = __commonJS({
2485
2485
  exports2.loadConfig = loadConfig6;
2486
2486
  exports2.saveConfig = saveConfig3;
2487
2487
  exports2.validateToken = validateToken;
2488
- var fs11 = __importStar(require("fs"));
2489
- var path13 = __importStar(require("path"));
2488
+ var fs12 = __importStar(require("fs"));
2489
+ var path14 = __importStar(require("path"));
2490
2490
  var os3 = __importStar(require("os"));
2491
2491
  var child_process_1 = require("child_process");
2492
2492
  var DEFAULT_CONFIG_FILE = "config.json";
2493
2493
  function getConfigDir5() {
2494
- return process.env.EPISODA_CONFIG_DIR || path13.join(os3.homedir(), ".episoda");
2494
+ return process.env.EPISODA_CONFIG_DIR || path14.join(os3.homedir(), ".episoda");
2495
2495
  }
2496
2496
  function getConfigPath4(configPath) {
2497
2497
  if (configPath) {
2498
2498
  return configPath;
2499
2499
  }
2500
- return path13.join(getConfigDir5(), DEFAULT_CONFIG_FILE);
2500
+ return path14.join(getConfigDir5(), DEFAULT_CONFIG_FILE);
2501
2501
  }
2502
2502
  function ensureConfigDir(configPath) {
2503
- const dir = path13.dirname(configPath);
2504
- const isNew = !fs11.existsSync(dir);
2503
+ const dir = path14.dirname(configPath);
2504
+ const isNew = !fs12.existsSync(dir);
2505
2505
  if (isNew) {
2506
- fs11.mkdirSync(dir, { recursive: true, mode: 448 });
2506
+ fs12.mkdirSync(dir, { recursive: true, mode: 448 });
2507
2507
  }
2508
2508
  if (process.platform === "darwin") {
2509
- const nosyncPath = path13.join(dir, ".nosync");
2510
- if (isNew || !fs11.existsSync(nosyncPath)) {
2509
+ const nosyncPath = path14.join(dir, ".nosync");
2510
+ if (isNew || !fs12.existsSync(nosyncPath)) {
2511
2511
  try {
2512
- fs11.writeFileSync(nosyncPath, "", { mode: 384 });
2512
+ fs12.writeFileSync(nosyncPath, "", { mode: 384 });
2513
2513
  (0, child_process_1.execSync)(`xattr -w com.apple.fileprovider.ignore 1 "${dir}"`, {
2514
2514
  stdio: "ignore",
2515
2515
  timeout: 5e3
@@ -2521,11 +2521,11 @@ var require_auth = __commonJS({
2521
2521
  }
2522
2522
  async function loadConfig6(configPath) {
2523
2523
  const fullPath = getConfigPath4(configPath);
2524
- if (!fs11.existsSync(fullPath)) {
2524
+ if (!fs12.existsSync(fullPath)) {
2525
2525
  return null;
2526
2526
  }
2527
2527
  try {
2528
- const content = fs11.readFileSync(fullPath, "utf8");
2528
+ const content = fs12.readFileSync(fullPath, "utf8");
2529
2529
  const config = JSON.parse(content);
2530
2530
  return config;
2531
2531
  } catch (error) {
@@ -2538,7 +2538,7 @@ var require_auth = __commonJS({
2538
2538
  ensureConfigDir(fullPath);
2539
2539
  try {
2540
2540
  const content = JSON.stringify(config, null, 2);
2541
- fs11.writeFileSync(fullPath, content, { mode: 384 });
2541
+ fs12.writeFileSync(fullPath, content, { mode: 384 });
2542
2542
  } catch (error) {
2543
2543
  throw new Error(`Failed to save config: ${error instanceof Error ? error.message : String(error)}`);
2544
2544
  }
@@ -3125,9 +3125,9 @@ async function getDevServerStatus() {
3125
3125
  }
3126
3126
 
3127
3127
  // src/commands/dev.ts
3128
- var import_child_process2 = require("child_process");
3129
- var path5 = __toESM(require("path"));
3130
- var fs4 = __toESM(require("fs"));
3128
+ var import_child_process3 = require("child_process");
3129
+ var path6 = __toESM(require("path"));
3130
+ var fs5 = __toESM(require("fs"));
3131
3131
 
3132
3132
  // src/utils/port-check.ts
3133
3133
  var net2 = __toESM(require("net"));
@@ -3784,7 +3784,7 @@ async function fetchProjectPath(config, projectId) {
3784
3784
  return null;
3785
3785
  }
3786
3786
  }
3787
- async function syncProjectPath(config, projectId, path13) {
3787
+ async function syncProjectPath(config, projectId, path14) {
3788
3788
  if (!config.device_id || !config.access_token) {
3789
3789
  return false;
3790
3790
  }
@@ -3797,7 +3797,7 @@ async function syncProjectPath(config, projectId, path13) {
3797
3797
  "Authorization": `Bearer ${config.access_token}`,
3798
3798
  "Content-Type": "application/json"
3799
3799
  },
3800
- body: JSON.stringify({ path: path13 })
3800
+ body: JSON.stringify({ path: path14 })
3801
3801
  });
3802
3802
  if (!response.ok) {
3803
3803
  console.debug(`[MachineSettings] syncProjectPath failed: ${response.status} ${response.statusText}`);
@@ -3809,11 +3809,35 @@ async function syncProjectPath(config, projectId, path13) {
3809
3809
  }
3810
3810
  }
3811
3811
 
3812
+ // src/utils/bootstrap.ts
3813
+ var fs4 = __toESM(require("fs"));
3814
+ var path5 = __toESM(require("path"));
3815
+ var import_child_process2 = require("child_process");
3816
+ async function extractBootstrapScripts(bareRepoPath, projectPath) {
3817
+ const scriptsDir = path5.join(projectPath, ".episoda", "scripts");
3818
+ const scriptPath = path5.join(scriptsDir, "api-helper.sh");
3819
+ if (fs4.existsSync(scriptPath)) {
3820
+ return false;
3821
+ }
3822
+ fs4.mkdirSync(scriptsDir, { recursive: true });
3823
+ try {
3824
+ const scriptContent = (0, import_child_process2.execSync)(
3825
+ `git --git-dir="${bareRepoPath}" show main:scripts/api-helper.sh`,
3826
+ { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
3827
+ );
3828
+ fs4.writeFileSync(scriptPath, scriptContent, { mode: 493 });
3829
+ return true;
3830
+ } catch (error) {
3831
+ console.log("[bootstrap] Could not extract api-helper.sh:", error);
3832
+ return false;
3833
+ }
3834
+ }
3835
+
3812
3836
  // src/commands/dev.ts
3813
3837
  var CONNECTION_MAX_RETRIES = 3;
3814
3838
  function findGitRoot(startDir) {
3815
3839
  try {
3816
- const result = (0, import_child_process2.execSync)("git rev-parse --show-toplevel", {
3840
+ const result = (0, import_child_process3.execSync)("git rev-parse --show-toplevel", {
3817
3841
  cwd: startDir,
3818
3842
  encoding: "utf-8",
3819
3843
  stdio: ["pipe", "pipe", "pipe"]
@@ -3869,12 +3893,12 @@ async function devCommand(options = {}) {
3869
3893
  }
3870
3894
  let projectPath;
3871
3895
  const serverPath = await fetchProjectPath(config, config.project_id);
3872
- if (serverPath && fs4.existsSync(serverPath)) {
3896
+ if (serverPath && fs5.existsSync(serverPath)) {
3873
3897
  projectPath = serverPath;
3874
3898
  status.debug(`Using server-synced project path: ${projectPath}`);
3875
3899
  } else {
3876
3900
  const detectedRoot = findGitRoot(options.cwd || process.cwd());
3877
- projectPath = detectedRoot || path5.resolve(options.cwd || process.cwd());
3901
+ projectPath = detectedRoot || path6.resolve(options.cwd || process.cwd());
3878
3902
  if (detectedRoot) {
3879
3903
  status.debug(`Detected project root: ${projectPath}`);
3880
3904
  } else {
@@ -3895,6 +3919,11 @@ async function devCommand(options = {}) {
3895
3919
  status.info("");
3896
3920
  process.exit(1);
3897
3921
  }
3922
+ const bareRepoPath = path6.join(projectPath, ".bare");
3923
+ const scriptsExtracted = await extractBootstrapScripts(bareRepoPath, projectPath);
3924
+ if (scriptsExtracted) {
3925
+ status.success("\u2713 Bootstrap scripts extracted");
3926
+ }
3898
3927
  let daemonPid = isDaemonRunning();
3899
3928
  if (!daemonPid) {
3900
3929
  status.info("Starting Episoda daemon...");
@@ -3987,7 +4016,7 @@ async function runDevServer(command, cwd, autoRestart) {
3987
4016
  let shuttingDown = false;
3988
4017
  const startServer = () => {
3989
4018
  status.info(`Starting dev server: ${command.join(" ")}`);
3990
- devProcess = (0, import_child_process2.spawn)(command[0], command.slice(1), {
4019
+ devProcess = (0, import_child_process3.spawn)(command[0], command.slice(1), {
3991
4020
  cwd,
3992
4021
  stdio: ["inherit", "inherit", "inherit"],
3993
4022
  shell: true
@@ -4040,33 +4069,33 @@ Received ${signal}, shutting down...`);
4040
4069
 
4041
4070
  // src/commands/auth.ts
4042
4071
  var os = __toESM(require("os"));
4043
- var fs6 = __toESM(require("fs"));
4044
- var path7 = __toESM(require("path"));
4045
- var import_child_process4 = require("child_process");
4072
+ var fs7 = __toESM(require("fs"));
4073
+ var path8 = __toESM(require("path"));
4074
+ var import_child_process5 = require("child_process");
4046
4075
  var import_core6 = __toESM(require_dist());
4047
4076
 
4048
4077
  // src/daemon/machine-id.ts
4049
- var fs5 = __toESM(require("fs"));
4050
- var path6 = __toESM(require("path"));
4078
+ var fs6 = __toESM(require("fs"));
4079
+ var path7 = __toESM(require("path"));
4051
4080
  var crypto2 = __toESM(require("crypto"));
4052
- var import_child_process3 = require("child_process");
4081
+ var import_child_process4 = require("child_process");
4053
4082
  var import_core5 = __toESM(require_dist());
4054
4083
  function isValidUUID(str) {
4055
4084
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4056
4085
  return uuidRegex.test(str);
4057
4086
  }
4058
4087
  async function getMachineId() {
4059
- const machineIdPath = path6.join((0, import_core5.getConfigDir)(), "machine-id");
4088
+ const machineIdPath = path7.join((0, import_core5.getConfigDir)(), "machine-id");
4060
4089
  try {
4061
- if (fs5.existsSync(machineIdPath)) {
4062
- const existingId = fs5.readFileSync(machineIdPath, "utf-8").trim();
4090
+ if (fs6.existsSync(machineIdPath)) {
4091
+ const existingId = fs6.readFileSync(machineIdPath, "utf-8").trim();
4063
4092
  if (existingId) {
4064
4093
  if (isValidUUID(existingId)) {
4065
4094
  return existingId;
4066
4095
  }
4067
4096
  console.log("[MachineId] Migrating legacy machine ID to UUID format...");
4068
4097
  const newUUID = generateMachineId();
4069
- fs5.writeFileSync(machineIdPath, newUUID, "utf-8");
4098
+ fs6.writeFileSync(machineIdPath, newUUID, "utf-8");
4070
4099
  console.log(`[MachineId] Migrated: ${existingId} \u2192 ${newUUID}`);
4071
4100
  return newUUID;
4072
4101
  }
@@ -4075,11 +4104,11 @@ async function getMachineId() {
4075
4104
  }
4076
4105
  const machineId = generateMachineId();
4077
4106
  try {
4078
- const dir = path6.dirname(machineIdPath);
4079
- if (!fs5.existsSync(dir)) {
4080
- fs5.mkdirSync(dir, { recursive: true });
4107
+ const dir = path7.dirname(machineIdPath);
4108
+ if (!fs6.existsSync(dir)) {
4109
+ fs6.mkdirSync(dir, { recursive: true });
4081
4110
  }
4082
- fs5.writeFileSync(machineIdPath, machineId, "utf-8");
4111
+ fs6.writeFileSync(machineIdPath, machineId, "utf-8");
4083
4112
  } catch (error) {
4084
4113
  console.error("Warning: Could not save machine ID to disk:", error);
4085
4114
  }
@@ -4088,7 +4117,7 @@ async function getMachineId() {
4088
4117
  function getHardwareUUID() {
4089
4118
  try {
4090
4119
  if (process.platform === "darwin") {
4091
- const output = (0, import_child_process3.execSync)(
4120
+ const output = (0, import_child_process4.execSync)(
4092
4121
  `ioreg -d2 -c IOPlatformExpertDevice | awk -F\\" '/IOPlatformUUID/{print $(NF-1)}'`,
4093
4122
  { encoding: "utf-8", timeout: 5e3 }
4094
4123
  ).trim();
@@ -4096,20 +4125,20 @@ function getHardwareUUID() {
4096
4125
  return output;
4097
4126
  }
4098
4127
  } else if (process.platform === "linux") {
4099
- if (fs5.existsSync("/etc/machine-id")) {
4100
- const machineId = fs5.readFileSync("/etc/machine-id", "utf-8").trim();
4128
+ if (fs6.existsSync("/etc/machine-id")) {
4129
+ const machineId = fs6.readFileSync("/etc/machine-id", "utf-8").trim();
4101
4130
  if (machineId && machineId.length > 0) {
4102
4131
  return machineId;
4103
4132
  }
4104
4133
  }
4105
- if (fs5.existsSync("/var/lib/dbus/machine-id")) {
4106
- const dbusId = fs5.readFileSync("/var/lib/dbus/machine-id", "utf-8").trim();
4134
+ if (fs6.existsSync("/var/lib/dbus/machine-id")) {
4135
+ const dbusId = fs6.readFileSync("/var/lib/dbus/machine-id", "utf-8").trim();
4107
4136
  if (dbusId && dbusId.length > 0) {
4108
4137
  return dbusId;
4109
4138
  }
4110
4139
  }
4111
4140
  } else if (process.platform === "win32") {
4112
- const output = (0, import_child_process3.execSync)("wmic csproduct get uuid", {
4141
+ const output = (0, import_child_process4.execSync)("wmic csproduct get uuid", {
4113
4142
  encoding: "utf-8",
4114
4143
  timeout: 5e3
4115
4144
  });
@@ -4548,7 +4577,7 @@ async function monitorAuthorization(apiUrl, deviceCode, expiresIn) {
4548
4577
  resolve4(false);
4549
4578
  }, expiresIn * 1e3);
4550
4579
  const url = `${apiUrl}/api/oauth/authorize-stream?device_code=${deviceCode}`;
4551
- const curlProcess = (0, import_child_process4.spawn)("curl", ["-N", url]);
4580
+ const curlProcess = (0, import_child_process5.spawn)("curl", ["-N", url]);
4552
4581
  let buffer = "";
4553
4582
  curlProcess.stdout.on("data", (chunk) => {
4554
4583
  buffer += chunk.toString();
@@ -4652,7 +4681,7 @@ function openBrowser(url) {
4652
4681
  break;
4653
4682
  }
4654
4683
  try {
4655
- (0, import_child_process4.spawn)(command, args, {
4684
+ (0, import_child_process5.spawn)(command, args, {
4656
4685
  detached: true,
4657
4686
  stdio: "ignore"
4658
4687
  }).unref();
@@ -4663,17 +4692,17 @@ function openBrowser(url) {
4663
4692
  async function installGitCredentialHelper(apiUrl) {
4664
4693
  try {
4665
4694
  const homeDir = os.homedir();
4666
- const episodaBinDir = path7.join(homeDir, ".episoda", "bin");
4667
- const helperPath = path7.join(episodaBinDir, "git-credential-episoda");
4668
- fs6.mkdirSync(episodaBinDir, { recursive: true });
4695
+ const episodaBinDir = path8.join(homeDir, ".episoda", "bin");
4696
+ const helperPath = path8.join(episodaBinDir, "git-credential-episoda");
4697
+ fs7.mkdirSync(episodaBinDir, { recursive: true });
4669
4698
  const scriptContent = generateCredentialHelperScript(apiUrl);
4670
- fs6.writeFileSync(helperPath, scriptContent, { mode: 493 });
4699
+ fs7.writeFileSync(helperPath, scriptContent, { mode: 493 });
4671
4700
  try {
4672
- fs6.accessSync(helperPath, fs6.constants.X_OK);
4701
+ fs7.accessSync(helperPath, fs7.constants.X_OK);
4673
4702
  } catch {
4674
4703
  }
4675
4704
  try {
4676
- const allHelpers = (0, import_child_process4.execSync)("git config --global --get-all credential.helper", {
4705
+ const allHelpers = (0, import_child_process5.execSync)("git config --global --get-all credential.helper", {
4677
4706
  encoding: "utf8",
4678
4707
  stdio: ["pipe", "pipe", "pipe"]
4679
4708
  }).trim().split("\n");
@@ -4682,7 +4711,7 @@ async function installGitCredentialHelper(apiUrl) {
4682
4711
  }
4683
4712
  } catch {
4684
4713
  }
4685
- (0, import_child_process4.execSync)(`git config --global --add credential.helper "${helperPath}"`, {
4714
+ (0, import_child_process5.execSync)(`git config --global --add credential.helper "${helperPath}"`, {
4686
4715
  encoding: "utf8",
4687
4716
  stdio: ["pipe", "pipe", "pipe"]
4688
4717
  });
@@ -4700,19 +4729,19 @@ function updateShellProfile(binDir) {
4700
4729
  }
4701
4730
  const homeDir = os.homedir();
4702
4731
  const profiles = [
4703
- path7.join(homeDir, ".bashrc"),
4704
- path7.join(homeDir, ".zshrc"),
4705
- path7.join(homeDir, ".profile")
4732
+ path8.join(homeDir, ".bashrc"),
4733
+ path8.join(homeDir, ".zshrc"),
4734
+ path8.join(homeDir, ".profile")
4706
4735
  ];
4707
4736
  const exportLine = `export PATH="${binDir}:$PATH" # Added by episoda auth`;
4708
4737
  for (const profile of profiles) {
4709
4738
  try {
4710
- if (fs6.existsSync(profile)) {
4711
- const content = fs6.readFileSync(profile, "utf8");
4739
+ if (fs7.existsSync(profile)) {
4740
+ const content = fs7.readFileSync(profile, "utf8");
4712
4741
  if (content.includes(".episoda/bin")) {
4713
4742
  continue;
4714
4743
  }
4715
- fs6.appendFileSync(profile, `
4744
+ fs7.appendFileSync(profile, `
4716
4745
  # Episoda CLI
4717
4746
  ${exportLine}
4718
4747
  `);
@@ -4724,9 +4753,9 @@ ${exportLine}
4724
4753
 
4725
4754
  // src/commands/connect.ts
4726
4755
  var os2 = __toESM(require("os"));
4727
- var fs7 = __toESM(require("fs"));
4728
- var path8 = __toESM(require("path"));
4729
- var import_child_process5 = require("child_process");
4756
+ var fs8 = __toESM(require("fs"));
4757
+ var path9 = __toESM(require("path"));
4758
+ var import_child_process6 = require("child_process");
4730
4759
  var import_core7 = __toESM(require_dist());
4731
4760
  async function connectCommand(options) {
4732
4761
  const { code } = options;
@@ -4800,13 +4829,13 @@ async function exchangeUserCode(apiUrl, userCode, machineId) {
4800
4829
  async function installGitCredentialHelper2(apiUrl) {
4801
4830
  try {
4802
4831
  const homeDir = os2.homedir();
4803
- const episodaBinDir = path8.join(homeDir, ".episoda", "bin");
4804
- const helperPath = path8.join(episodaBinDir, "git-credential-episoda");
4805
- fs7.mkdirSync(episodaBinDir, { recursive: true });
4832
+ const episodaBinDir = path9.join(homeDir, ".episoda", "bin");
4833
+ const helperPath = path9.join(episodaBinDir, "git-credential-episoda");
4834
+ fs8.mkdirSync(episodaBinDir, { recursive: true });
4806
4835
  const scriptContent = generateCredentialHelperScript(apiUrl);
4807
- fs7.writeFileSync(helperPath, scriptContent, { mode: 493 });
4836
+ fs8.writeFileSync(helperPath, scriptContent, { mode: 493 });
4808
4837
  try {
4809
- const allHelpers = (0, import_child_process5.execSync)("git config --global --get-all credential.helper", {
4838
+ const allHelpers = (0, import_child_process6.execSync)("git config --global --get-all credential.helper", {
4810
4839
  encoding: "utf8",
4811
4840
  stdio: ["pipe", "pipe", "pipe"]
4812
4841
  }).trim().split("\n");
@@ -4815,7 +4844,7 @@ async function installGitCredentialHelper2(apiUrl) {
4815
4844
  }
4816
4845
  } catch {
4817
4846
  }
4818
- (0, import_child_process5.execSync)(`git config --global --add credential.helper "${helperPath}"`, {
4847
+ (0, import_child_process6.execSync)(`git config --global --add credential.helper "${helperPath}"`, {
4819
4848
  encoding: "utf8",
4820
4849
  stdio: ["pipe", "pipe", "pipe"]
4821
4850
  });
@@ -4833,19 +4862,19 @@ function updateShellProfile2(binDir) {
4833
4862
  }
4834
4863
  const homeDir = os2.homedir();
4835
4864
  const profiles = [
4836
- path8.join(homeDir, ".bashrc"),
4837
- path8.join(homeDir, ".zshrc"),
4838
- path8.join(homeDir, ".profile")
4865
+ path9.join(homeDir, ".bashrc"),
4866
+ path9.join(homeDir, ".zshrc"),
4867
+ path9.join(homeDir, ".profile")
4839
4868
  ];
4840
4869
  const exportLine = `export PATH="${binDir}:$PATH" # Added by episoda`;
4841
4870
  for (const profile of profiles) {
4842
4871
  try {
4843
- if (fs7.existsSync(profile)) {
4844
- const content = fs7.readFileSync(profile, "utf8");
4872
+ if (fs8.existsSync(profile)) {
4873
+ const content = fs8.readFileSync(profile, "utf8");
4845
4874
  if (content.includes(".episoda/bin")) {
4846
4875
  continue;
4847
4876
  }
4848
- fs7.appendFileSync(profile, `
4877
+ fs8.appendFileSync(profile, `
4849
4878
  # Episoda CLI
4850
4879
  ${exportLine}
4851
4880
  `);
@@ -5036,25 +5065,24 @@ async function stopCommand(options = {}) {
5036
5065
  }
5037
5066
 
5038
5067
  // src/commands/clone.ts
5039
- var fs9 = __toESM(require("fs"));
5040
- var path10 = __toESM(require("path"));
5041
- var import_child_process6 = require("child_process");
5068
+ var fs10 = __toESM(require("fs"));
5069
+ var path11 = __toESM(require("path"));
5042
5070
  var import_core10 = __toESM(require_dist());
5043
5071
 
5044
5072
  // src/daemon/project-tracker.ts
5045
- var fs8 = __toESM(require("fs"));
5046
- var path9 = __toESM(require("path"));
5073
+ var fs9 = __toESM(require("fs"));
5074
+ var path10 = __toESM(require("path"));
5047
5075
  var import_core9 = __toESM(require_dist());
5048
5076
  function getProjectsFilePath() {
5049
- return path9.join((0, import_core9.getConfigDir)(), "projects.json");
5077
+ return path10.join((0, import_core9.getConfigDir)(), "projects.json");
5050
5078
  }
5051
5079
  function readProjects() {
5052
5080
  const projectsPath = getProjectsFilePath();
5053
5081
  try {
5054
- if (!fs8.existsSync(projectsPath)) {
5082
+ if (!fs9.existsSync(projectsPath)) {
5055
5083
  return { projects: [] };
5056
5084
  }
5057
- const content = fs8.readFileSync(projectsPath, "utf-8");
5085
+ const content = fs9.readFileSync(projectsPath, "utf-8");
5058
5086
  const data = JSON.parse(content);
5059
5087
  if (!data.projects || !Array.isArray(data.projects)) {
5060
5088
  console.warn("Invalid projects.json structure, resetting");
@@ -5069,11 +5097,11 @@ function readProjects() {
5069
5097
  function writeProjects(data) {
5070
5098
  const projectsPath = getProjectsFilePath();
5071
5099
  try {
5072
- const dir = path9.dirname(projectsPath);
5073
- if (!fs8.existsSync(dir)) {
5074
- fs8.mkdirSync(dir, { recursive: true });
5100
+ const dir = path10.dirname(projectsPath);
5101
+ if (!fs9.existsSync(dir)) {
5102
+ fs9.mkdirSync(dir, { recursive: true });
5075
5103
  }
5076
- fs8.writeFileSync(projectsPath, JSON.stringify(data, null, 2), "utf-8");
5104
+ fs9.writeFileSync(projectsPath, JSON.stringify(data, null, 2), "utf-8");
5077
5105
  } catch (error) {
5078
5106
  throw new Error(`Failed to write projects.json: ${error}`);
5079
5107
  }
@@ -5097,7 +5125,7 @@ function addProject2(projectId, projectPath, options) {
5097
5125
  console.log(`[ProjectTracker] Replacing project entry: ${existingById.path} -> ${projectPath}`);
5098
5126
  data.projects.splice(existingByIdIndex, 1);
5099
5127
  }
5100
- const projectName = path9.basename(projectPath);
5128
+ const projectName = path10.basename(projectPath);
5101
5129
  const newProject = {
5102
5130
  id: projectId,
5103
5131
  path: projectPath,
@@ -5131,9 +5159,9 @@ async function cloneCommand(slugArg, options = {}) {
5131
5159
  }
5132
5160
  const apiUrl = options.apiUrl || config.api_url || "https://episoda.dev";
5133
5161
  const projectPath = getProjectPath(workspaceSlug, projectSlug);
5134
- if (fs9.existsSync(projectPath)) {
5135
- const bareRepoPath = path10.join(projectPath, ".bare");
5136
- if (fs9.existsSync(bareRepoPath)) {
5162
+ if (fs10.existsSync(projectPath)) {
5163
+ const bareRepoPath = path11.join(projectPath, ".bare");
5164
+ if (fs10.existsSync(bareRepoPath)) {
5137
5165
  status.warning(`Project already cloned at ${projectPath}`);
5138
5166
  status.info("");
5139
5167
  status.info("Next steps:");
@@ -5165,7 +5193,7 @@ Please configure a repository in the project settings on episoda.dev.`
5165
5193
  status.info("");
5166
5194
  status.info("Creating project directory...");
5167
5195
  const episodaRoot = getEpisodaRoot();
5168
- fs9.mkdirSync(projectPath, { recursive: true });
5196
+ fs10.mkdirSync(projectPath, { recursive: true });
5169
5197
  status.success(`\u2713 Created ${projectPath}`);
5170
5198
  status.info("Cloning repository (bare)...");
5171
5199
  try {
@@ -5203,9 +5231,9 @@ Please configure a repository in the project settings on episoda.dev.`
5203
5231
  status.info(" 3. episoda checkout {moduleUid} # e.g., episoda checkout EP100");
5204
5232
  status.info("");
5205
5233
  } catch (error) {
5206
- if (fs9.existsSync(projectPath)) {
5234
+ if (fs10.existsSync(projectPath)) {
5207
5235
  try {
5208
- fs9.rmSync(projectPath, { recursive: true, force: true });
5236
+ fs10.rmSync(projectPath, { recursive: true, force: true });
5209
5237
  } catch {
5210
5238
  }
5211
5239
  }
@@ -5278,20 +5306,6 @@ ${errorBody}`
5278
5306
  }
5279
5307
  return data;
5280
5308
  }
5281
- async function extractBootstrapScripts(bareRepoPath, projectPath) {
5282
- const scriptsDir = path10.join(projectPath, ".episoda", "scripts");
5283
- fs9.mkdirSync(scriptsDir, { recursive: true });
5284
- try {
5285
- const scriptContent = (0, import_child_process6.execSync)(
5286
- `git --git-dir="${bareRepoPath}" show main:scripts/api-helper.sh`,
5287
- { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
5288
- );
5289
- const scriptPath = path10.join(scriptsDir, "api-helper.sh");
5290
- fs9.writeFileSync(scriptPath, scriptContent, { mode: 493 });
5291
- } catch (error) {
5292
- console.log("[clone] Could not extract api-helper.sh:", error);
5293
- }
5294
- }
5295
5309
 
5296
5310
  // src/commands/checkout.ts
5297
5311
  var import_core11 = __toESM(require_dist());
@@ -5471,7 +5485,7 @@ async function updateModuleCheckout(apiUrl, moduleId, accessToken, branchName) {
5471
5485
  }
5472
5486
 
5473
5487
  // src/commands/release.ts
5474
- var path11 = __toESM(require("path"));
5488
+ var path12 = __toESM(require("path"));
5475
5489
  var import_core12 = __toESM(require_dist());
5476
5490
  async function releaseCommand(moduleUid, options = {}) {
5477
5491
  if (!moduleUid || !moduleUid.match(/^EP\d+$/)) {
@@ -5518,7 +5532,7 @@ Commit or stash your changes first, or use --force to discard them.`
5518
5532
  );
5519
5533
  }
5520
5534
  }
5521
- const currentPath = path11.resolve(process.cwd());
5535
+ const currentPath = path12.resolve(process.cwd());
5522
5536
  if (currentPath.startsWith(existing.worktreePath)) {
5523
5537
  status.warning("You are inside the worktree being released.");
5524
5538
  status.info(`Please cd to ${projectRoot} first.`);
@@ -5592,8 +5606,8 @@ async function updateModuleRelease(apiUrl, projectId, workspaceSlug, moduleUid,
5592
5606
  }
5593
5607
 
5594
5608
  // src/commands/list.ts
5595
- var fs10 = __toESM(require("fs"));
5596
- var path12 = __toESM(require("path"));
5609
+ var fs11 = __toESM(require("fs"));
5610
+ var path13 = __toESM(require("path"));
5597
5611
  var import_chalk2 = __toESM(require("chalk"));
5598
5612
  var import_core13 = __toESM(require_dist());
5599
5613
  async function listCommand(subcommand, options = {}) {
@@ -5605,7 +5619,7 @@ async function listCommand(subcommand, options = {}) {
5605
5619
  }
5606
5620
  async function listProjects(options) {
5607
5621
  const episodaRoot = getEpisodaRoot();
5608
- if (!fs10.existsSync(episodaRoot)) {
5622
+ if (!fs11.existsSync(episodaRoot)) {
5609
5623
  status.info("No projects cloned yet.");
5610
5624
  status.info("");
5611
5625
  status.info("Clone a project with:");
@@ -5613,12 +5627,12 @@ async function listProjects(options) {
5613
5627
  return;
5614
5628
  }
5615
5629
  const projects = [];
5616
- const workspaces = fs10.readdirSync(episodaRoot, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("."));
5630
+ const workspaces = fs11.readdirSync(episodaRoot, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("."));
5617
5631
  for (const workspace of workspaces) {
5618
- const workspacePath = path12.join(episodaRoot, workspace.name);
5619
- const projectDirs = fs10.readdirSync(workspacePath, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("."));
5632
+ const workspacePath = path13.join(episodaRoot, workspace.name);
5633
+ const projectDirs = fs11.readdirSync(workspacePath, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("."));
5620
5634
  for (const projectDir of projectDirs) {
5621
- const projectPath = path12.join(workspacePath, projectDir.name);
5635
+ const projectPath = path13.join(workspacePath, projectDir.name);
5622
5636
  if (await isWorktreeProject(projectPath)) {
5623
5637
  const manager = new WorktreeManager(projectPath);
5624
5638
  await manager.initialize();