@locusai/sdk 0.9.4 → 0.9.5

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.
@@ -547,7 +547,7 @@ function getAgentArtifactsPath(projectPath, agentId) {
547
547
 
548
548
  // src/ai/claude-runner.ts
549
549
  var import_node_child_process = require("node:child_process");
550
- var import_node_path2 = require("node:path");
550
+ var import_node_path3 = require("node:path");
551
551
 
552
552
  // src/utils/colors.ts
553
553
  var ESC = "\x1B[";
@@ -611,6 +611,47 @@ var c = {
611
611
  underline: (t) => c.text(t, "underline")
612
612
  };
613
613
 
614
+ // src/utils/resolve-bin.ts
615
+ var import_node_fs = require("node:fs");
616
+ var import_node_os = require("node:os");
617
+ var import_node_path2 = require("node:path");
618
+ var EXTRA_BIN_DIRS = [
619
+ import_node_path2.join(import_node_os.homedir(), ".local", "bin"),
620
+ import_node_path2.join(import_node_os.homedir(), ".npm", "bin"),
621
+ import_node_path2.join(import_node_os.homedir(), ".npm-global", "bin"),
622
+ import_node_path2.join(import_node_os.homedir(), ".yarn", "bin"),
623
+ "/usr/local/bin"
624
+ ];
625
+ function getNodeManagerDirs() {
626
+ const dirs = [];
627
+ const nvmDir = process.env.NVM_DIR || import_node_path2.join(import_node_os.homedir(), ".nvm");
628
+ const nvmCurrent = import_node_path2.join(nvmDir, "current", "bin");
629
+ if (import_node_fs.existsSync(nvmCurrent)) {
630
+ dirs.push(nvmCurrent);
631
+ }
632
+ const fnmDir = process.env.FNM_DIR || import_node_path2.join(import_node_os.homedir(), ".fnm");
633
+ const fnmCurrent = import_node_path2.join(fnmDir, "current", "bin");
634
+ if (import_node_fs.existsSync(fnmCurrent)) {
635
+ dirs.push(fnmCurrent);
636
+ }
637
+ return dirs;
638
+ }
639
+ function getAugmentedPath() {
640
+ const currentPath = process.env.PATH || "";
641
+ const currentDirs = new Set(currentPath.split(import_node_path2.delimiter));
642
+ const extra = [...EXTRA_BIN_DIRS, ...getNodeManagerDirs()].filter((dir) => !currentDirs.has(dir) && import_node_fs.existsSync(dir));
643
+ if (extra.length === 0)
644
+ return currentPath;
645
+ return currentPath + import_node_path2.delimiter + extra.join(import_node_path2.delimiter);
646
+ }
647
+ function getAugmentedEnv(overrides = {}) {
648
+ return {
649
+ ...process.env,
650
+ ...overrides,
651
+ PATH: getAugmentedPath()
652
+ };
653
+ }
654
+
614
655
  // src/ai/claude-runner.ts
615
656
  var SANDBOX_SETTINGS = JSON.stringify({
616
657
  sandbox: {
@@ -631,7 +672,7 @@ class ClaudeRunner {
631
672
  constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CLAUDE], log) {
632
673
  this.model = model;
633
674
  this.log = log;
634
- this.projectPath = import_node_path2.resolve(projectPath);
675
+ this.projectPath = import_node_path3.resolve(projectPath);
635
676
  }
636
677
  setEventEmitter(emitter) {
637
678
  this.eventEmitter = emitter;
@@ -674,11 +715,10 @@ class ClaudeRunner {
674
715
  "--settings",
675
716
  SANDBOX_SETTINGS
676
717
  ];
677
- const env = {
678
- ...process.env,
718
+ const env = getAugmentedEnv({
679
719
  FORCE_COLOR: "1",
680
720
  TERM: "xterm-256color"
681
- };
721
+ });
682
722
  this.eventEmitter?.emitSessionStarted({
683
723
  model: this.model,
684
724
  provider: "claude"
@@ -919,11 +959,10 @@ class ClaudeRunner {
919
959
  "--settings",
920
960
  SANDBOX_SETTINGS
921
961
  ];
922
- const env = {
923
- ...process.env,
962
+ const env = getAugmentedEnv({
924
963
  FORCE_COLOR: "1",
925
964
  TERM: "xterm-256color"
926
- };
965
+ });
927
966
  const claude = import_node_child_process.spawn("claude", args, {
928
967
  cwd: this.projectPath,
929
968
  stdio: ["pipe", "pipe", "pipe"],
@@ -1023,9 +1062,9 @@ ${c.primary("[Claude]")} ${c.bold(`Running ${content_block.name}...`)}
1023
1062
  // src/ai/codex-runner.ts
1024
1063
  var import_node_child_process2 = require("node:child_process");
1025
1064
  var import_node_crypto = require("node:crypto");
1026
- var import_node_fs = require("node:fs");
1027
- var import_node_os = require("node:os");
1028
- var import_node_path3 = require("node:path");
1065
+ var import_node_fs2 = require("node:fs");
1066
+ var import_node_os2 = require("node:os");
1067
+ var import_node_path4 = require("node:path");
1029
1068
  class CodexRunner {
1030
1069
  projectPath;
1031
1070
  model;
@@ -1060,12 +1099,12 @@ class CodexRunner {
1060
1099
  throw lastError || new Error("Codex CLI failed after multiple attempts");
1061
1100
  }
1062
1101
  async* runStream(prompt) {
1063
- const outputPath = import_node_path3.join(import_node_os.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1102
+ const outputPath = import_node_path4.join(import_node_os2.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1064
1103
  const args = this.buildArgs(outputPath);
1065
1104
  const codex = import_node_child_process2.spawn("codex", args, {
1066
1105
  cwd: this.projectPath,
1067
1106
  stdio: ["pipe", "pipe", "pipe"],
1068
- env: process.env,
1107
+ env: getAugmentedEnv(),
1069
1108
  shell: false
1070
1109
  });
1071
1110
  this.activeProcess = codex;
@@ -1156,12 +1195,12 @@ class CodexRunner {
1156
1195
  }
1157
1196
  executeRun(prompt) {
1158
1197
  return new Promise((resolve2, reject) => {
1159
- const outputPath = import_node_path3.join(import_node_os.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1198
+ const outputPath = import_node_path4.join(import_node_os2.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1160
1199
  const args = this.buildArgs(outputPath);
1161
1200
  const codex = import_node_child_process2.spawn("codex", args, {
1162
1201
  cwd: this.projectPath,
1163
1202
  stdio: ["pipe", "pipe", "pipe"],
1164
- env: process.env,
1203
+ env: getAugmentedEnv(),
1165
1204
  shell: false
1166
1205
  });
1167
1206
  this.activeProcess = codex;
@@ -1228,9 +1267,9 @@ class CodexRunner {
1228
1267
  ].some((pattern) => pattern.test(line));
1229
1268
  }
1230
1269
  readOutput(outputPath, fallback) {
1231
- if (import_node_fs.existsSync(outputPath)) {
1270
+ if (import_node_fs2.existsSync(outputPath)) {
1232
1271
  try {
1233
- const text = import_node_fs.readFileSync(outputPath, "utf-8").trim();
1272
+ const text = import_node_fs2.readFileSync(outputPath, "utf-8").trim();
1234
1273
  if (text)
1235
1274
  return text;
1236
1275
  } catch {}
@@ -1244,8 +1283,8 @@ class CodexRunner {
1244
1283
  }
1245
1284
  cleanupTempFile(path) {
1246
1285
  try {
1247
- if (import_node_fs.existsSync(path))
1248
- import_node_fs.unlinkSync(path);
1286
+ if (import_node_fs2.existsSync(path))
1287
+ import_node_fs2.unlinkSync(path);
1249
1288
  } catch {}
1250
1289
  }
1251
1290
  sleep(ms) {
@@ -1591,8 +1630,8 @@ class PrService {
1591
1630
  }
1592
1631
 
1593
1632
  // src/project/knowledge-base.ts
1594
- var import_node_fs2 = require("node:fs");
1595
- var import_node_path4 = require("node:path");
1633
+ var import_node_fs3 = require("node:fs");
1634
+ var import_node_path5 = require("node:path");
1596
1635
  class KnowledgeBase {
1597
1636
  contextPath;
1598
1637
  progressPath;
@@ -1601,20 +1640,20 @@ class KnowledgeBase {
1601
1640
  this.progressPath = getLocusPath(projectPath, "projectProgressFile");
1602
1641
  }
1603
1642
  readContext() {
1604
- if (!import_node_fs2.existsSync(this.contextPath)) {
1643
+ if (!import_node_fs3.existsSync(this.contextPath)) {
1605
1644
  return "";
1606
1645
  }
1607
- return import_node_fs2.readFileSync(this.contextPath, "utf-8");
1646
+ return import_node_fs3.readFileSync(this.contextPath, "utf-8");
1608
1647
  }
1609
1648
  readProgress() {
1610
- if (!import_node_fs2.existsSync(this.progressPath)) {
1649
+ if (!import_node_fs3.existsSync(this.progressPath)) {
1611
1650
  return "";
1612
1651
  }
1613
- return import_node_fs2.readFileSync(this.progressPath, "utf-8");
1652
+ return import_node_fs3.readFileSync(this.progressPath, "utf-8");
1614
1653
  }
1615
1654
  updateContext(content) {
1616
1655
  this.ensureDir(this.contextPath);
1617
- import_node_fs2.writeFileSync(this.contextPath, content);
1656
+ import_node_fs3.writeFileSync(this.contextPath, content);
1618
1657
  }
1619
1658
  updateProgress(event) {
1620
1659
  this.ensureDir(this.progressPath);
@@ -1660,7 +1699,7 @@ class KnowledgeBase {
1660
1699
  ${entry}` : `# Project Progress
1661
1700
 
1662
1701
  ${entry}`;
1663
- import_node_fs2.writeFileSync(this.progressPath, updated);
1702
+ import_node_fs3.writeFileSync(this.progressPath, updated);
1664
1703
  }
1665
1704
  getFullContext() {
1666
1705
  const context = this.readContext();
@@ -1704,24 +1743,24 @@ ${techStackList}
1704
1743
 
1705
1744
  No sprints started yet.
1706
1745
  `;
1707
- import_node_fs2.writeFileSync(this.contextPath, contextContent);
1708
- import_node_fs2.writeFileSync(this.progressPath, progressContent);
1746
+ import_node_fs3.writeFileSync(this.contextPath, contextContent);
1747
+ import_node_fs3.writeFileSync(this.progressPath, progressContent);
1709
1748
  }
1710
1749
  get exists() {
1711
- return import_node_fs2.existsSync(this.contextPath) || import_node_fs2.existsSync(this.progressPath);
1750
+ return import_node_fs3.existsSync(this.contextPath) || import_node_fs3.existsSync(this.progressPath);
1712
1751
  }
1713
1752
  ensureDir(filePath) {
1714
- const dir = import_node_path4.dirname(filePath);
1715
- if (!import_node_fs2.existsSync(dir)) {
1716
- import_node_fs2.mkdirSync(dir, { recursive: true });
1753
+ const dir = import_node_path5.dirname(filePath);
1754
+ if (!import_node_fs3.existsSync(dir)) {
1755
+ import_node_fs3.mkdirSync(dir, { recursive: true });
1717
1756
  }
1718
1757
  }
1719
1758
  }
1720
1759
 
1721
1760
  // src/worktree/worktree-manager.ts
1722
1761
  var import_node_child_process5 = require("node:child_process");
1723
- var import_node_fs3 = require("node:fs");
1724
- var import_node_path5 = require("node:path");
1762
+ var import_node_fs4 = require("node:fs");
1763
+ var import_node_path6 = require("node:path");
1725
1764
 
1726
1765
  // src/worktree/worktree-config.ts
1727
1766
  var WORKTREE_ROOT_DIR = ".locus-worktrees";
@@ -1738,14 +1777,14 @@ class WorktreeManager {
1738
1777
  projectPath;
1739
1778
  log;
1740
1779
  constructor(projectPath, config, log) {
1741
- this.projectPath = import_node_path5.resolve(projectPath);
1780
+ this.projectPath = import_node_path6.resolve(projectPath);
1742
1781
  this.config = { ...DEFAULT_WORKTREE_CONFIG, ...config };
1743
1782
  this.log = log ?? ((_msg) => {
1744
1783
  return;
1745
1784
  });
1746
1785
  }
1747
1786
  get rootPath() {
1748
- return import_node_path5.join(this.projectPath, this.config.rootDir);
1787
+ return import_node_path6.join(this.projectPath, this.config.rootDir);
1749
1788
  }
1750
1789
  buildBranchName(taskId, taskSlug) {
1751
1790
  const sanitized = taskSlug.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50);
@@ -1754,16 +1793,16 @@ class WorktreeManager {
1754
1793
  create(options) {
1755
1794
  const branch = this.buildBranchName(options.taskId, options.taskSlug);
1756
1795
  const worktreeDir = `${options.agentId}-${options.taskId}`;
1757
- const worktreePath = import_node_path5.join(this.rootPath, worktreeDir);
1796
+ const worktreePath = import_node_path6.join(this.rootPath, worktreeDir);
1758
1797
  this.ensureDirectory(this.rootPath, "Worktree root");
1759
1798
  const baseBranch = options.baseBranch ?? this.config.baseBranch ?? this.getCurrentBranch();
1760
1799
  this.log(`Creating worktree: ${worktreeDir} (branch: ${branch}, base: ${baseBranch})`, "info");
1761
- if (import_node_fs3.existsSync(worktreePath)) {
1800
+ if (import_node_fs4.existsSync(worktreePath)) {
1762
1801
  this.log(`Removing stale worktree directory: ${worktreePath}`, "warn");
1763
1802
  try {
1764
1803
  this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
1765
1804
  } catch {
1766
- import_node_fs3.rmSync(worktreePath, { recursive: true, force: true });
1805
+ import_node_fs4.rmSync(worktreePath, { recursive: true, force: true });
1767
1806
  this.git("worktree prune", this.projectPath);
1768
1807
  }
1769
1808
  }
@@ -1771,7 +1810,7 @@ class WorktreeManager {
1771
1810
  this.log(`Deleting existing branch: ${branch}`, "warn");
1772
1811
  const branchWorktrees = this.list().filter((wt) => wt.branch === branch);
1773
1812
  for (const wt of branchWorktrees) {
1774
- const worktreePath2 = import_node_path5.resolve(wt.path);
1813
+ const worktreePath2 = import_node_path6.resolve(wt.path);
1775
1814
  if (wt.isMain || !this.isManagedWorktreePath(worktreePath2)) {
1776
1815
  throw new Error(`Branch "${branch}" is checked out at "${worktreePath2}". Remove or detach that worktree before retrying.`);
1777
1816
  }
@@ -1831,7 +1870,7 @@ class WorktreeManager {
1831
1870
  branch = "(detached)";
1832
1871
  }
1833
1872
  }
1834
- if (import_node_path5.resolve(path) === this.projectPath) {
1873
+ if (import_node_path6.resolve(path) === this.projectPath) {
1835
1874
  isMain = true;
1836
1875
  }
1837
1876
  if (path) {
@@ -1844,16 +1883,16 @@ class WorktreeManager {
1844
1883
  return this.list().filter((wt) => !wt.isMain);
1845
1884
  }
1846
1885
  remove(worktreePath, deleteBranch = true) {
1847
- const absolutePath = import_node_path5.resolve(worktreePath);
1886
+ const absolutePath = import_node_path6.resolve(worktreePath);
1848
1887
  const worktrees = this.list();
1849
- const worktree = worktrees.find((wt) => import_node_path5.resolve(wt.path) === absolutePath);
1888
+ const worktree = worktrees.find((wt) => import_node_path6.resolve(wt.path) === absolutePath);
1850
1889
  const branchToDelete = worktree?.branch;
1851
1890
  this.log(`Removing worktree: ${absolutePath}`, "info");
1852
1891
  try {
1853
1892
  this.git(`worktree remove "${absolutePath}" --force`, this.projectPath);
1854
1893
  } catch {
1855
- if (import_node_fs3.existsSync(absolutePath)) {
1856
- import_node_fs3.rmSync(absolutePath, { recursive: true, force: true });
1894
+ if (import_node_fs4.existsSync(absolutePath)) {
1895
+ import_node_fs4.rmSync(absolutePath, { recursive: true, force: true });
1857
1896
  }
1858
1897
  this.git("worktree prune", this.projectPath);
1859
1898
  }
@@ -1888,9 +1927,9 @@ class WorktreeManager {
1888
1927
  this.log(`Failed to remove worktree: ${wt.path}`, "warn");
1889
1928
  }
1890
1929
  }
1891
- if (import_node_fs3.existsSync(this.rootPath)) {
1930
+ if (import_node_fs4.existsSync(this.rootPath)) {
1892
1931
  try {
1893
- import_node_fs3.rmSync(this.rootPath, { recursive: true, force: true });
1932
+ import_node_fs4.rmSync(this.rootPath, { recursive: true, force: true });
1894
1933
  } catch {}
1895
1934
  }
1896
1935
  return removed;
@@ -1948,19 +1987,19 @@ class WorktreeManager {
1948
1987
  return this.git("rev-parse --abbrev-ref HEAD", this.projectPath).trim();
1949
1988
  }
1950
1989
  isManagedWorktreePath(worktreePath) {
1951
- const rootPath = import_node_path5.resolve(this.rootPath);
1952
- const candidate = import_node_path5.resolve(worktreePath);
1953
- const rootWithSep = rootPath.endsWith(import_node_path5.sep) ? rootPath : `${rootPath}${import_node_path5.sep}`;
1990
+ const rootPath = import_node_path6.resolve(this.rootPath);
1991
+ const candidate = import_node_path6.resolve(worktreePath);
1992
+ const rootWithSep = rootPath.endsWith(import_node_path6.sep) ? rootPath : `${rootPath}${import_node_path6.sep}`;
1954
1993
  return candidate.startsWith(rootWithSep);
1955
1994
  }
1956
1995
  ensureDirectory(dirPath, label) {
1957
- if (import_node_fs3.existsSync(dirPath)) {
1958
- if (!import_node_fs3.statSync(dirPath).isDirectory()) {
1996
+ if (import_node_fs4.existsSync(dirPath)) {
1997
+ if (!import_node_fs4.statSync(dirPath).isDirectory()) {
1959
1998
  throw new Error(`${label} exists but is not a directory: ${dirPath}`);
1960
1999
  }
1961
2000
  return;
1962
2001
  }
1963
- import_node_fs3.mkdirSync(dirPath, { recursive: true });
2002
+ import_node_fs4.mkdirSync(dirPath, { recursive: true });
1964
2003
  }
1965
2004
  isMissingDirectoryError(error) {
1966
2005
  const message = error instanceof Error ? error.message : String(error);
@@ -1970,8 +2009,8 @@ class WorktreeManager {
1970
2009
  try {
1971
2010
  this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
1972
2011
  } catch {}
1973
- if (import_node_fs3.existsSync(worktreePath)) {
1974
- import_node_fs3.rmSync(worktreePath, { recursive: true, force: true });
2012
+ if (import_node_fs4.existsSync(worktreePath)) {
2013
+ import_node_fs4.rmSync(worktreePath, { recursive: true, force: true });
1975
2014
  }
1976
2015
  try {
1977
2016
  this.git("worktree prune", this.projectPath);
@@ -2003,8 +2042,8 @@ class WorktreeManager {
2003
2042
  }
2004
2043
 
2005
2044
  // src/core/prompt-builder.ts
2006
- var import_node_fs4 = require("node:fs");
2007
- var import_node_path6 = require("node:path");
2045
+ var import_node_fs5 = require("node:fs");
2046
+ var import_node_path7 = require("node:path");
2008
2047
  var import_shared2 = require("@locusai/shared");
2009
2048
  class PromptBuilder {
2010
2049
  projectPath;
@@ -2046,9 +2085,9 @@ ${task.description || "No description provided."}
2046
2085
  }
2047
2086
  const contextPath = getLocusPath(this.projectPath, "contextFile");
2048
2087
  let hasLocalContext = false;
2049
- if (import_node_fs4.existsSync(contextPath)) {
2088
+ if (import_node_fs5.existsSync(contextPath)) {
2050
2089
  try {
2051
- const context = import_node_fs4.readFileSync(contextPath, "utf-8");
2090
+ const context = import_node_fs5.readFileSync(contextPath, "utf-8");
2052
2091
  if (context.trim().length > 20) {
2053
2092
  prompt += `## Project Context (Local)
2054
2093
  ${context}
@@ -2102,7 +2141,7 @@ ${serverContext.context}
2102
2141
 
2103
2142
  `;
2104
2143
  const indexPath = getLocusPath(this.projectPath, "indexFile");
2105
- if (import_node_fs4.existsSync(indexPath)) {
2144
+ if (import_node_fs5.existsSync(indexPath)) {
2106
2145
  prompt += `## Codebase Overview
2107
2146
  There is an index file in the .locus/codebase-index.json and if you need you can check it.
2108
2147
 
@@ -2177,9 +2216,9 @@ ${query}
2177
2216
  }
2178
2217
  const contextPath = getLocusPath(this.projectPath, "contextFile");
2179
2218
  let hasLocalContext = false;
2180
- if (import_node_fs4.existsSync(contextPath)) {
2219
+ if (import_node_fs5.existsSync(contextPath)) {
2181
2220
  try {
2182
- const context = import_node_fs4.readFileSync(contextPath, "utf-8");
2221
+ const context = import_node_fs5.readFileSync(contextPath, "utf-8");
2183
2222
  if (context.trim().length > 20) {
2184
2223
  prompt += `## Project Context (Local)
2185
2224
  ${context}
@@ -2213,7 +2252,7 @@ ${fallback}
2213
2252
 
2214
2253
  `;
2215
2254
  const indexPath = getLocusPath(this.projectPath, "indexFile");
2216
- if (import_node_fs4.existsSync(indexPath)) {
2255
+ if (import_node_fs5.existsSync(indexPath)) {
2217
2256
  prompt += `## Codebase Overview
2218
2257
  There is an index file in the .locus/codebase-index.json and if you need you can check it.
2219
2258
 
@@ -2226,9 +2265,9 @@ There is an index file in the .locus/codebase-index.json and if you need you can
2226
2265
  }
2227
2266
  getProjectConfig() {
2228
2267
  const configPath = getLocusPath(this.projectPath, "configFile");
2229
- if (import_node_fs4.existsSync(configPath)) {
2268
+ if (import_node_fs5.existsSync(configPath)) {
2230
2269
  try {
2231
- return JSON.parse(import_node_fs4.readFileSync(configPath, "utf-8"));
2270
+ return JSON.parse(import_node_fs5.readFileSync(configPath, "utf-8"));
2232
2271
  } catch {
2233
2272
  return null;
2234
2273
  }
@@ -2236,10 +2275,10 @@ There is an index file in the .locus/codebase-index.json and if you need you can
2236
2275
  return null;
2237
2276
  }
2238
2277
  getFallbackContext() {
2239
- const readmePath = import_node_path6.join(this.projectPath, "README.md");
2240
- if (import_node_fs4.existsSync(readmePath)) {
2278
+ const readmePath = import_node_path7.join(this.projectPath, "README.md");
2279
+ if (import_node_fs5.existsSync(readmePath)) {
2241
2280
  try {
2242
- const content = import_node_fs4.readFileSync(readmePath, "utf-8");
2281
+ const content = import_node_fs5.readFileSync(readmePath, "utf-8");
2243
2282
  const limit = 1000;
2244
2283
  return content.slice(0, limit) + (content.length > limit ? `
2245
2284
  ...(truncated)...` : "");
@@ -2251,12 +2290,12 @@ There is an index file in the .locus/codebase-index.json and if you need you can
2251
2290
  }
2252
2291
  getProjectStructure() {
2253
2292
  try {
2254
- const entries = import_node_fs4.readdirSync(this.projectPath);
2293
+ const entries = import_node_fs5.readdirSync(this.projectPath);
2255
2294
  const folders = entries.filter((e) => {
2256
2295
  if (e.startsWith(".") || e === "node_modules")
2257
2296
  return false;
2258
2297
  try {
2259
- return import_node_fs4.statSync(import_node_path6.join(this.projectPath, e)).isDirectory();
2298
+ return import_node_fs5.statSync(import_node_path7.join(this.projectPath, e)).isDirectory();
2260
2299
  } catch {
2261
2300
  return false;
2262
2301
  }
@@ -1 +1 @@
1
- {"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/ai/claude-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwC5C,qBAAa,YAAa,YAAW,QAAQ;IASzC,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG,CAAC;IATd,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAmB;IACxC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,aAAa,CAA6B;gBAGhD,WAAW,EAAE,MAAM,EACX,KAAK,GAAE,MAAuC,EAC9C,GAAG,CAAC,EAAE,KAAK,YAAA;IAKrB;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAIhD;;OAEG;IACH,KAAK,IAAI,IAAI;IAOP,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBnC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IA2K5E;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,kBAAkB;IAwE1B,OAAO,CAAC,UAAU;IAwFlB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;CAO7B"}
1
+ {"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/ai/claude-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwC5C,qBAAa,YAAa,YAAW,QAAQ;IASzC,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG,CAAC;IATd,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAmB;IACxC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,aAAa,CAA6B;gBAGhD,WAAW,EAAE,MAAM,EACX,KAAK,GAAE,MAAuC,EAC9C,GAAG,CAAC,EAAE,KAAK,YAAA;IAKrB;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAIhD;;OAEG;IACH,KAAK,IAAI,IAAI;IAOP,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBnC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IA0K5E;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,kBAAkB;IAwE1B,OAAO,CAAC,UAAU;IAuFlB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;CAO7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-runner.d.ts","sourceRoot":"","sources":["../../src/ai/codex-runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,qBAAa,WAAY,YAAW,QAAQ;IAIxC,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG,CAAC;IALd,OAAO,CAAC,aAAa,CAA6B;gBAGxC,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAsC,EAC7C,GAAG,CAAC,EAAE,KAAK,YAAA;IAGrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAOP,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBnC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IAgH5E,OAAO,CAAC,UAAU;IAuDlB,OAAO,CAAC,SAAS;IAkBjB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,KAAK;CAGd"}
1
+ {"version":3,"file":"codex-runner.d.ts","sourceRoot":"","sources":["../../src/ai/codex-runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,qBAAa,WAAY,YAAW,QAAQ;IAIxC,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG,CAAC;IALd,OAAO,CAAC,aAAa,CAA6B;gBAGxC,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAsC,EAC7C,GAAG,CAAC,EAAE,KAAK,YAAA;IAGrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAOP,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBnC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IAgH5E,OAAO,CAAC,UAAU;IAuDlB,OAAO,CAAC,SAAS;IAkBjB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,KAAK;CAGd"}
@@ -547,7 +547,7 @@ function getAgentArtifactsPath(projectPath, agentId) {
547
547
 
548
548
  // src/ai/claude-runner.ts
549
549
  var import_node_child_process = require("node:child_process");
550
- var import_node_path2 = require("node:path");
550
+ var import_node_path3 = require("node:path");
551
551
 
552
552
  // src/utils/colors.ts
553
553
  var ESC = "\x1B[";
@@ -611,6 +611,47 @@ var c = {
611
611
  underline: (t) => c.text(t, "underline")
612
612
  };
613
613
 
614
+ // src/utils/resolve-bin.ts
615
+ var import_node_fs = require("node:fs");
616
+ var import_node_os = require("node:os");
617
+ var import_node_path2 = require("node:path");
618
+ var EXTRA_BIN_DIRS = [
619
+ import_node_path2.join(import_node_os.homedir(), ".local", "bin"),
620
+ import_node_path2.join(import_node_os.homedir(), ".npm", "bin"),
621
+ import_node_path2.join(import_node_os.homedir(), ".npm-global", "bin"),
622
+ import_node_path2.join(import_node_os.homedir(), ".yarn", "bin"),
623
+ "/usr/local/bin"
624
+ ];
625
+ function getNodeManagerDirs() {
626
+ const dirs = [];
627
+ const nvmDir = process.env.NVM_DIR || import_node_path2.join(import_node_os.homedir(), ".nvm");
628
+ const nvmCurrent = import_node_path2.join(nvmDir, "current", "bin");
629
+ if (import_node_fs.existsSync(nvmCurrent)) {
630
+ dirs.push(nvmCurrent);
631
+ }
632
+ const fnmDir = process.env.FNM_DIR || import_node_path2.join(import_node_os.homedir(), ".fnm");
633
+ const fnmCurrent = import_node_path2.join(fnmDir, "current", "bin");
634
+ if (import_node_fs.existsSync(fnmCurrent)) {
635
+ dirs.push(fnmCurrent);
636
+ }
637
+ return dirs;
638
+ }
639
+ function getAugmentedPath() {
640
+ const currentPath = process.env.PATH || "";
641
+ const currentDirs = new Set(currentPath.split(import_node_path2.delimiter));
642
+ const extra = [...EXTRA_BIN_DIRS, ...getNodeManagerDirs()].filter((dir) => !currentDirs.has(dir) && import_node_fs.existsSync(dir));
643
+ if (extra.length === 0)
644
+ return currentPath;
645
+ return currentPath + import_node_path2.delimiter + extra.join(import_node_path2.delimiter);
646
+ }
647
+ function getAugmentedEnv(overrides = {}) {
648
+ return {
649
+ ...process.env,
650
+ ...overrides,
651
+ PATH: getAugmentedPath()
652
+ };
653
+ }
654
+
614
655
  // src/ai/claude-runner.ts
615
656
  var SANDBOX_SETTINGS = JSON.stringify({
616
657
  sandbox: {
@@ -631,7 +672,7 @@ class ClaudeRunner {
631
672
  constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CLAUDE], log) {
632
673
  this.model = model;
633
674
  this.log = log;
634
- this.projectPath = import_node_path2.resolve(projectPath);
675
+ this.projectPath = import_node_path3.resolve(projectPath);
635
676
  }
636
677
  setEventEmitter(emitter) {
637
678
  this.eventEmitter = emitter;
@@ -674,11 +715,10 @@ class ClaudeRunner {
674
715
  "--settings",
675
716
  SANDBOX_SETTINGS
676
717
  ];
677
- const env = {
678
- ...process.env,
718
+ const env = getAugmentedEnv({
679
719
  FORCE_COLOR: "1",
680
720
  TERM: "xterm-256color"
681
- };
721
+ });
682
722
  this.eventEmitter?.emitSessionStarted({
683
723
  model: this.model,
684
724
  provider: "claude"
@@ -919,11 +959,10 @@ class ClaudeRunner {
919
959
  "--settings",
920
960
  SANDBOX_SETTINGS
921
961
  ];
922
- const env = {
923
- ...process.env,
962
+ const env = getAugmentedEnv({
924
963
  FORCE_COLOR: "1",
925
964
  TERM: "xterm-256color"
926
- };
965
+ });
927
966
  const claude = import_node_child_process.spawn("claude", args, {
928
967
  cwd: this.projectPath,
929
968
  stdio: ["pipe", "pipe", "pipe"],
@@ -1023,9 +1062,9 @@ ${c.primary("[Claude]")} ${c.bold(`Running ${content_block.name}...`)}
1023
1062
  // src/ai/codex-runner.ts
1024
1063
  var import_node_child_process2 = require("node:child_process");
1025
1064
  var import_node_crypto = require("node:crypto");
1026
- var import_node_fs = require("node:fs");
1027
- var import_node_os = require("node:os");
1028
- var import_node_path3 = require("node:path");
1065
+ var import_node_fs2 = require("node:fs");
1066
+ var import_node_os2 = require("node:os");
1067
+ var import_node_path4 = require("node:path");
1029
1068
  class CodexRunner {
1030
1069
  projectPath;
1031
1070
  model;
@@ -1060,12 +1099,12 @@ class CodexRunner {
1060
1099
  throw lastError || new Error("Codex CLI failed after multiple attempts");
1061
1100
  }
1062
1101
  async* runStream(prompt) {
1063
- const outputPath = import_node_path3.join(import_node_os.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1102
+ const outputPath = import_node_path4.join(import_node_os2.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1064
1103
  const args = this.buildArgs(outputPath);
1065
1104
  const codex = import_node_child_process2.spawn("codex", args, {
1066
1105
  cwd: this.projectPath,
1067
1106
  stdio: ["pipe", "pipe", "pipe"],
1068
- env: process.env,
1107
+ env: getAugmentedEnv(),
1069
1108
  shell: false
1070
1109
  });
1071
1110
  this.activeProcess = codex;
@@ -1156,12 +1195,12 @@ class CodexRunner {
1156
1195
  }
1157
1196
  executeRun(prompt) {
1158
1197
  return new Promise((resolve2, reject) => {
1159
- const outputPath = import_node_path3.join(import_node_os.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1198
+ const outputPath = import_node_path4.join(import_node_os2.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
1160
1199
  const args = this.buildArgs(outputPath);
1161
1200
  const codex = import_node_child_process2.spawn("codex", args, {
1162
1201
  cwd: this.projectPath,
1163
1202
  stdio: ["pipe", "pipe", "pipe"],
1164
- env: process.env,
1203
+ env: getAugmentedEnv(),
1165
1204
  shell: false
1166
1205
  });
1167
1206
  this.activeProcess = codex;
@@ -1228,9 +1267,9 @@ class CodexRunner {
1228
1267
  ].some((pattern) => pattern.test(line));
1229
1268
  }
1230
1269
  readOutput(outputPath, fallback) {
1231
- if (import_node_fs.existsSync(outputPath)) {
1270
+ if (import_node_fs2.existsSync(outputPath)) {
1232
1271
  try {
1233
- const text = import_node_fs.readFileSync(outputPath, "utf-8").trim();
1272
+ const text = import_node_fs2.readFileSync(outputPath, "utf-8").trim();
1234
1273
  if (text)
1235
1274
  return text;
1236
1275
  } catch {}
@@ -1244,8 +1283,8 @@ class CodexRunner {
1244
1283
  }
1245
1284
  cleanupTempFile(path) {
1246
1285
  try {
1247
- if (import_node_fs.existsSync(path))
1248
- import_node_fs.unlinkSync(path);
1286
+ if (import_node_fs2.existsSync(path))
1287
+ import_node_fs2.unlinkSync(path);
1249
1288
  } catch {}
1250
1289
  }
1251
1290
  sleep(ms) {
@@ -1591,8 +1630,8 @@ class PrService {
1591
1630
  }
1592
1631
 
1593
1632
  // src/project/knowledge-base.ts
1594
- var import_node_fs2 = require("node:fs");
1595
- var import_node_path4 = require("node:path");
1633
+ var import_node_fs3 = require("node:fs");
1634
+ var import_node_path5 = require("node:path");
1596
1635
  class KnowledgeBase {
1597
1636
  contextPath;
1598
1637
  progressPath;
@@ -1601,20 +1640,20 @@ class KnowledgeBase {
1601
1640
  this.progressPath = getLocusPath(projectPath, "projectProgressFile");
1602
1641
  }
1603
1642
  readContext() {
1604
- if (!import_node_fs2.existsSync(this.contextPath)) {
1643
+ if (!import_node_fs3.existsSync(this.contextPath)) {
1605
1644
  return "";
1606
1645
  }
1607
- return import_node_fs2.readFileSync(this.contextPath, "utf-8");
1646
+ return import_node_fs3.readFileSync(this.contextPath, "utf-8");
1608
1647
  }
1609
1648
  readProgress() {
1610
- if (!import_node_fs2.existsSync(this.progressPath)) {
1649
+ if (!import_node_fs3.existsSync(this.progressPath)) {
1611
1650
  return "";
1612
1651
  }
1613
- return import_node_fs2.readFileSync(this.progressPath, "utf-8");
1652
+ return import_node_fs3.readFileSync(this.progressPath, "utf-8");
1614
1653
  }
1615
1654
  updateContext(content) {
1616
1655
  this.ensureDir(this.contextPath);
1617
- import_node_fs2.writeFileSync(this.contextPath, content);
1656
+ import_node_fs3.writeFileSync(this.contextPath, content);
1618
1657
  }
1619
1658
  updateProgress(event) {
1620
1659
  this.ensureDir(this.progressPath);
@@ -1660,7 +1699,7 @@ class KnowledgeBase {
1660
1699
  ${entry}` : `# Project Progress
1661
1700
 
1662
1701
  ${entry}`;
1663
- import_node_fs2.writeFileSync(this.progressPath, updated);
1702
+ import_node_fs3.writeFileSync(this.progressPath, updated);
1664
1703
  }
1665
1704
  getFullContext() {
1666
1705
  const context = this.readContext();
@@ -1704,24 +1743,24 @@ ${techStackList}
1704
1743
 
1705
1744
  No sprints started yet.
1706
1745
  `;
1707
- import_node_fs2.writeFileSync(this.contextPath, contextContent);
1708
- import_node_fs2.writeFileSync(this.progressPath, progressContent);
1746
+ import_node_fs3.writeFileSync(this.contextPath, contextContent);
1747
+ import_node_fs3.writeFileSync(this.progressPath, progressContent);
1709
1748
  }
1710
1749
  get exists() {
1711
- return import_node_fs2.existsSync(this.contextPath) || import_node_fs2.existsSync(this.progressPath);
1750
+ return import_node_fs3.existsSync(this.contextPath) || import_node_fs3.existsSync(this.progressPath);
1712
1751
  }
1713
1752
  ensureDir(filePath) {
1714
- const dir = import_node_path4.dirname(filePath);
1715
- if (!import_node_fs2.existsSync(dir)) {
1716
- import_node_fs2.mkdirSync(dir, { recursive: true });
1753
+ const dir = import_node_path5.dirname(filePath);
1754
+ if (!import_node_fs3.existsSync(dir)) {
1755
+ import_node_fs3.mkdirSync(dir, { recursive: true });
1717
1756
  }
1718
1757
  }
1719
1758
  }
1720
1759
 
1721
1760
  // src/worktree/worktree-manager.ts
1722
1761
  var import_node_child_process5 = require("node:child_process");
1723
- var import_node_fs3 = require("node:fs");
1724
- var import_node_path5 = require("node:path");
1762
+ var import_node_fs4 = require("node:fs");
1763
+ var import_node_path6 = require("node:path");
1725
1764
 
1726
1765
  // src/worktree/worktree-config.ts
1727
1766
  var WORKTREE_ROOT_DIR = ".locus-worktrees";
@@ -1738,14 +1777,14 @@ class WorktreeManager {
1738
1777
  projectPath;
1739
1778
  log;
1740
1779
  constructor(projectPath, config, log) {
1741
- this.projectPath = import_node_path5.resolve(projectPath);
1780
+ this.projectPath = import_node_path6.resolve(projectPath);
1742
1781
  this.config = { ...DEFAULT_WORKTREE_CONFIG, ...config };
1743
1782
  this.log = log ?? ((_msg) => {
1744
1783
  return;
1745
1784
  });
1746
1785
  }
1747
1786
  get rootPath() {
1748
- return import_node_path5.join(this.projectPath, this.config.rootDir);
1787
+ return import_node_path6.join(this.projectPath, this.config.rootDir);
1749
1788
  }
1750
1789
  buildBranchName(taskId, taskSlug) {
1751
1790
  const sanitized = taskSlug.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50);
@@ -1754,16 +1793,16 @@ class WorktreeManager {
1754
1793
  create(options) {
1755
1794
  const branch = this.buildBranchName(options.taskId, options.taskSlug);
1756
1795
  const worktreeDir = `${options.agentId}-${options.taskId}`;
1757
- const worktreePath = import_node_path5.join(this.rootPath, worktreeDir);
1796
+ const worktreePath = import_node_path6.join(this.rootPath, worktreeDir);
1758
1797
  this.ensureDirectory(this.rootPath, "Worktree root");
1759
1798
  const baseBranch = options.baseBranch ?? this.config.baseBranch ?? this.getCurrentBranch();
1760
1799
  this.log(`Creating worktree: ${worktreeDir} (branch: ${branch}, base: ${baseBranch})`, "info");
1761
- if (import_node_fs3.existsSync(worktreePath)) {
1800
+ if (import_node_fs4.existsSync(worktreePath)) {
1762
1801
  this.log(`Removing stale worktree directory: ${worktreePath}`, "warn");
1763
1802
  try {
1764
1803
  this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
1765
1804
  } catch {
1766
- import_node_fs3.rmSync(worktreePath, { recursive: true, force: true });
1805
+ import_node_fs4.rmSync(worktreePath, { recursive: true, force: true });
1767
1806
  this.git("worktree prune", this.projectPath);
1768
1807
  }
1769
1808
  }
@@ -1771,7 +1810,7 @@ class WorktreeManager {
1771
1810
  this.log(`Deleting existing branch: ${branch}`, "warn");
1772
1811
  const branchWorktrees = this.list().filter((wt) => wt.branch === branch);
1773
1812
  for (const wt of branchWorktrees) {
1774
- const worktreePath2 = import_node_path5.resolve(wt.path);
1813
+ const worktreePath2 = import_node_path6.resolve(wt.path);
1775
1814
  if (wt.isMain || !this.isManagedWorktreePath(worktreePath2)) {
1776
1815
  throw new Error(`Branch "${branch}" is checked out at "${worktreePath2}". Remove or detach that worktree before retrying.`);
1777
1816
  }
@@ -1831,7 +1870,7 @@ class WorktreeManager {
1831
1870
  branch = "(detached)";
1832
1871
  }
1833
1872
  }
1834
- if (import_node_path5.resolve(path) === this.projectPath) {
1873
+ if (import_node_path6.resolve(path) === this.projectPath) {
1835
1874
  isMain = true;
1836
1875
  }
1837
1876
  if (path) {
@@ -1844,16 +1883,16 @@ class WorktreeManager {
1844
1883
  return this.list().filter((wt) => !wt.isMain);
1845
1884
  }
1846
1885
  remove(worktreePath, deleteBranch = true) {
1847
- const absolutePath = import_node_path5.resolve(worktreePath);
1886
+ const absolutePath = import_node_path6.resolve(worktreePath);
1848
1887
  const worktrees = this.list();
1849
- const worktree = worktrees.find((wt) => import_node_path5.resolve(wt.path) === absolutePath);
1888
+ const worktree = worktrees.find((wt) => import_node_path6.resolve(wt.path) === absolutePath);
1850
1889
  const branchToDelete = worktree?.branch;
1851
1890
  this.log(`Removing worktree: ${absolutePath}`, "info");
1852
1891
  try {
1853
1892
  this.git(`worktree remove "${absolutePath}" --force`, this.projectPath);
1854
1893
  } catch {
1855
- if (import_node_fs3.existsSync(absolutePath)) {
1856
- import_node_fs3.rmSync(absolutePath, { recursive: true, force: true });
1894
+ if (import_node_fs4.existsSync(absolutePath)) {
1895
+ import_node_fs4.rmSync(absolutePath, { recursive: true, force: true });
1857
1896
  }
1858
1897
  this.git("worktree prune", this.projectPath);
1859
1898
  }
@@ -1888,9 +1927,9 @@ class WorktreeManager {
1888
1927
  this.log(`Failed to remove worktree: ${wt.path}`, "warn");
1889
1928
  }
1890
1929
  }
1891
- if (import_node_fs3.existsSync(this.rootPath)) {
1930
+ if (import_node_fs4.existsSync(this.rootPath)) {
1892
1931
  try {
1893
- import_node_fs3.rmSync(this.rootPath, { recursive: true, force: true });
1932
+ import_node_fs4.rmSync(this.rootPath, { recursive: true, force: true });
1894
1933
  } catch {}
1895
1934
  }
1896
1935
  return removed;
@@ -1948,19 +1987,19 @@ class WorktreeManager {
1948
1987
  return this.git("rev-parse --abbrev-ref HEAD", this.projectPath).trim();
1949
1988
  }
1950
1989
  isManagedWorktreePath(worktreePath) {
1951
- const rootPath = import_node_path5.resolve(this.rootPath);
1952
- const candidate = import_node_path5.resolve(worktreePath);
1953
- const rootWithSep = rootPath.endsWith(import_node_path5.sep) ? rootPath : `${rootPath}${import_node_path5.sep}`;
1990
+ const rootPath = import_node_path6.resolve(this.rootPath);
1991
+ const candidate = import_node_path6.resolve(worktreePath);
1992
+ const rootWithSep = rootPath.endsWith(import_node_path6.sep) ? rootPath : `${rootPath}${import_node_path6.sep}`;
1954
1993
  return candidate.startsWith(rootWithSep);
1955
1994
  }
1956
1995
  ensureDirectory(dirPath, label) {
1957
- if (import_node_fs3.existsSync(dirPath)) {
1958
- if (!import_node_fs3.statSync(dirPath).isDirectory()) {
1996
+ if (import_node_fs4.existsSync(dirPath)) {
1997
+ if (!import_node_fs4.statSync(dirPath).isDirectory()) {
1959
1998
  throw new Error(`${label} exists but is not a directory: ${dirPath}`);
1960
1999
  }
1961
2000
  return;
1962
2001
  }
1963
- import_node_fs3.mkdirSync(dirPath, { recursive: true });
2002
+ import_node_fs4.mkdirSync(dirPath, { recursive: true });
1964
2003
  }
1965
2004
  isMissingDirectoryError(error) {
1966
2005
  const message = error instanceof Error ? error.message : String(error);
@@ -1970,8 +2009,8 @@ class WorktreeManager {
1970
2009
  try {
1971
2010
  this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
1972
2011
  } catch {}
1973
- if (import_node_fs3.existsSync(worktreePath)) {
1974
- import_node_fs3.rmSync(worktreePath, { recursive: true, force: true });
2012
+ if (import_node_fs4.existsSync(worktreePath)) {
2013
+ import_node_fs4.rmSync(worktreePath, { recursive: true, force: true });
1975
2014
  }
1976
2015
  try {
1977
2016
  this.git("worktree prune", this.projectPath);
@@ -2003,8 +2042,8 @@ class WorktreeManager {
2003
2042
  }
2004
2043
 
2005
2044
  // src/core/prompt-builder.ts
2006
- var import_node_fs4 = require("node:fs");
2007
- var import_node_path6 = require("node:path");
2045
+ var import_node_fs5 = require("node:fs");
2046
+ var import_node_path7 = require("node:path");
2008
2047
  var import_shared2 = require("@locusai/shared");
2009
2048
  class PromptBuilder {
2010
2049
  projectPath;
@@ -2046,9 +2085,9 @@ ${task.description || "No description provided."}
2046
2085
  }
2047
2086
  const contextPath = getLocusPath(this.projectPath, "contextFile");
2048
2087
  let hasLocalContext = false;
2049
- if (import_node_fs4.existsSync(contextPath)) {
2088
+ if (import_node_fs5.existsSync(contextPath)) {
2050
2089
  try {
2051
- const context = import_node_fs4.readFileSync(contextPath, "utf-8");
2090
+ const context = import_node_fs5.readFileSync(contextPath, "utf-8");
2052
2091
  if (context.trim().length > 20) {
2053
2092
  prompt += `## Project Context (Local)
2054
2093
  ${context}
@@ -2102,7 +2141,7 @@ ${serverContext.context}
2102
2141
 
2103
2142
  `;
2104
2143
  const indexPath = getLocusPath(this.projectPath, "indexFile");
2105
- if (import_node_fs4.existsSync(indexPath)) {
2144
+ if (import_node_fs5.existsSync(indexPath)) {
2106
2145
  prompt += `## Codebase Overview
2107
2146
  There is an index file in the .locus/codebase-index.json and if you need you can check it.
2108
2147
 
@@ -2177,9 +2216,9 @@ ${query}
2177
2216
  }
2178
2217
  const contextPath = getLocusPath(this.projectPath, "contextFile");
2179
2218
  let hasLocalContext = false;
2180
- if (import_node_fs4.existsSync(contextPath)) {
2219
+ if (import_node_fs5.existsSync(contextPath)) {
2181
2220
  try {
2182
- const context = import_node_fs4.readFileSync(contextPath, "utf-8");
2221
+ const context = import_node_fs5.readFileSync(contextPath, "utf-8");
2183
2222
  if (context.trim().length > 20) {
2184
2223
  prompt += `## Project Context (Local)
2185
2224
  ${context}
@@ -2213,7 +2252,7 @@ ${fallback}
2213
2252
 
2214
2253
  `;
2215
2254
  const indexPath = getLocusPath(this.projectPath, "indexFile");
2216
- if (import_node_fs4.existsSync(indexPath)) {
2255
+ if (import_node_fs5.existsSync(indexPath)) {
2217
2256
  prompt += `## Codebase Overview
2218
2257
  There is an index file in the .locus/codebase-index.json and if you need you can check it.
2219
2258
 
@@ -2226,9 +2265,9 @@ There is an index file in the .locus/codebase-index.json and if you need you can
2226
2265
  }
2227
2266
  getProjectConfig() {
2228
2267
  const configPath = getLocusPath(this.projectPath, "configFile");
2229
- if (import_node_fs4.existsSync(configPath)) {
2268
+ if (import_node_fs5.existsSync(configPath)) {
2230
2269
  try {
2231
- return JSON.parse(import_node_fs4.readFileSync(configPath, "utf-8"));
2270
+ return JSON.parse(import_node_fs5.readFileSync(configPath, "utf-8"));
2232
2271
  } catch {
2233
2272
  return null;
2234
2273
  }
@@ -2236,10 +2275,10 @@ There is an index file in the .locus/codebase-index.json and if you need you can
2236
2275
  return null;
2237
2276
  }
2238
2277
  getFallbackContext() {
2239
- const readmePath = import_node_path6.join(this.projectPath, "README.md");
2240
- if (import_node_fs4.existsSync(readmePath)) {
2278
+ const readmePath = import_node_path7.join(this.projectPath, "README.md");
2279
+ if (import_node_fs5.existsSync(readmePath)) {
2241
2280
  try {
2242
- const content = import_node_fs4.readFileSync(readmePath, "utf-8");
2281
+ const content = import_node_fs5.readFileSync(readmePath, "utf-8");
2243
2282
  const limit = 1000;
2244
2283
  return content.slice(0, limit) + (content.length > limit ? `
2245
2284
  ...(truncated)...` : "");
@@ -2251,12 +2290,12 @@ There is an index file in the .locus/codebase-index.json and if you need you can
2251
2290
  }
2252
2291
  getProjectStructure() {
2253
2292
  try {
2254
- const entries = import_node_fs4.readdirSync(this.projectPath);
2293
+ const entries = import_node_fs5.readdirSync(this.projectPath);
2255
2294
  const folders = entries.filter((e) => {
2256
2295
  if (e.startsWith(".") || e === "node_modules")
2257
2296
  return false;
2258
2297
  try {
2259
- return import_node_fs4.statSync(import_node_path6.join(this.projectPath, e)).isDirectory();
2298
+ return import_node_fs5.statSync(import_node_path7.join(this.projectPath, e)).isDirectory();
2260
2299
  } catch {
2261
2300
  return false;
2262
2301
  }
@@ -2866,8 +2905,8 @@ module.exports = __toCommonJS(exports_index_node);
2866
2905
 
2867
2906
  // src/core/indexer.ts
2868
2907
  var import_node_crypto2 = require("node:crypto");
2869
- var import_node_fs5 = require("node:fs");
2870
- var import_node_path7 = require("node:path");
2908
+ var import_node_fs6 = require("node:fs");
2909
+ var import_node_path8 = require("node:path");
2871
2910
  var import_globby = require("globby");
2872
2911
 
2873
2912
  class CodebaseIndexer {
@@ -2876,7 +2915,7 @@ class CodebaseIndexer {
2876
2915
  fullReindexRatioThreshold = 0.2;
2877
2916
  constructor(projectPath) {
2878
2917
  this.projectPath = projectPath;
2879
- this.indexPath = import_node_path7.join(projectPath, ".locus", "codebase-index.json");
2918
+ this.indexPath = import_node_path8.join(projectPath, ".locus", "codebase-index.json");
2880
2919
  }
2881
2920
  async index(onProgress, treeSummarizer, force = false) {
2882
2921
  if (!treeSummarizer) {
@@ -2932,11 +2971,11 @@ class CodebaseIndexer {
2932
2971
  }
2933
2972
  }
2934
2973
  async getFileTree() {
2935
- const gitmodulesPath = import_node_path7.join(this.projectPath, ".gitmodules");
2974
+ const gitmodulesPath = import_node_path8.join(this.projectPath, ".gitmodules");
2936
2975
  const submoduleIgnores = [];
2937
- if (import_node_fs5.existsSync(gitmodulesPath)) {
2976
+ if (import_node_fs6.existsSync(gitmodulesPath)) {
2938
2977
  try {
2939
- const content = import_node_fs5.readFileSync(gitmodulesPath, "utf-8");
2978
+ const content = import_node_fs6.readFileSync(gitmodulesPath, "utf-8");
2940
2979
  const lines = content.split(`
2941
2980
  `);
2942
2981
  for (const line of lines) {
@@ -2992,9 +3031,9 @@ class CodebaseIndexer {
2992
3031
  });
2993
3032
  }
2994
3033
  loadIndex() {
2995
- if (import_node_fs5.existsSync(this.indexPath)) {
3034
+ if (import_node_fs6.existsSync(this.indexPath)) {
2996
3035
  try {
2997
- return JSON.parse(import_node_fs5.readFileSync(this.indexPath, "utf-8"));
3036
+ return JSON.parse(import_node_fs6.readFileSync(this.indexPath, "utf-8"));
2998
3037
  } catch {
2999
3038
  return null;
3000
3039
  }
@@ -3002,11 +3041,11 @@ class CodebaseIndexer {
3002
3041
  return null;
3003
3042
  }
3004
3043
  saveIndex(index) {
3005
- const dir = import_node_path7.dirname(this.indexPath);
3006
- if (!import_node_fs5.existsSync(dir)) {
3007
- import_node_fs5.mkdirSync(dir, { recursive: true });
3044
+ const dir = import_node_path8.dirname(this.indexPath);
3045
+ if (!import_node_fs6.existsSync(dir)) {
3046
+ import_node_fs6.mkdirSync(dir, { recursive: true });
3008
3047
  }
3009
- import_node_fs5.writeFileSync(this.indexPath, JSON.stringify(index, null, 2));
3048
+ import_node_fs6.writeFileSync(this.indexPath, JSON.stringify(index, null, 2));
3010
3049
  }
3011
3050
  cloneIndex(index) {
3012
3051
  return JSON.parse(JSON.stringify(index));
@@ -3022,7 +3061,7 @@ class CodebaseIndexer {
3022
3061
  }
3023
3062
  hashFile(filePath) {
3024
3063
  try {
3025
- const content = import_node_fs5.readFileSync(import_node_path7.join(this.projectPath, filePath), "utf-8");
3064
+ const content = import_node_fs6.readFileSync(import_node_path8.join(this.projectPath, filePath), "utf-8");
3026
3065
  return import_node_crypto2.createHash("sha256").update(content).digest("hex").slice(0, 16);
3027
3066
  } catch {
3028
3067
  return null;
@@ -3126,8 +3165,8 @@ Return ONLY valid JSON, no markdown formatting.`;
3126
3165
  }
3127
3166
  }
3128
3167
  // src/agent/document-fetcher.ts
3129
- var import_node_fs6 = require("node:fs");
3130
- var import_node_path8 = require("node:path");
3168
+ var import_node_fs7 = require("node:fs");
3169
+ var import_node_path9 = require("node:path");
3131
3170
  class DocumentFetcher {
3132
3171
  deps;
3133
3172
  constructor(deps) {
@@ -3135,8 +3174,8 @@ class DocumentFetcher {
3135
3174
  }
3136
3175
  async fetch() {
3137
3176
  const documentsDir = getLocusPath(this.deps.projectPath, "documentsDir");
3138
- if (!import_node_fs6.existsSync(documentsDir)) {
3139
- import_node_fs6.mkdirSync(documentsDir, { recursive: true });
3177
+ if (!import_node_fs7.existsSync(documentsDir)) {
3178
+ import_node_fs7.mkdirSync(documentsDir, { recursive: true });
3140
3179
  }
3141
3180
  try {
3142
3181
  const groups = await this.deps.client.docs.listGroups(this.deps.workspaceId);
@@ -3149,14 +3188,14 @@ class DocumentFetcher {
3149
3188
  continue;
3150
3189
  }
3151
3190
  const groupName = groupMap.get(doc.groupId || "") || "General";
3152
- const groupDir = import_node_path8.join(documentsDir, groupName);
3153
- if (!import_node_fs6.existsSync(groupDir)) {
3154
- import_node_fs6.mkdirSync(groupDir, { recursive: true });
3191
+ const groupDir = import_node_path9.join(documentsDir, groupName);
3192
+ if (!import_node_fs7.existsSync(groupDir)) {
3193
+ import_node_fs7.mkdirSync(groupDir, { recursive: true });
3155
3194
  }
3156
3195
  const fileName = `${doc.title}.md`;
3157
- const filePath = import_node_path8.join(groupDir, fileName);
3158
- if (!import_node_fs6.existsSync(filePath) || import_node_fs6.readFileSync(filePath, "utf-8") !== doc.content) {
3159
- import_node_fs6.writeFileSync(filePath, doc.content || "");
3196
+ const filePath = import_node_path9.join(groupDir, fileName);
3197
+ if (!import_node_fs7.existsSync(filePath) || import_node_fs7.readFileSync(filePath, "utf-8") !== doc.content) {
3198
+ import_node_fs7.writeFileSync(filePath, doc.content || "");
3160
3199
  fetchedCount++;
3161
3200
  }
3162
3201
  }
@@ -3853,8 +3892,8 @@ class ExecEventEmitter {
3853
3892
  }
3854
3893
  }
3855
3894
  // src/exec/history-manager.ts
3856
- var import_node_fs7 = require("node:fs");
3857
- var import_node_path9 = require("node:path");
3895
+ var import_node_fs8 = require("node:fs");
3896
+ var import_node_path10 = require("node:path");
3858
3897
  var DEFAULT_MAX_SESSIONS = 30;
3859
3898
  function generateSessionId2() {
3860
3899
  const timestamp = Date.now().toString(36);
@@ -3866,30 +3905,30 @@ class HistoryManager {
3866
3905
  historyDir;
3867
3906
  maxSessions;
3868
3907
  constructor(projectPath, options) {
3869
- this.historyDir = options?.historyDir ?? import_node_path9.join(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.sessionsDir);
3908
+ this.historyDir = options?.historyDir ?? import_node_path10.join(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.sessionsDir);
3870
3909
  this.maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;
3871
3910
  this.ensureHistoryDir();
3872
3911
  }
3873
3912
  ensureHistoryDir() {
3874
- if (!import_node_fs7.existsSync(this.historyDir)) {
3875
- import_node_fs7.mkdirSync(this.historyDir, { recursive: true });
3913
+ if (!import_node_fs8.existsSync(this.historyDir)) {
3914
+ import_node_fs8.mkdirSync(this.historyDir, { recursive: true });
3876
3915
  }
3877
3916
  }
3878
3917
  getSessionPath(sessionId) {
3879
- return import_node_path9.join(this.historyDir, `${sessionId}.json`);
3918
+ return import_node_path10.join(this.historyDir, `${sessionId}.json`);
3880
3919
  }
3881
3920
  saveSession(session) {
3882
3921
  const filePath = this.getSessionPath(session.id);
3883
3922
  session.updatedAt = Date.now();
3884
- import_node_fs7.writeFileSync(filePath, JSON.stringify(session, null, 2), "utf-8");
3923
+ import_node_fs8.writeFileSync(filePath, JSON.stringify(session, null, 2), "utf-8");
3885
3924
  }
3886
3925
  loadSession(sessionId) {
3887
3926
  const filePath = this.getSessionPath(sessionId);
3888
- if (!import_node_fs7.existsSync(filePath)) {
3927
+ if (!import_node_fs8.existsSync(filePath)) {
3889
3928
  return null;
3890
3929
  }
3891
3930
  try {
3892
- const content = import_node_fs7.readFileSync(filePath, "utf-8");
3931
+ const content = import_node_fs8.readFileSync(filePath, "utf-8");
3893
3932
  return JSON.parse(content);
3894
3933
  } catch {
3895
3934
  return null;
@@ -3897,18 +3936,18 @@ class HistoryManager {
3897
3936
  }
3898
3937
  deleteSession(sessionId) {
3899
3938
  const filePath = this.getSessionPath(sessionId);
3900
- if (!import_node_fs7.existsSync(filePath)) {
3939
+ if (!import_node_fs8.existsSync(filePath)) {
3901
3940
  return false;
3902
3941
  }
3903
3942
  try {
3904
- import_node_fs7.rmSync(filePath);
3943
+ import_node_fs8.rmSync(filePath);
3905
3944
  return true;
3906
3945
  } catch {
3907
3946
  return false;
3908
3947
  }
3909
3948
  }
3910
3949
  listSessions(options) {
3911
- const files = import_node_fs7.readdirSync(this.historyDir);
3950
+ const files = import_node_fs8.readdirSync(this.historyDir);
3912
3951
  let sessions = [];
3913
3952
  for (const file of files) {
3914
3953
  if (file.endsWith(".json")) {
@@ -3981,11 +4020,11 @@ class HistoryManager {
3981
4020
  return deleted;
3982
4021
  }
3983
4022
  getSessionCount() {
3984
- const files = import_node_fs7.readdirSync(this.historyDir);
4023
+ const files = import_node_fs8.readdirSync(this.historyDir);
3985
4024
  return files.filter((f) => f.endsWith(".json")).length;
3986
4025
  }
3987
4026
  sessionExists(sessionId) {
3988
- return import_node_fs7.existsSync(this.getSessionPath(sessionId));
4027
+ return import_node_fs8.existsSync(this.getSessionPath(sessionId));
3989
4028
  }
3990
4029
  findSessionByPartialId(partialId) {
3991
4030
  const sessions = this.listSessions();
@@ -3999,12 +4038,12 @@ class HistoryManager {
3999
4038
  return this.historyDir;
4000
4039
  }
4001
4040
  clearAllSessions() {
4002
- const files = import_node_fs7.readdirSync(this.historyDir);
4041
+ const files = import_node_fs8.readdirSync(this.historyDir);
4003
4042
  let deleted = 0;
4004
4043
  for (const file of files) {
4005
4044
  if (file.endsWith(".json")) {
4006
4045
  try {
4007
- import_node_fs7.rmSync(import_node_path9.join(this.historyDir, file));
4046
+ import_node_fs8.rmSync(import_node_path10.join(this.historyDir, file));
4008
4047
  deleted++;
4009
4048
  } catch {}
4010
4049
  }
@@ -4270,8 +4309,8 @@ ${currentPrompt}`);
4270
4309
  }
4271
4310
  // src/orchestrator.ts
4272
4311
  var import_node_child_process7 = require("node:child_process");
4273
- var import_node_fs8 = require("node:fs");
4274
- var import_node_path10 = require("node:path");
4312
+ var import_node_fs9 = require("node:fs");
4313
+ var import_node_path11 = require("node:path");
4275
4314
  var import_node_url = require("node:url");
4276
4315
  var import_shared4 = require("@locusai/shared");
4277
4316
  var import_events4 = require("events");
@@ -4482,13 +4521,13 @@ ${agentId} finished (exit code: ${code})`);
4482
4521
  }
4483
4522
  resolveWorkerPath() {
4484
4523
  const currentModulePath = import_node_url.fileURLToPath("file:///home/runner/work/locusai/locusai/packages/sdk/src/orchestrator.ts");
4485
- const currentModuleDir = import_node_path10.dirname(currentModulePath);
4524
+ const currentModuleDir = import_node_path11.dirname(currentModulePath);
4486
4525
  const potentialPaths = [
4487
- import_node_path10.join(currentModuleDir, "agent", "worker.js"),
4488
- import_node_path10.join(currentModuleDir, "worker.js"),
4489
- import_node_path10.join(currentModuleDir, "agent", "worker.ts")
4526
+ import_node_path11.join(currentModuleDir, "agent", "worker.js"),
4527
+ import_node_path11.join(currentModuleDir, "worker.js"),
4528
+ import_node_path11.join(currentModuleDir, "agent", "worker.ts")
4490
4529
  ];
4491
- return potentialPaths.find((p) => import_node_fs8.existsSync(p));
4530
+ return potentialPaths.find((p) => import_node_fs9.existsSync(p));
4492
4531
  }
4493
4532
  startHeartbeatMonitor() {
4494
4533
  this.heartbeatInterval = setInterval(() => {
@@ -4663,8 +4702,8 @@ ${summary}`
4663
4702
  }
4664
4703
  }
4665
4704
  // src/planning/plan-manager.ts
4666
- var import_node_fs9 = require("node:fs");
4667
- var import_node_path11 = require("node:path");
4705
+ var import_node_fs10 = require("node:fs");
4706
+ var import_node_path12 = require("node:path");
4668
4707
 
4669
4708
  // src/planning/sprint-plan.ts
4670
4709
  var import_shared5 = require("@locusai/shared");
@@ -4787,19 +4826,19 @@ class PlanManager {
4787
4826
  save(plan) {
4788
4827
  this.ensurePlansDir();
4789
4828
  const slug = this.slugify(plan.name);
4790
- const jsonPath = import_node_path11.join(this.plansDir, `${slug}.json`);
4791
- const mdPath = import_node_path11.join(this.plansDir, `sprint-${slug}.md`);
4792
- import_node_fs9.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf-8");
4793
- import_node_fs9.writeFileSync(mdPath, sprintPlanToMarkdown(plan), "utf-8");
4829
+ const jsonPath = import_node_path12.join(this.plansDir, `${slug}.json`);
4830
+ const mdPath = import_node_path12.join(this.plansDir, `sprint-${slug}.md`);
4831
+ import_node_fs10.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf-8");
4832
+ import_node_fs10.writeFileSync(mdPath, sprintPlanToMarkdown(plan), "utf-8");
4794
4833
  return plan.id;
4795
4834
  }
4796
4835
  load(idOrSlug) {
4797
4836
  this.ensurePlansDir();
4798
- const files = import_node_fs9.readdirSync(this.plansDir).filter((f) => f.endsWith(".json"));
4837
+ const files = import_node_fs10.readdirSync(this.plansDir).filter((f) => f.endsWith(".json"));
4799
4838
  for (const file of files) {
4800
- const filePath = import_node_path11.join(this.plansDir, file);
4839
+ const filePath = import_node_path12.join(this.plansDir, file);
4801
4840
  try {
4802
- const plan = JSON.parse(import_node_fs9.readFileSync(filePath, "utf-8"));
4841
+ const plan = JSON.parse(import_node_fs10.readFileSync(filePath, "utf-8"));
4803
4842
  if (plan.id === idOrSlug || this.slugify(plan.name) === idOrSlug) {
4804
4843
  return plan;
4805
4844
  }
@@ -4809,11 +4848,11 @@ class PlanManager {
4809
4848
  }
4810
4849
  list(status) {
4811
4850
  this.ensurePlansDir();
4812
- const files = import_node_fs9.readdirSync(this.plansDir).filter((f) => f.endsWith(".json"));
4851
+ const files = import_node_fs10.readdirSync(this.plansDir).filter((f) => f.endsWith(".json"));
4813
4852
  const plans = [];
4814
4853
  for (const file of files) {
4815
4854
  try {
4816
- const plan = JSON.parse(import_node_fs9.readFileSync(import_node_path11.join(this.plansDir, file), "utf-8"));
4855
+ const plan = JSON.parse(import_node_fs10.readFileSync(import_node_path12.join(this.plansDir, file), "utf-8"));
4817
4856
  if (!status || plan.status === status) {
4818
4857
  plans.push(plan);
4819
4858
  }
@@ -4876,18 +4915,18 @@ class PlanManager {
4876
4915
  }
4877
4916
  delete(idOrSlug) {
4878
4917
  this.ensurePlansDir();
4879
- const files = import_node_fs9.readdirSync(this.plansDir);
4918
+ const files = import_node_fs10.readdirSync(this.plansDir);
4880
4919
  for (const file of files) {
4881
- const filePath = import_node_path11.join(this.plansDir, file);
4920
+ const filePath = import_node_path12.join(this.plansDir, file);
4882
4921
  if (!file.endsWith(".json"))
4883
4922
  continue;
4884
4923
  try {
4885
- const plan = JSON.parse(import_node_fs9.readFileSync(filePath, "utf-8"));
4924
+ const plan = JSON.parse(import_node_fs10.readFileSync(filePath, "utf-8"));
4886
4925
  if (plan.id === idOrSlug || this.slugify(plan.name) === idOrSlug) {
4887
- import_node_fs9.unlinkSync(filePath);
4888
- const mdPath = import_node_path11.join(this.plansDir, `sprint-${this.slugify(plan.name)}.md`);
4889
- if (import_node_fs9.existsSync(mdPath)) {
4890
- import_node_fs9.unlinkSync(mdPath);
4926
+ import_node_fs10.unlinkSync(filePath);
4927
+ const mdPath = import_node_path12.join(this.plansDir, `sprint-${this.slugify(plan.name)}.md`);
4928
+ if (import_node_fs10.existsSync(mdPath)) {
4929
+ import_node_fs10.unlinkSync(mdPath);
4891
4930
  }
4892
4931
  return;
4893
4932
  }
@@ -4901,8 +4940,8 @@ class PlanManager {
4901
4940
  return sprintPlanToMarkdown(plan);
4902
4941
  }
4903
4942
  ensurePlansDir() {
4904
- if (!import_node_fs9.existsSync(this.plansDir)) {
4905
- import_node_fs9.mkdirSync(this.plansDir, { recursive: true });
4943
+ if (!import_node_fs10.existsSync(this.plansDir)) {
4944
+ import_node_fs10.mkdirSync(this.plansDir, { recursive: true });
4906
4945
  }
4907
4946
  }
4908
4947
  slugify(name) {
@@ -4910,7 +4949,7 @@ class PlanManager {
4910
4949
  }
4911
4950
  }
4912
4951
  // src/planning/planning-meeting.ts
4913
- var import_node_fs10 = require("node:fs");
4952
+ var import_node_fs11 = require("node:fs");
4914
4953
 
4915
4954
  // src/planning/agents/architect.ts
4916
4955
  function buildArchitectPrompt(input) {
@@ -5164,11 +5203,11 @@ class PlanningMeeting {
5164
5203
  }
5165
5204
  getCodebaseIndex() {
5166
5205
  const indexPath = getLocusPath(this.projectPath, "indexFile");
5167
- if (!import_node_fs10.existsSync(indexPath)) {
5206
+ if (!import_node_fs11.existsSync(indexPath)) {
5168
5207
  return "";
5169
5208
  }
5170
5209
  try {
5171
- const raw = import_node_fs10.readFileSync(indexPath, "utf-8");
5210
+ const raw = import_node_fs11.readFileSync(indexPath, "utf-8");
5172
5211
  const index = JSON.parse(raw);
5173
5212
  const parts = [];
5174
5213
  if (index.responsibilities) {
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Build a PATH string that includes common CLI binary directories
3
+ * in addition to the current process PATH. Existing entries take priority.
4
+ */
5
+ export declare function getAugmentedPath(): string;
6
+ /**
7
+ * Returns a copy of the current process.env with an augmented PATH.
8
+ * Use this when spawning CLI tools (claude, codex) to ensure they
9
+ * can be found even when running from restricted environments.
10
+ */
11
+ export declare function getAugmentedEnv(overrides?: Record<string, string>): NodeJS.ProcessEnv;
12
+ //# sourceMappingURL=resolve-bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-bin.d.ts","sourceRoot":"","sources":["../../src/utils/resolve-bin.ts"],"names":[],"mappings":"AAuCA;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAUzC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACrC,MAAM,CAAC,UAAU,CAMnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locusai/sdk",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -30,7 +30,7 @@
30
30
  "clean": "rm -rf node_modules"
31
31
  },
32
32
  "dependencies": {
33
- "@locusai/shared": "^0.9.4",
33
+ "@locusai/shared": "^0.9.5",
34
34
  "axios": "^1.13.2",
35
35
  "events": "^3.3.0",
36
36
  "globby": "^14.0.2"