@locusai/cli 0.9.3 → 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.
- package/bin/agent/worker.js +81 -42
- package/bin/locus.js +166 -133
- package/package.json +2 -2
package/bin/agent/worker.js
CHANGED
|
@@ -10402,8 +10402,8 @@ var require_common = __commonJS((exports, module) => {
|
|
|
10402
10402
|
}
|
|
10403
10403
|
return debug;
|
|
10404
10404
|
}
|
|
10405
|
-
function extend3(namespace,
|
|
10406
|
-
const newDebug = createDebug(this.namespace + (typeof
|
|
10405
|
+
function extend3(namespace, delimiter2) {
|
|
10406
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter2 === "undefined" ? ":" : delimiter2) + namespace);
|
|
10407
10407
|
newDebug.log = this.log;
|
|
10408
10408
|
return newDebug;
|
|
10409
10409
|
}
|
|
@@ -25790,6 +25790,47 @@ var c = {
|
|
|
25790
25790
|
underline: (t) => c.text(t, "underline")
|
|
25791
25791
|
};
|
|
25792
25792
|
|
|
25793
|
+
// ../sdk/src/utils/resolve-bin.ts
|
|
25794
|
+
import { existsSync } from "node:fs";
|
|
25795
|
+
import { homedir } from "node:os";
|
|
25796
|
+
import { delimiter, join as join2 } from "node:path";
|
|
25797
|
+
var EXTRA_BIN_DIRS = [
|
|
25798
|
+
join2(homedir(), ".local", "bin"),
|
|
25799
|
+
join2(homedir(), ".npm", "bin"),
|
|
25800
|
+
join2(homedir(), ".npm-global", "bin"),
|
|
25801
|
+
join2(homedir(), ".yarn", "bin"),
|
|
25802
|
+
"/usr/local/bin"
|
|
25803
|
+
];
|
|
25804
|
+
function getNodeManagerDirs() {
|
|
25805
|
+
const dirs = [];
|
|
25806
|
+
const nvmDir = process.env.NVM_DIR || join2(homedir(), ".nvm");
|
|
25807
|
+
const nvmCurrent = join2(nvmDir, "current", "bin");
|
|
25808
|
+
if (existsSync(nvmCurrent)) {
|
|
25809
|
+
dirs.push(nvmCurrent);
|
|
25810
|
+
}
|
|
25811
|
+
const fnmDir = process.env.FNM_DIR || join2(homedir(), ".fnm");
|
|
25812
|
+
const fnmCurrent = join2(fnmDir, "current", "bin");
|
|
25813
|
+
if (existsSync(fnmCurrent)) {
|
|
25814
|
+
dirs.push(fnmCurrent);
|
|
25815
|
+
}
|
|
25816
|
+
return dirs;
|
|
25817
|
+
}
|
|
25818
|
+
function getAugmentedPath() {
|
|
25819
|
+
const currentPath = process.env.PATH || "";
|
|
25820
|
+
const currentDirs = new Set(currentPath.split(delimiter));
|
|
25821
|
+
const extra = [...EXTRA_BIN_DIRS, ...getNodeManagerDirs()].filter((dir) => !currentDirs.has(dir) && existsSync(dir));
|
|
25822
|
+
if (extra.length === 0)
|
|
25823
|
+
return currentPath;
|
|
25824
|
+
return currentPath + delimiter + extra.join(delimiter);
|
|
25825
|
+
}
|
|
25826
|
+
function getAugmentedEnv(overrides = {}) {
|
|
25827
|
+
return {
|
|
25828
|
+
...process.env,
|
|
25829
|
+
...overrides,
|
|
25830
|
+
PATH: getAugmentedPath()
|
|
25831
|
+
};
|
|
25832
|
+
}
|
|
25833
|
+
|
|
25793
25834
|
// ../sdk/src/ai/claude-runner.ts
|
|
25794
25835
|
var SANDBOX_SETTINGS = JSON.stringify({
|
|
25795
25836
|
sandbox: {
|
|
@@ -25853,11 +25894,10 @@ class ClaudeRunner {
|
|
|
25853
25894
|
"--settings",
|
|
25854
25895
|
SANDBOX_SETTINGS
|
|
25855
25896
|
];
|
|
25856
|
-
const env = {
|
|
25857
|
-
...process.env,
|
|
25897
|
+
const env = getAugmentedEnv({
|
|
25858
25898
|
FORCE_COLOR: "1",
|
|
25859
25899
|
TERM: "xterm-256color"
|
|
25860
|
-
};
|
|
25900
|
+
});
|
|
25861
25901
|
this.eventEmitter?.emitSessionStarted({
|
|
25862
25902
|
model: this.model,
|
|
25863
25903
|
provider: "claude"
|
|
@@ -26098,11 +26138,10 @@ class ClaudeRunner {
|
|
|
26098
26138
|
"--settings",
|
|
26099
26139
|
SANDBOX_SETTINGS
|
|
26100
26140
|
];
|
|
26101
|
-
const env = {
|
|
26102
|
-
...process.env,
|
|
26141
|
+
const env = getAugmentedEnv({
|
|
26103
26142
|
FORCE_COLOR: "1",
|
|
26104
26143
|
TERM: "xterm-256color"
|
|
26105
|
-
};
|
|
26144
|
+
});
|
|
26106
26145
|
const claude = spawn("claude", args, {
|
|
26107
26146
|
cwd: this.projectPath,
|
|
26108
26147
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -26202,9 +26241,9 @@ ${c.primary("[Claude]")} ${c.bold(`Running ${content_block.name}...`)}
|
|
|
26202
26241
|
// ../sdk/src/ai/codex-runner.ts
|
|
26203
26242
|
import { spawn as spawn2 } from "node:child_process";
|
|
26204
26243
|
import { randomUUID } from "node:crypto";
|
|
26205
|
-
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
26244
|
+
import { existsSync as existsSync2, readFileSync, unlinkSync } from "node:fs";
|
|
26206
26245
|
import { tmpdir } from "node:os";
|
|
26207
|
-
import { join as
|
|
26246
|
+
import { join as join3 } from "node:path";
|
|
26208
26247
|
class CodexRunner {
|
|
26209
26248
|
projectPath;
|
|
26210
26249
|
model;
|
|
@@ -26239,12 +26278,12 @@ class CodexRunner {
|
|
|
26239
26278
|
throw lastError || new Error("Codex CLI failed after multiple attempts");
|
|
26240
26279
|
}
|
|
26241
26280
|
async* runStream(prompt) {
|
|
26242
|
-
const outputPath =
|
|
26281
|
+
const outputPath = join3(tmpdir(), `locus-codex-${randomUUID()}.txt`);
|
|
26243
26282
|
const args = this.buildArgs(outputPath);
|
|
26244
26283
|
const codex = spawn2("codex", args, {
|
|
26245
26284
|
cwd: this.projectPath,
|
|
26246
26285
|
stdio: ["pipe", "pipe", "pipe"],
|
|
26247
|
-
env:
|
|
26286
|
+
env: getAugmentedEnv(),
|
|
26248
26287
|
shell: false
|
|
26249
26288
|
});
|
|
26250
26289
|
this.activeProcess = codex;
|
|
@@ -26335,12 +26374,12 @@ class CodexRunner {
|
|
|
26335
26374
|
}
|
|
26336
26375
|
executeRun(prompt) {
|
|
26337
26376
|
return new Promise((resolve2, reject) => {
|
|
26338
|
-
const outputPath =
|
|
26377
|
+
const outputPath = join3(tmpdir(), `locus-codex-${randomUUID()}.txt`);
|
|
26339
26378
|
const args = this.buildArgs(outputPath);
|
|
26340
26379
|
const codex = spawn2("codex", args, {
|
|
26341
26380
|
cwd: this.projectPath,
|
|
26342
26381
|
stdio: ["pipe", "pipe", "pipe"],
|
|
26343
|
-
env:
|
|
26382
|
+
env: getAugmentedEnv(),
|
|
26344
26383
|
shell: false
|
|
26345
26384
|
});
|
|
26346
26385
|
this.activeProcess = codex;
|
|
@@ -26407,7 +26446,7 @@ class CodexRunner {
|
|
|
26407
26446
|
].some((pattern) => pattern.test(line));
|
|
26408
26447
|
}
|
|
26409
26448
|
readOutput(outputPath, fallback) {
|
|
26410
|
-
if (
|
|
26449
|
+
if (existsSync2(outputPath)) {
|
|
26411
26450
|
try {
|
|
26412
26451
|
const text = readFileSync(outputPath, "utf-8").trim();
|
|
26413
26452
|
if (text)
|
|
@@ -26423,7 +26462,7 @@ class CodexRunner {
|
|
|
26423
26462
|
}
|
|
26424
26463
|
cleanupTempFile(path) {
|
|
26425
26464
|
try {
|
|
26426
|
-
if (
|
|
26465
|
+
if (existsSync2(path))
|
|
26427
26466
|
unlinkSync(path);
|
|
26428
26467
|
} catch {}
|
|
26429
26468
|
}
|
|
@@ -27051,14 +27090,14 @@ var freezeMethods = (obj) => {
|
|
|
27051
27090
|
}
|
|
27052
27091
|
});
|
|
27053
27092
|
};
|
|
27054
|
-
var toObjectSet = (arrayOrString,
|
|
27093
|
+
var toObjectSet = (arrayOrString, delimiter2) => {
|
|
27055
27094
|
const obj = {};
|
|
27056
27095
|
const define = (arr) => {
|
|
27057
27096
|
arr.forEach((value) => {
|
|
27058
27097
|
obj[value] = true;
|
|
27059
27098
|
});
|
|
27060
27099
|
};
|
|
27061
|
-
isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(
|
|
27100
|
+
isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter2));
|
|
27062
27101
|
return obj;
|
|
27063
27102
|
};
|
|
27064
27103
|
var noop = () => {};
|
|
@@ -30574,7 +30613,7 @@ class LocusClient {
|
|
|
30574
30613
|
}
|
|
30575
30614
|
|
|
30576
30615
|
// ../sdk/src/project/knowledge-base.ts
|
|
30577
|
-
import { existsSync as
|
|
30616
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
30578
30617
|
import { dirname } from "node:path";
|
|
30579
30618
|
class KnowledgeBase {
|
|
30580
30619
|
contextPath;
|
|
@@ -30584,13 +30623,13 @@ class KnowledgeBase {
|
|
|
30584
30623
|
this.progressPath = getLocusPath(projectPath, "projectProgressFile");
|
|
30585
30624
|
}
|
|
30586
30625
|
readContext() {
|
|
30587
|
-
if (!
|
|
30626
|
+
if (!existsSync3(this.contextPath)) {
|
|
30588
30627
|
return "";
|
|
30589
30628
|
}
|
|
30590
30629
|
return readFileSync2(this.contextPath, "utf-8");
|
|
30591
30630
|
}
|
|
30592
30631
|
readProgress() {
|
|
30593
|
-
if (!
|
|
30632
|
+
if (!existsSync3(this.progressPath)) {
|
|
30594
30633
|
return "";
|
|
30595
30634
|
}
|
|
30596
30635
|
return readFileSync2(this.progressPath, "utf-8");
|
|
@@ -30691,11 +30730,11 @@ No sprints started yet.
|
|
|
30691
30730
|
writeFileSync(this.progressPath, progressContent);
|
|
30692
30731
|
}
|
|
30693
30732
|
get exists() {
|
|
30694
|
-
return
|
|
30733
|
+
return existsSync3(this.contextPath) || existsSync3(this.progressPath);
|
|
30695
30734
|
}
|
|
30696
30735
|
ensureDir(filePath) {
|
|
30697
30736
|
const dir = dirname(filePath);
|
|
30698
|
-
if (!
|
|
30737
|
+
if (!existsSync3(dir)) {
|
|
30699
30738
|
mkdirSync(dir, { recursive: true });
|
|
30700
30739
|
}
|
|
30701
30740
|
}
|
|
@@ -30703,8 +30742,8 @@ No sprints started yet.
|
|
|
30703
30742
|
|
|
30704
30743
|
// ../sdk/src/worktree/worktree-manager.ts
|
|
30705
30744
|
import { execFileSync as execFileSync3, execSync } from "node:child_process";
|
|
30706
|
-
import { existsSync as
|
|
30707
|
-
import { join as
|
|
30745
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, rmSync, statSync } from "node:fs";
|
|
30746
|
+
import { join as join4, resolve as resolve2, sep } from "node:path";
|
|
30708
30747
|
|
|
30709
30748
|
// ../sdk/src/worktree/worktree-config.ts
|
|
30710
30749
|
var WORKTREE_ROOT_DIR = ".locus-worktrees";
|
|
@@ -30728,7 +30767,7 @@ class WorktreeManager {
|
|
|
30728
30767
|
});
|
|
30729
30768
|
}
|
|
30730
30769
|
get rootPath() {
|
|
30731
|
-
return
|
|
30770
|
+
return join4(this.projectPath, this.config.rootDir);
|
|
30732
30771
|
}
|
|
30733
30772
|
buildBranchName(taskId, taskSlug) {
|
|
30734
30773
|
const sanitized = taskSlug.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50);
|
|
@@ -30737,11 +30776,11 @@ class WorktreeManager {
|
|
|
30737
30776
|
create(options) {
|
|
30738
30777
|
const branch = this.buildBranchName(options.taskId, options.taskSlug);
|
|
30739
30778
|
const worktreeDir = `${options.agentId}-${options.taskId}`;
|
|
30740
|
-
const worktreePath =
|
|
30779
|
+
const worktreePath = join4(this.rootPath, worktreeDir);
|
|
30741
30780
|
this.ensureDirectory(this.rootPath, "Worktree root");
|
|
30742
30781
|
const baseBranch = options.baseBranch ?? this.config.baseBranch ?? this.getCurrentBranch();
|
|
30743
30782
|
this.log(`Creating worktree: ${worktreeDir} (branch: ${branch}, base: ${baseBranch})`, "info");
|
|
30744
|
-
if (
|
|
30783
|
+
if (existsSync4(worktreePath)) {
|
|
30745
30784
|
this.log(`Removing stale worktree directory: ${worktreePath}`, "warn");
|
|
30746
30785
|
try {
|
|
30747
30786
|
this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
|
|
@@ -30835,7 +30874,7 @@ class WorktreeManager {
|
|
|
30835
30874
|
try {
|
|
30836
30875
|
this.git(`worktree remove "${absolutePath}" --force`, this.projectPath);
|
|
30837
30876
|
} catch {
|
|
30838
|
-
if (
|
|
30877
|
+
if (existsSync4(absolutePath)) {
|
|
30839
30878
|
rmSync(absolutePath, { recursive: true, force: true });
|
|
30840
30879
|
}
|
|
30841
30880
|
this.git("worktree prune", this.projectPath);
|
|
@@ -30871,7 +30910,7 @@ class WorktreeManager {
|
|
|
30871
30910
|
this.log(`Failed to remove worktree: ${wt.path}`, "warn");
|
|
30872
30911
|
}
|
|
30873
30912
|
}
|
|
30874
|
-
if (
|
|
30913
|
+
if (existsSync4(this.rootPath)) {
|
|
30875
30914
|
try {
|
|
30876
30915
|
rmSync(this.rootPath, { recursive: true, force: true });
|
|
30877
30916
|
} catch {}
|
|
@@ -30937,7 +30976,7 @@ class WorktreeManager {
|
|
|
30937
30976
|
return candidate.startsWith(rootWithSep);
|
|
30938
30977
|
}
|
|
30939
30978
|
ensureDirectory(dirPath, label) {
|
|
30940
|
-
if (
|
|
30979
|
+
if (existsSync4(dirPath)) {
|
|
30941
30980
|
if (!statSync(dirPath).isDirectory()) {
|
|
30942
30981
|
throw new Error(`${label} exists but is not a directory: ${dirPath}`);
|
|
30943
30982
|
}
|
|
@@ -30953,7 +30992,7 @@ class WorktreeManager {
|
|
|
30953
30992
|
try {
|
|
30954
30993
|
this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
|
|
30955
30994
|
} catch {}
|
|
30956
|
-
if (
|
|
30995
|
+
if (existsSync4(worktreePath)) {
|
|
30957
30996
|
rmSync(worktreePath, { recursive: true, force: true });
|
|
30958
30997
|
}
|
|
30959
30998
|
try {
|
|
@@ -30986,8 +31025,8 @@ class WorktreeManager {
|
|
|
30986
31025
|
}
|
|
30987
31026
|
|
|
30988
31027
|
// ../sdk/src/core/prompt-builder.ts
|
|
30989
|
-
import { existsSync as
|
|
30990
|
-
import { join as
|
|
31028
|
+
import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
|
|
31029
|
+
import { join as join5 } from "node:path";
|
|
30991
31030
|
class PromptBuilder {
|
|
30992
31031
|
projectPath;
|
|
30993
31032
|
constructor(projectPath) {
|
|
@@ -31028,7 +31067,7 @@ ${task2.description || "No description provided."}
|
|
|
31028
31067
|
}
|
|
31029
31068
|
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
31030
31069
|
let hasLocalContext = false;
|
|
31031
|
-
if (
|
|
31070
|
+
if (existsSync5(contextPath)) {
|
|
31032
31071
|
try {
|
|
31033
31072
|
const context = readFileSync3(contextPath, "utf-8");
|
|
31034
31073
|
if (context.trim().length > 20) {
|
|
@@ -31084,7 +31123,7 @@ ${serverContext.context}
|
|
|
31084
31123
|
|
|
31085
31124
|
`;
|
|
31086
31125
|
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
31087
|
-
if (
|
|
31126
|
+
if (existsSync5(indexPath)) {
|
|
31088
31127
|
prompt += `## Codebase Overview
|
|
31089
31128
|
There is an index file in the .locus/codebase-index.json and if you need you can check it.
|
|
31090
31129
|
|
|
@@ -31159,7 +31198,7 @@ ${query}
|
|
|
31159
31198
|
}
|
|
31160
31199
|
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
31161
31200
|
let hasLocalContext = false;
|
|
31162
|
-
if (
|
|
31201
|
+
if (existsSync5(contextPath)) {
|
|
31163
31202
|
try {
|
|
31164
31203
|
const context = readFileSync3(contextPath, "utf-8");
|
|
31165
31204
|
if (context.trim().length > 20) {
|
|
@@ -31195,7 +31234,7 @@ ${fallback}
|
|
|
31195
31234
|
|
|
31196
31235
|
`;
|
|
31197
31236
|
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
31198
|
-
if (
|
|
31237
|
+
if (existsSync5(indexPath)) {
|
|
31199
31238
|
prompt += `## Codebase Overview
|
|
31200
31239
|
There is an index file in the .locus/codebase-index.json and if you need you can check it.
|
|
31201
31240
|
|
|
@@ -31208,7 +31247,7 @@ There is an index file in the .locus/codebase-index.json and if you need you can
|
|
|
31208
31247
|
}
|
|
31209
31248
|
getProjectConfig() {
|
|
31210
31249
|
const configPath = getLocusPath(this.projectPath, "configFile");
|
|
31211
|
-
if (
|
|
31250
|
+
if (existsSync5(configPath)) {
|
|
31212
31251
|
try {
|
|
31213
31252
|
return JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
31214
31253
|
} catch {
|
|
@@ -31218,8 +31257,8 @@ There is an index file in the .locus/codebase-index.json and if you need you can
|
|
|
31218
31257
|
return null;
|
|
31219
31258
|
}
|
|
31220
31259
|
getFallbackContext() {
|
|
31221
|
-
const readmePath =
|
|
31222
|
-
if (
|
|
31260
|
+
const readmePath = join5(this.projectPath, "README.md");
|
|
31261
|
+
if (existsSync5(readmePath)) {
|
|
31223
31262
|
try {
|
|
31224
31263
|
const content = readFileSync3(readmePath, "utf-8");
|
|
31225
31264
|
const limit = 1000;
|
|
@@ -31238,7 +31277,7 @@ There is an index file in the .locus/codebase-index.json and if you need you can
|
|
|
31238
31277
|
if (e.startsWith(".") || e === "node_modules")
|
|
31239
31278
|
return false;
|
|
31240
31279
|
try {
|
|
31241
|
-
return statSync2(
|
|
31280
|
+
return statSync2(join5(this.projectPath, e)).isDirectory();
|
|
31242
31281
|
} catch {
|
|
31243
31282
|
return false;
|
|
31244
31283
|
}
|
package/bin/locus.js
CHANGED
|
@@ -6556,6 +6556,50 @@ var init_colors = __esm(() => {
|
|
|
6556
6556
|
};
|
|
6557
6557
|
});
|
|
6558
6558
|
|
|
6559
|
+
// ../sdk/src/utils/resolve-bin.ts
|
|
6560
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
6561
|
+
import { homedir } from "node:os";
|
|
6562
|
+
import { delimiter, join as join4 } from "node:path";
|
|
6563
|
+
function getNodeManagerDirs() {
|
|
6564
|
+
const dirs = [];
|
|
6565
|
+
const nvmDir = process.env.NVM_DIR || join4(homedir(), ".nvm");
|
|
6566
|
+
const nvmCurrent = join4(nvmDir, "current", "bin");
|
|
6567
|
+
if (existsSync3(nvmCurrent)) {
|
|
6568
|
+
dirs.push(nvmCurrent);
|
|
6569
|
+
}
|
|
6570
|
+
const fnmDir = process.env.FNM_DIR || join4(homedir(), ".fnm");
|
|
6571
|
+
const fnmCurrent = join4(fnmDir, "current", "bin");
|
|
6572
|
+
if (existsSync3(fnmCurrent)) {
|
|
6573
|
+
dirs.push(fnmCurrent);
|
|
6574
|
+
}
|
|
6575
|
+
return dirs;
|
|
6576
|
+
}
|
|
6577
|
+
function getAugmentedPath() {
|
|
6578
|
+
const currentPath = process.env.PATH || "";
|
|
6579
|
+
const currentDirs = new Set(currentPath.split(delimiter));
|
|
6580
|
+
const extra = [...EXTRA_BIN_DIRS, ...getNodeManagerDirs()].filter((dir) => !currentDirs.has(dir) && existsSync3(dir));
|
|
6581
|
+
if (extra.length === 0)
|
|
6582
|
+
return currentPath;
|
|
6583
|
+
return currentPath + delimiter + extra.join(delimiter);
|
|
6584
|
+
}
|
|
6585
|
+
function getAugmentedEnv(overrides = {}) {
|
|
6586
|
+
return {
|
|
6587
|
+
...process.env,
|
|
6588
|
+
...overrides,
|
|
6589
|
+
PATH: getAugmentedPath()
|
|
6590
|
+
};
|
|
6591
|
+
}
|
|
6592
|
+
var EXTRA_BIN_DIRS;
|
|
6593
|
+
var init_resolve_bin = __esm(() => {
|
|
6594
|
+
EXTRA_BIN_DIRS = [
|
|
6595
|
+
join4(homedir(), ".local", "bin"),
|
|
6596
|
+
join4(homedir(), ".npm", "bin"),
|
|
6597
|
+
join4(homedir(), ".npm-global", "bin"),
|
|
6598
|
+
join4(homedir(), ".yarn", "bin"),
|
|
6599
|
+
"/usr/local/bin"
|
|
6600
|
+
];
|
|
6601
|
+
});
|
|
6602
|
+
|
|
6559
6603
|
// ../sdk/src/ai/claude-runner.ts
|
|
6560
6604
|
import { spawn } from "node:child_process";
|
|
6561
6605
|
import { resolve } from "node:path";
|
|
@@ -6614,11 +6658,10 @@ class ClaudeRunner {
|
|
|
6614
6658
|
"--settings",
|
|
6615
6659
|
SANDBOX_SETTINGS
|
|
6616
6660
|
];
|
|
6617
|
-
const env = {
|
|
6618
|
-
...process.env,
|
|
6661
|
+
const env = getAugmentedEnv({
|
|
6619
6662
|
FORCE_COLOR: "1",
|
|
6620
6663
|
TERM: "xterm-256color"
|
|
6621
|
-
};
|
|
6664
|
+
});
|
|
6622
6665
|
this.eventEmitter?.emitSessionStarted({
|
|
6623
6666
|
model: this.model,
|
|
6624
6667
|
provider: "claude"
|
|
@@ -6859,11 +6902,10 @@ class ClaudeRunner {
|
|
|
6859
6902
|
"--settings",
|
|
6860
6903
|
SANDBOX_SETTINGS
|
|
6861
6904
|
];
|
|
6862
|
-
const env = {
|
|
6863
|
-
...process.env,
|
|
6905
|
+
const env = getAugmentedEnv({
|
|
6864
6906
|
FORCE_COLOR: "1",
|
|
6865
6907
|
TERM: "xterm-256color"
|
|
6866
|
-
};
|
|
6908
|
+
});
|
|
6867
6909
|
const claude = spawn("claude", args, {
|
|
6868
6910
|
cwd: this.projectPath,
|
|
6869
6911
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -6963,6 +7005,7 @@ var SANDBOX_SETTINGS;
|
|
|
6963
7005
|
var init_claude_runner = __esm(() => {
|
|
6964
7006
|
init_config();
|
|
6965
7007
|
init_colors();
|
|
7008
|
+
init_resolve_bin();
|
|
6966
7009
|
SANDBOX_SETTINGS = JSON.stringify({
|
|
6967
7010
|
sandbox: {
|
|
6968
7011
|
enabled: true,
|
|
@@ -6975,9 +7018,9 @@ var init_claude_runner = __esm(() => {
|
|
|
6975
7018
|
// ../sdk/src/ai/codex-runner.ts
|
|
6976
7019
|
import { spawn as spawn2 } from "node:child_process";
|
|
6977
7020
|
import { randomUUID } from "node:crypto";
|
|
6978
|
-
import { existsSync as
|
|
7021
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, unlinkSync } from "node:fs";
|
|
6979
7022
|
import { tmpdir } from "node:os";
|
|
6980
|
-
import { join as
|
|
7023
|
+
import { join as join5 } from "node:path";
|
|
6981
7024
|
|
|
6982
7025
|
class CodexRunner {
|
|
6983
7026
|
projectPath;
|
|
@@ -7013,12 +7056,12 @@ class CodexRunner {
|
|
|
7013
7056
|
throw lastError || new Error("Codex CLI failed after multiple attempts");
|
|
7014
7057
|
}
|
|
7015
7058
|
async* runStream(prompt) {
|
|
7016
|
-
const outputPath =
|
|
7059
|
+
const outputPath = join5(tmpdir(), `locus-codex-${randomUUID()}.txt`);
|
|
7017
7060
|
const args = this.buildArgs(outputPath);
|
|
7018
7061
|
const codex = spawn2("codex", args, {
|
|
7019
7062
|
cwd: this.projectPath,
|
|
7020
7063
|
stdio: ["pipe", "pipe", "pipe"],
|
|
7021
|
-
env:
|
|
7064
|
+
env: getAugmentedEnv(),
|
|
7022
7065
|
shell: false
|
|
7023
7066
|
});
|
|
7024
7067
|
this.activeProcess = codex;
|
|
@@ -7109,12 +7152,12 @@ class CodexRunner {
|
|
|
7109
7152
|
}
|
|
7110
7153
|
executeRun(prompt) {
|
|
7111
7154
|
return new Promise((resolve2, reject) => {
|
|
7112
|
-
const outputPath =
|
|
7155
|
+
const outputPath = join5(tmpdir(), `locus-codex-${randomUUID()}.txt`);
|
|
7113
7156
|
const args = this.buildArgs(outputPath);
|
|
7114
7157
|
const codex = spawn2("codex", args, {
|
|
7115
7158
|
cwd: this.projectPath,
|
|
7116
7159
|
stdio: ["pipe", "pipe", "pipe"],
|
|
7117
|
-
env:
|
|
7160
|
+
env: getAugmentedEnv(),
|
|
7118
7161
|
shell: false
|
|
7119
7162
|
});
|
|
7120
7163
|
this.activeProcess = codex;
|
|
@@ -7181,7 +7224,7 @@ class CodexRunner {
|
|
|
7181
7224
|
].some((pattern) => pattern.test(line));
|
|
7182
7225
|
}
|
|
7183
7226
|
readOutput(outputPath, fallback) {
|
|
7184
|
-
if (
|
|
7227
|
+
if (existsSync4(outputPath)) {
|
|
7185
7228
|
try {
|
|
7186
7229
|
const text = readFileSync3(outputPath, "utf-8").trim();
|
|
7187
7230
|
if (text)
|
|
@@ -7197,7 +7240,7 @@ class CodexRunner {
|
|
|
7197
7240
|
}
|
|
7198
7241
|
cleanupTempFile(path2) {
|
|
7199
7242
|
try {
|
|
7200
|
-
if (
|
|
7243
|
+
if (existsSync4(path2))
|
|
7201
7244
|
unlinkSync(path2);
|
|
7202
7245
|
} catch {}
|
|
7203
7246
|
}
|
|
@@ -7207,6 +7250,7 @@ class CodexRunner {
|
|
|
7207
7250
|
}
|
|
7208
7251
|
var init_codex_runner = __esm(() => {
|
|
7209
7252
|
init_config();
|
|
7253
|
+
init_resolve_bin();
|
|
7210
7254
|
});
|
|
7211
7255
|
|
|
7212
7256
|
// ../sdk/src/ai/factory.ts
|
|
@@ -7788,14 +7832,14 @@ var toString, getPrototypeOf, iterator, toStringTag, kindOf, kindOfTest = (type)
|
|
|
7788
7832
|
};
|
|
7789
7833
|
}
|
|
7790
7834
|
});
|
|
7791
|
-
}, toObjectSet = (arrayOrString,
|
|
7835
|
+
}, toObjectSet = (arrayOrString, delimiter2) => {
|
|
7792
7836
|
const obj = {};
|
|
7793
7837
|
const define = (arr) => {
|
|
7794
7838
|
arr.forEach((value) => {
|
|
7795
7839
|
obj[value] = true;
|
|
7796
7840
|
});
|
|
7797
7841
|
};
|
|
7798
|
-
isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(
|
|
7842
|
+
isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter2));
|
|
7799
7843
|
return obj;
|
|
7800
7844
|
}, noop2 = () => {}, toFiniteNumber = (value, defaultValue) => {
|
|
7801
7845
|
return value != null && Number.isFinite(value = +value) ? value : defaultValue;
|
|
@@ -19218,8 +19262,8 @@ var require_common3 = __commonJS((exports, module) => {
|
|
|
19218
19262
|
}
|
|
19219
19263
|
return debug;
|
|
19220
19264
|
}
|
|
19221
|
-
function extend2(namespace,
|
|
19222
|
-
const newDebug = createDebug(this.namespace + (typeof
|
|
19265
|
+
function extend2(namespace, delimiter2) {
|
|
19266
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter2 === "undefined" ? ":" : delimiter2) + namespace);
|
|
19223
19267
|
newDebug.log = this.log;
|
|
19224
19268
|
return newDebug;
|
|
19225
19269
|
}
|
|
@@ -23820,8 +23864,8 @@ var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uui
|
|
|
23820
23864
|
if (!version)
|
|
23821
23865
|
return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
|
|
23822
23866
|
return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
|
|
23823
|
-
}, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (
|
|
23824
|
-
const escapedDelim = escapeRegex(
|
|
23867
|
+
}, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (delimiter2) => {
|
|
23868
|
+
const escapedDelim = escapeRegex(delimiter2 ?? ":");
|
|
23825
23869
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
23826
23870
|
}, cidrv4, cidrv6, base64, base64url, hostname, domain, e164, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date, string = (params) => {
|
|
23827
23871
|
const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
|
|
@@ -37700,7 +37744,7 @@ var init_src2 = __esm(() => {
|
|
|
37700
37744
|
});
|
|
37701
37745
|
|
|
37702
37746
|
// ../sdk/src/project/knowledge-base.ts
|
|
37703
|
-
import { existsSync as
|
|
37747
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
37704
37748
|
import { dirname as dirname2 } from "node:path";
|
|
37705
37749
|
|
|
37706
37750
|
class KnowledgeBase {
|
|
@@ -37711,13 +37755,13 @@ class KnowledgeBase {
|
|
|
37711
37755
|
this.progressPath = getLocusPath(projectPath, "projectProgressFile");
|
|
37712
37756
|
}
|
|
37713
37757
|
readContext() {
|
|
37714
|
-
if (!
|
|
37758
|
+
if (!existsSync5(this.contextPath)) {
|
|
37715
37759
|
return "";
|
|
37716
37760
|
}
|
|
37717
37761
|
return readFileSync4(this.contextPath, "utf-8");
|
|
37718
37762
|
}
|
|
37719
37763
|
readProgress() {
|
|
37720
|
-
if (!
|
|
37764
|
+
if (!existsSync5(this.progressPath)) {
|
|
37721
37765
|
return "";
|
|
37722
37766
|
}
|
|
37723
37767
|
return readFileSync4(this.progressPath, "utf-8");
|
|
@@ -37818,11 +37862,11 @@ No sprints started yet.
|
|
|
37818
37862
|
writeFileSync3(this.progressPath, progressContent);
|
|
37819
37863
|
}
|
|
37820
37864
|
get exists() {
|
|
37821
|
-
return
|
|
37865
|
+
return existsSync5(this.contextPath) || existsSync5(this.progressPath);
|
|
37822
37866
|
}
|
|
37823
37867
|
ensureDir(filePath) {
|
|
37824
37868
|
const dir = dirname2(filePath);
|
|
37825
|
-
if (!
|
|
37869
|
+
if (!existsSync5(dir)) {
|
|
37826
37870
|
mkdirSync3(dir, { recursive: true });
|
|
37827
37871
|
}
|
|
37828
37872
|
}
|
|
@@ -38056,8 +38100,8 @@ var init_reviewer_worker = __esm(() => {
|
|
|
38056
38100
|
});
|
|
38057
38101
|
|
|
38058
38102
|
// ../sdk/src/core/prompt-builder.ts
|
|
38059
|
-
import { existsSync as
|
|
38060
|
-
import { join as
|
|
38103
|
+
import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5, statSync } from "node:fs";
|
|
38104
|
+
import { join as join6 } from "node:path";
|
|
38061
38105
|
|
|
38062
38106
|
class PromptBuilder {
|
|
38063
38107
|
projectPath;
|
|
@@ -38099,7 +38143,7 @@ ${task2.description || "No description provided."}
|
|
|
38099
38143
|
}
|
|
38100
38144
|
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
38101
38145
|
let hasLocalContext = false;
|
|
38102
|
-
if (
|
|
38146
|
+
if (existsSync6(contextPath)) {
|
|
38103
38147
|
try {
|
|
38104
38148
|
const context = readFileSync5(contextPath, "utf-8");
|
|
38105
38149
|
if (context.trim().length > 20) {
|
|
@@ -38155,7 +38199,7 @@ ${serverContext.context}
|
|
|
38155
38199
|
|
|
38156
38200
|
`;
|
|
38157
38201
|
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
38158
|
-
if (
|
|
38202
|
+
if (existsSync6(indexPath)) {
|
|
38159
38203
|
prompt += `## Codebase Overview
|
|
38160
38204
|
There is an index file in the .locus/codebase-index.json and if you need you can check it.
|
|
38161
38205
|
|
|
@@ -38230,7 +38274,7 @@ ${query}
|
|
|
38230
38274
|
}
|
|
38231
38275
|
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
38232
38276
|
let hasLocalContext = false;
|
|
38233
|
-
if (
|
|
38277
|
+
if (existsSync6(contextPath)) {
|
|
38234
38278
|
try {
|
|
38235
38279
|
const context = readFileSync5(contextPath, "utf-8");
|
|
38236
38280
|
if (context.trim().length > 20) {
|
|
@@ -38266,7 +38310,7 @@ ${fallback}
|
|
|
38266
38310
|
|
|
38267
38311
|
`;
|
|
38268
38312
|
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
38269
|
-
if (
|
|
38313
|
+
if (existsSync6(indexPath)) {
|
|
38270
38314
|
prompt += `## Codebase Overview
|
|
38271
38315
|
There is an index file in the .locus/codebase-index.json and if you need you can check it.
|
|
38272
38316
|
|
|
@@ -38279,7 +38323,7 @@ There is an index file in the .locus/codebase-index.json and if you need you can
|
|
|
38279
38323
|
}
|
|
38280
38324
|
getProjectConfig() {
|
|
38281
38325
|
const configPath = getLocusPath(this.projectPath, "configFile");
|
|
38282
|
-
if (
|
|
38326
|
+
if (existsSync6(configPath)) {
|
|
38283
38327
|
try {
|
|
38284
38328
|
return JSON.parse(readFileSync5(configPath, "utf-8"));
|
|
38285
38329
|
} catch {
|
|
@@ -38289,8 +38333,8 @@ There is an index file in the .locus/codebase-index.json and if you need you can
|
|
|
38289
38333
|
return null;
|
|
38290
38334
|
}
|
|
38291
38335
|
getFallbackContext() {
|
|
38292
|
-
const readmePath =
|
|
38293
|
-
if (
|
|
38336
|
+
const readmePath = join6(this.projectPath, "README.md");
|
|
38337
|
+
if (existsSync6(readmePath)) {
|
|
38294
38338
|
try {
|
|
38295
38339
|
const content = readFileSync5(readmePath, "utf-8");
|
|
38296
38340
|
const limit = 1000;
|
|
@@ -38309,7 +38353,7 @@ There is an index file in the .locus/codebase-index.json and if you need you can
|
|
|
38309
38353
|
if (e.startsWith(".") || e === "node_modules")
|
|
38310
38354
|
return false;
|
|
38311
38355
|
try {
|
|
38312
|
-
return statSync(
|
|
38356
|
+
return statSync(join6(this.projectPath, e)).isDirectory();
|
|
38313
38357
|
} catch {
|
|
38314
38358
|
return false;
|
|
38315
38359
|
}
|
|
@@ -38394,8 +38438,8 @@ var init_worktree_config = __esm(() => {
|
|
|
38394
38438
|
|
|
38395
38439
|
// ../sdk/src/worktree/worktree-manager.ts
|
|
38396
38440
|
import { execFileSync as execFileSync3, execSync as execSync2 } from "node:child_process";
|
|
38397
|
-
import { existsSync as
|
|
38398
|
-
import { join as
|
|
38441
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, rmSync, statSync as statSync2 } from "node:fs";
|
|
38442
|
+
import { join as join7, resolve as resolve2, sep } from "node:path";
|
|
38399
38443
|
|
|
38400
38444
|
class WorktreeManager {
|
|
38401
38445
|
config;
|
|
@@ -38409,7 +38453,7 @@ class WorktreeManager {
|
|
|
38409
38453
|
});
|
|
38410
38454
|
}
|
|
38411
38455
|
get rootPath() {
|
|
38412
|
-
return
|
|
38456
|
+
return join7(this.projectPath, this.config.rootDir);
|
|
38413
38457
|
}
|
|
38414
38458
|
buildBranchName(taskId, taskSlug) {
|
|
38415
38459
|
const sanitized = taskSlug.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50);
|
|
@@ -38418,11 +38462,11 @@ class WorktreeManager {
|
|
|
38418
38462
|
create(options) {
|
|
38419
38463
|
const branch = this.buildBranchName(options.taskId, options.taskSlug);
|
|
38420
38464
|
const worktreeDir = `${options.agentId}-${options.taskId}`;
|
|
38421
|
-
const worktreePath =
|
|
38465
|
+
const worktreePath = join7(this.rootPath, worktreeDir);
|
|
38422
38466
|
this.ensureDirectory(this.rootPath, "Worktree root");
|
|
38423
38467
|
const baseBranch = options.baseBranch ?? this.config.baseBranch ?? this.getCurrentBranch();
|
|
38424
38468
|
this.log(`Creating worktree: ${worktreeDir} (branch: ${branch}, base: ${baseBranch})`, "info");
|
|
38425
|
-
if (
|
|
38469
|
+
if (existsSync7(worktreePath)) {
|
|
38426
38470
|
this.log(`Removing stale worktree directory: ${worktreePath}`, "warn");
|
|
38427
38471
|
try {
|
|
38428
38472
|
this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
|
|
@@ -38516,7 +38560,7 @@ class WorktreeManager {
|
|
|
38516
38560
|
try {
|
|
38517
38561
|
this.git(`worktree remove "${absolutePath}" --force`, this.projectPath);
|
|
38518
38562
|
} catch {
|
|
38519
|
-
if (
|
|
38563
|
+
if (existsSync7(absolutePath)) {
|
|
38520
38564
|
rmSync(absolutePath, { recursive: true, force: true });
|
|
38521
38565
|
}
|
|
38522
38566
|
this.git("worktree prune", this.projectPath);
|
|
@@ -38552,7 +38596,7 @@ class WorktreeManager {
|
|
|
38552
38596
|
this.log(`Failed to remove worktree: ${wt.path}`, "warn");
|
|
38553
38597
|
}
|
|
38554
38598
|
}
|
|
38555
|
-
if (
|
|
38599
|
+
if (existsSync7(this.rootPath)) {
|
|
38556
38600
|
try {
|
|
38557
38601
|
rmSync(this.rootPath, { recursive: true, force: true });
|
|
38558
38602
|
} catch {}
|
|
@@ -38618,7 +38662,7 @@ class WorktreeManager {
|
|
|
38618
38662
|
return candidate.startsWith(rootWithSep);
|
|
38619
38663
|
}
|
|
38620
38664
|
ensureDirectory(dirPath, label) {
|
|
38621
|
-
if (
|
|
38665
|
+
if (existsSync7(dirPath)) {
|
|
38622
38666
|
if (!statSync2(dirPath).isDirectory()) {
|
|
38623
38667
|
throw new Error(`${label} exists but is not a directory: ${dirPath}`);
|
|
38624
38668
|
}
|
|
@@ -38634,7 +38678,7 @@ class WorktreeManager {
|
|
|
38634
38678
|
try {
|
|
38635
38679
|
this.git(`worktree remove "${worktreePath}" --force`, this.projectPath);
|
|
38636
38680
|
} catch {}
|
|
38637
|
-
if (
|
|
38681
|
+
if (existsSync7(worktreePath)) {
|
|
38638
38682
|
rmSync(worktreePath, { recursive: true, force: true });
|
|
38639
38683
|
}
|
|
38640
38684
|
try {
|
|
@@ -39597,14 +39641,14 @@ var init_event_emitter = __esm(() => {
|
|
|
39597
39641
|
|
|
39598
39642
|
// ../sdk/src/exec/history-manager.ts
|
|
39599
39643
|
import {
|
|
39600
|
-
existsSync as
|
|
39644
|
+
existsSync as existsSync8,
|
|
39601
39645
|
mkdirSync as mkdirSync5,
|
|
39602
39646
|
readdirSync as readdirSync2,
|
|
39603
39647
|
readFileSync as readFileSync6,
|
|
39604
39648
|
rmSync as rmSync2,
|
|
39605
39649
|
writeFileSync as writeFileSync4
|
|
39606
39650
|
} from "node:fs";
|
|
39607
|
-
import { join as
|
|
39651
|
+
import { join as join8 } from "node:path";
|
|
39608
39652
|
function generateSessionId2() {
|
|
39609
39653
|
const timestamp = Date.now().toString(36);
|
|
39610
39654
|
const random = Math.random().toString(36).substring(2, 9);
|
|
@@ -39615,17 +39659,17 @@ class HistoryManager {
|
|
|
39615
39659
|
historyDir;
|
|
39616
39660
|
maxSessions;
|
|
39617
39661
|
constructor(projectPath, options) {
|
|
39618
|
-
this.historyDir = options?.historyDir ??
|
|
39662
|
+
this.historyDir = options?.historyDir ?? join8(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.sessionsDir);
|
|
39619
39663
|
this.maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;
|
|
39620
39664
|
this.ensureHistoryDir();
|
|
39621
39665
|
}
|
|
39622
39666
|
ensureHistoryDir() {
|
|
39623
|
-
if (!
|
|
39667
|
+
if (!existsSync8(this.historyDir)) {
|
|
39624
39668
|
mkdirSync5(this.historyDir, { recursive: true });
|
|
39625
39669
|
}
|
|
39626
39670
|
}
|
|
39627
39671
|
getSessionPath(sessionId) {
|
|
39628
|
-
return
|
|
39672
|
+
return join8(this.historyDir, `${sessionId}.json`);
|
|
39629
39673
|
}
|
|
39630
39674
|
saveSession(session) {
|
|
39631
39675
|
const filePath = this.getSessionPath(session.id);
|
|
@@ -39634,7 +39678,7 @@ class HistoryManager {
|
|
|
39634
39678
|
}
|
|
39635
39679
|
loadSession(sessionId) {
|
|
39636
39680
|
const filePath = this.getSessionPath(sessionId);
|
|
39637
|
-
if (!
|
|
39681
|
+
if (!existsSync8(filePath)) {
|
|
39638
39682
|
return null;
|
|
39639
39683
|
}
|
|
39640
39684
|
try {
|
|
@@ -39646,7 +39690,7 @@ class HistoryManager {
|
|
|
39646
39690
|
}
|
|
39647
39691
|
deleteSession(sessionId) {
|
|
39648
39692
|
const filePath = this.getSessionPath(sessionId);
|
|
39649
|
-
if (!
|
|
39693
|
+
if (!existsSync8(filePath)) {
|
|
39650
39694
|
return false;
|
|
39651
39695
|
}
|
|
39652
39696
|
try {
|
|
@@ -39734,7 +39778,7 @@ class HistoryManager {
|
|
|
39734
39778
|
return files.filter((f) => f.endsWith(".json")).length;
|
|
39735
39779
|
}
|
|
39736
39780
|
sessionExists(sessionId) {
|
|
39737
|
-
return
|
|
39781
|
+
return existsSync8(this.getSessionPath(sessionId));
|
|
39738
39782
|
}
|
|
39739
39783
|
findSessionByPartialId(partialId) {
|
|
39740
39784
|
const sessions = this.listSessions();
|
|
@@ -39753,7 +39797,7 @@ class HistoryManager {
|
|
|
39753
39797
|
for (const file2 of files) {
|
|
39754
39798
|
if (file2.endsWith(".json")) {
|
|
39755
39799
|
try {
|
|
39756
|
-
rmSync2(
|
|
39800
|
+
rmSync2(join8(this.historyDir, file2));
|
|
39757
39801
|
deleted++;
|
|
39758
39802
|
} catch {}
|
|
39759
39803
|
}
|
|
@@ -40042,8 +40086,8 @@ var init_git = __esm(() => {
|
|
|
40042
40086
|
|
|
40043
40087
|
// ../sdk/src/orchestrator.ts
|
|
40044
40088
|
import { spawn as spawn3 } from "node:child_process";
|
|
40045
|
-
import { existsSync as
|
|
40046
|
-
import { dirname as dirname3, join as
|
|
40089
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
40090
|
+
import { dirname as dirname3, join as join9 } from "node:path";
|
|
40047
40091
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
40048
40092
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
40049
40093
|
var MAX_AGENTS = 5, AgentOrchestrator;
|
|
@@ -40260,11 +40304,11 @@ ${agentId} finished (exit code: ${code})`);
|
|
|
40260
40304
|
const currentModulePath = fileURLToPath2(import.meta.url);
|
|
40261
40305
|
const currentModuleDir = dirname3(currentModulePath);
|
|
40262
40306
|
const potentialPaths = [
|
|
40263
|
-
|
|
40264
|
-
|
|
40265
|
-
|
|
40307
|
+
join9(currentModuleDir, "agent", "worker.js"),
|
|
40308
|
+
join9(currentModuleDir, "worker.js"),
|
|
40309
|
+
join9(currentModuleDir, "agent", "worker.ts")
|
|
40266
40310
|
];
|
|
40267
|
-
return potentialPaths.find((p) =>
|
|
40311
|
+
return potentialPaths.find((p) => existsSync9(p));
|
|
40268
40312
|
}
|
|
40269
40313
|
startHeartbeatMonitor() {
|
|
40270
40314
|
this.heartbeatInterval = setInterval(() => {
|
|
@@ -40554,14 +40598,14 @@ var init_sprint_plan = __esm(() => {
|
|
|
40554
40598
|
|
|
40555
40599
|
// ../sdk/src/planning/plan-manager.ts
|
|
40556
40600
|
import {
|
|
40557
|
-
existsSync as
|
|
40601
|
+
existsSync as existsSync10,
|
|
40558
40602
|
mkdirSync as mkdirSync6,
|
|
40559
40603
|
readdirSync as readdirSync3,
|
|
40560
40604
|
readFileSync as readFileSync7,
|
|
40561
40605
|
unlinkSync as unlinkSync2,
|
|
40562
40606
|
writeFileSync as writeFileSync5
|
|
40563
40607
|
} from "node:fs";
|
|
40564
|
-
import { join as
|
|
40608
|
+
import { join as join10 } from "node:path";
|
|
40565
40609
|
|
|
40566
40610
|
class PlanManager {
|
|
40567
40611
|
projectPath;
|
|
@@ -40573,8 +40617,8 @@ class PlanManager {
|
|
|
40573
40617
|
save(plan) {
|
|
40574
40618
|
this.ensurePlansDir();
|
|
40575
40619
|
const slug = this.slugify(plan.name);
|
|
40576
|
-
const jsonPath =
|
|
40577
|
-
const mdPath =
|
|
40620
|
+
const jsonPath = join10(this.plansDir, `${slug}.json`);
|
|
40621
|
+
const mdPath = join10(this.plansDir, `sprint-${slug}.md`);
|
|
40578
40622
|
writeFileSync5(jsonPath, JSON.stringify(plan, null, 2), "utf-8");
|
|
40579
40623
|
writeFileSync5(mdPath, sprintPlanToMarkdown(plan), "utf-8");
|
|
40580
40624
|
return plan.id;
|
|
@@ -40583,7 +40627,7 @@ class PlanManager {
|
|
|
40583
40627
|
this.ensurePlansDir();
|
|
40584
40628
|
const files = readdirSync3(this.plansDir).filter((f) => f.endsWith(".json"));
|
|
40585
40629
|
for (const file2 of files) {
|
|
40586
|
-
const filePath =
|
|
40630
|
+
const filePath = join10(this.plansDir, file2);
|
|
40587
40631
|
try {
|
|
40588
40632
|
const plan = JSON.parse(readFileSync7(filePath, "utf-8"));
|
|
40589
40633
|
if (plan.id === idOrSlug || this.slugify(plan.name) === idOrSlug) {
|
|
@@ -40599,7 +40643,7 @@ class PlanManager {
|
|
|
40599
40643
|
const plans = [];
|
|
40600
40644
|
for (const file2 of files) {
|
|
40601
40645
|
try {
|
|
40602
|
-
const plan = JSON.parse(readFileSync7(
|
|
40646
|
+
const plan = JSON.parse(readFileSync7(join10(this.plansDir, file2), "utf-8"));
|
|
40603
40647
|
if (!status || plan.status === status) {
|
|
40604
40648
|
plans.push(plan);
|
|
40605
40649
|
}
|
|
@@ -40664,15 +40708,15 @@ class PlanManager {
|
|
|
40664
40708
|
this.ensurePlansDir();
|
|
40665
40709
|
const files = readdirSync3(this.plansDir);
|
|
40666
40710
|
for (const file2 of files) {
|
|
40667
|
-
const filePath =
|
|
40711
|
+
const filePath = join10(this.plansDir, file2);
|
|
40668
40712
|
if (!file2.endsWith(".json"))
|
|
40669
40713
|
continue;
|
|
40670
40714
|
try {
|
|
40671
40715
|
const plan = JSON.parse(readFileSync7(filePath, "utf-8"));
|
|
40672
40716
|
if (plan.id === idOrSlug || this.slugify(plan.name) === idOrSlug) {
|
|
40673
40717
|
unlinkSync2(filePath);
|
|
40674
|
-
const mdPath =
|
|
40675
|
-
if (
|
|
40718
|
+
const mdPath = join10(this.plansDir, `sprint-${this.slugify(plan.name)}.md`);
|
|
40719
|
+
if (existsSync10(mdPath)) {
|
|
40676
40720
|
unlinkSync2(mdPath);
|
|
40677
40721
|
}
|
|
40678
40722
|
return;
|
|
@@ -40687,7 +40731,7 @@ class PlanManager {
|
|
|
40687
40731
|
return sprintPlanToMarkdown(plan);
|
|
40688
40732
|
}
|
|
40689
40733
|
ensurePlansDir() {
|
|
40690
|
-
if (!
|
|
40734
|
+
if (!existsSync10(this.plansDir)) {
|
|
40691
40735
|
mkdirSync6(this.plansDir, { recursive: true });
|
|
40692
40736
|
}
|
|
40693
40737
|
}
|
|
@@ -40894,7 +40938,7 @@ Respond with ONLY a JSON object (no markdown code blocks, no explanation):
|
|
|
40894
40938
|
}
|
|
40895
40939
|
|
|
40896
40940
|
// ../sdk/src/planning/planning-meeting.ts
|
|
40897
|
-
import { existsSync as
|
|
40941
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
|
|
40898
40942
|
|
|
40899
40943
|
class PlanningMeeting {
|
|
40900
40944
|
projectPath;
|
|
@@ -40955,7 +40999,7 @@ class PlanningMeeting {
|
|
|
40955
40999
|
}
|
|
40956
41000
|
getCodebaseIndex() {
|
|
40957
41001
|
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
40958
|
-
if (!
|
|
41002
|
+
if (!existsSync11(indexPath)) {
|
|
40959
41003
|
return "";
|
|
40960
41004
|
}
|
|
40961
41005
|
try {
|
|
@@ -42068,22 +42112,22 @@ import { parseArgs } from "node:util";
|
|
|
42068
42112
|
init_index_node();
|
|
42069
42113
|
|
|
42070
42114
|
// src/utils/version.ts
|
|
42071
|
-
import { existsSync as
|
|
42072
|
-
import { dirname as dirname4, join as
|
|
42115
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
|
|
42116
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
42073
42117
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
42074
42118
|
function getVersion() {
|
|
42075
42119
|
try {
|
|
42076
42120
|
const __filename2 = fileURLToPath3(import.meta.url);
|
|
42077
42121
|
const __dirname2 = dirname4(__filename2);
|
|
42078
|
-
const bundledPath =
|
|
42079
|
-
const sourcePath =
|
|
42080
|
-
if (
|
|
42122
|
+
const bundledPath = join11(__dirname2, "..", "package.json");
|
|
42123
|
+
const sourcePath = join11(__dirname2, "..", "..", "package.json");
|
|
42124
|
+
if (existsSync12(bundledPath)) {
|
|
42081
42125
|
const pkg = JSON.parse(readFileSync9(bundledPath, "utf-8"));
|
|
42082
42126
|
if (pkg.name === "@locusai/cli") {
|
|
42083
42127
|
return pkg.version || "0.0.0";
|
|
42084
42128
|
}
|
|
42085
42129
|
}
|
|
42086
|
-
if (
|
|
42130
|
+
if (existsSync12(sourcePath)) {
|
|
42087
42131
|
const pkg = JSON.parse(readFileSync9(sourcePath, "utf-8"));
|
|
42088
42132
|
if (pkg.name === "@locusai/cli") {
|
|
42089
42133
|
return pkg.version || "0.0.0";
|
|
@@ -42106,12 +42150,12 @@ function printBanner() {
|
|
|
42106
42150
|
}
|
|
42107
42151
|
// src/utils/helpers.ts
|
|
42108
42152
|
init_index_node();
|
|
42109
|
-
import { existsSync as
|
|
42110
|
-
import { join as
|
|
42153
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
42154
|
+
import { join as join12 } from "node:path";
|
|
42111
42155
|
function isProjectInitialized(projectPath) {
|
|
42112
|
-
const locusDir =
|
|
42113
|
-
const configPath =
|
|
42114
|
-
return
|
|
42156
|
+
const locusDir = join12(projectPath, LOCUS_CONFIG.dir);
|
|
42157
|
+
const configPath = join12(locusDir, LOCUS_CONFIG.configFile);
|
|
42158
|
+
return existsSync13(locusDir) && existsSync13(configPath);
|
|
42115
42159
|
}
|
|
42116
42160
|
function requireInitialization(projectPath, command) {
|
|
42117
42161
|
if (!isProjectInitialized(projectPath)) {
|
|
@@ -42248,10 +42292,10 @@ import { createInterface } from "node:readline";
|
|
|
42248
42292
|
|
|
42249
42293
|
// src/settings-manager.ts
|
|
42250
42294
|
init_index_node();
|
|
42251
|
-
import { existsSync as
|
|
42252
|
-
import { join as
|
|
42295
|
+
import { existsSync as existsSync14, readFileSync as readFileSync10, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
42296
|
+
import { join as join13 } from "node:path";
|
|
42253
42297
|
function getSettingsPath(projectPath) {
|
|
42254
|
-
return
|
|
42298
|
+
return join13(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.settingsFile);
|
|
42255
42299
|
}
|
|
42256
42300
|
|
|
42257
42301
|
class SettingsManager {
|
|
@@ -42261,7 +42305,7 @@ class SettingsManager {
|
|
|
42261
42305
|
}
|
|
42262
42306
|
load() {
|
|
42263
42307
|
const settingsPath = getSettingsPath(this.projectPath);
|
|
42264
|
-
if (!
|
|
42308
|
+
if (!existsSync14(settingsPath)) {
|
|
42265
42309
|
return {};
|
|
42266
42310
|
}
|
|
42267
42311
|
return JSON.parse(readFileSync10(settingsPath, "utf-8"));
|
|
@@ -42282,12 +42326,12 @@ class SettingsManager {
|
|
|
42282
42326
|
}
|
|
42283
42327
|
remove() {
|
|
42284
42328
|
const settingsPath = getSettingsPath(this.projectPath);
|
|
42285
|
-
if (
|
|
42329
|
+
if (existsSync14(settingsPath)) {
|
|
42286
42330
|
unlinkSync3(settingsPath);
|
|
42287
42331
|
}
|
|
42288
42332
|
}
|
|
42289
42333
|
exists() {
|
|
42290
|
-
return
|
|
42334
|
+
return existsSync14(getSettingsPath(this.projectPath));
|
|
42291
42335
|
}
|
|
42292
42336
|
}
|
|
42293
42337
|
|
|
@@ -42555,8 +42599,8 @@ import { parseArgs as parseArgs2 } from "node:util";
|
|
|
42555
42599
|
|
|
42556
42600
|
// src/config-manager.ts
|
|
42557
42601
|
init_index_node();
|
|
42558
|
-
import { existsSync as
|
|
42559
|
-
import { join as
|
|
42602
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "node:fs";
|
|
42603
|
+
import { join as join14 } from "node:path";
|
|
42560
42604
|
var LOCUS_GITIGNORE_MARKER = "# Locus AI";
|
|
42561
42605
|
var DEFAULT_CONTEXT_MD = `# Project
|
|
42562
42606
|
|
|
@@ -42600,11 +42644,11 @@ Complex tasks must be planned before writing code. Create \`.locus/plans/<task-n
|
|
|
42600
42644
|
- Read before writing Before modifying a file, read the relevant existing code to match conventions, understand context, and avoid duplicating logic that already exists.
|
|
42601
42645
|
`;
|
|
42602
42646
|
function updateGitignore(projectPath) {
|
|
42603
|
-
const gitignorePath =
|
|
42647
|
+
const gitignorePath = join14(projectPath, ".gitignore");
|
|
42604
42648
|
let content = "";
|
|
42605
42649
|
const locusBlock = LOCUS_GITIGNORE_PATTERNS.join(`
|
|
42606
42650
|
`);
|
|
42607
|
-
if (
|
|
42651
|
+
if (existsSync15(gitignorePath)) {
|
|
42608
42652
|
content = readFileSync11(gitignorePath, "utf-8");
|
|
42609
42653
|
if (content.includes(LOCUS_GITIGNORE_MARKER)) {
|
|
42610
42654
|
const lines = content.split(`
|
|
@@ -42646,9 +42690,9 @@ class ConfigManager {
|
|
|
42646
42690
|
this.projectPath = projectPath;
|
|
42647
42691
|
}
|
|
42648
42692
|
async init(version2) {
|
|
42649
|
-
const locusConfigDir =
|
|
42693
|
+
const locusConfigDir = join14(this.projectPath, LOCUS_CONFIG.dir);
|
|
42650
42694
|
const locusConfigPath = getLocusPath(this.projectPath, "configFile");
|
|
42651
|
-
if (!
|
|
42695
|
+
if (!existsSync15(locusConfigDir)) {
|
|
42652
42696
|
mkdirSync7(locusConfigDir, { recursive: true });
|
|
42653
42697
|
}
|
|
42654
42698
|
const locusSubdirs = [
|
|
@@ -42660,24 +42704,24 @@ class ConfigManager {
|
|
|
42660
42704
|
LOCUS_CONFIG.projectDir
|
|
42661
42705
|
];
|
|
42662
42706
|
for (const subdir of locusSubdirs) {
|
|
42663
|
-
const subdirPath =
|
|
42664
|
-
if (!
|
|
42707
|
+
const subdirPath = join14(locusConfigDir, subdir);
|
|
42708
|
+
if (!existsSync15(subdirPath)) {
|
|
42665
42709
|
mkdirSync7(subdirPath, { recursive: true });
|
|
42666
42710
|
}
|
|
42667
42711
|
}
|
|
42668
42712
|
const contextFilePath = getLocusPath(this.projectPath, "projectContextFile");
|
|
42669
|
-
if (!
|
|
42713
|
+
if (!existsSync15(contextFilePath)) {
|
|
42670
42714
|
writeFileSync7(contextFilePath, DEFAULT_CONTEXT_MD);
|
|
42671
42715
|
}
|
|
42672
42716
|
const progressFilePath = getLocusPath(this.projectPath, "projectProgressFile");
|
|
42673
|
-
if (!
|
|
42717
|
+
if (!existsSync15(progressFilePath)) {
|
|
42674
42718
|
writeFileSync7(progressFilePath, DEFAULT_PROGRESS_MD);
|
|
42675
42719
|
}
|
|
42676
42720
|
const locusMdPath = getLocusPath(this.projectPath, "contextFile");
|
|
42677
|
-
if (!
|
|
42721
|
+
if (!existsSync15(locusMdPath)) {
|
|
42678
42722
|
writeFileSync7(locusMdPath, LOCUS_MD_TEMPLATE);
|
|
42679
42723
|
}
|
|
42680
|
-
if (!
|
|
42724
|
+
if (!existsSync15(locusConfigPath)) {
|
|
42681
42725
|
const config2 = {
|
|
42682
42726
|
$schema: LOCUS_SCHEMAS.config,
|
|
42683
42727
|
version: version2,
|
|
@@ -42690,7 +42734,7 @@ class ConfigManager {
|
|
|
42690
42734
|
}
|
|
42691
42735
|
loadConfig() {
|
|
42692
42736
|
const path2 = getLocusPath(this.projectPath, "configFile");
|
|
42693
|
-
if (
|
|
42737
|
+
if (existsSync15(path2)) {
|
|
42694
42738
|
return JSON.parse(readFileSync11(path2, "utf-8"));
|
|
42695
42739
|
}
|
|
42696
42740
|
return null;
|
|
@@ -42709,7 +42753,7 @@ class ConfigManager {
|
|
|
42709
42753
|
directoriesCreated: [],
|
|
42710
42754
|
gitignoreUpdated: false
|
|
42711
42755
|
};
|
|
42712
|
-
const locusConfigDir =
|
|
42756
|
+
const locusConfigDir = join14(this.projectPath, LOCUS_CONFIG.dir);
|
|
42713
42757
|
const locusMdPath = getLocusPath(this.projectPath, "contextFile");
|
|
42714
42758
|
const config2 = this.loadConfig();
|
|
42715
42759
|
if (config2) {
|
|
@@ -42723,8 +42767,8 @@ class ConfigManager {
|
|
|
42723
42767
|
this.saveConfig(config2);
|
|
42724
42768
|
}
|
|
42725
42769
|
}
|
|
42726
|
-
const settingsPath =
|
|
42727
|
-
if (
|
|
42770
|
+
const settingsPath = join14(this.projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.settingsFile);
|
|
42771
|
+
if (existsSync15(settingsPath)) {
|
|
42728
42772
|
const raw = readFileSync11(settingsPath, "utf-8");
|
|
42729
42773
|
const settings = JSON.parse(raw);
|
|
42730
42774
|
if (settings.$schema !== LOCUS_SCHEMAS.settings) {
|
|
@@ -42733,7 +42777,7 @@ class ConfigManager {
|
|
|
42733
42777
|
writeFileSync7(settingsPath, JSON.stringify(ordered, null, 2), "utf-8");
|
|
42734
42778
|
}
|
|
42735
42779
|
}
|
|
42736
|
-
if (!
|
|
42780
|
+
if (!existsSync15(locusMdPath)) {
|
|
42737
42781
|
writeFileSync7(locusMdPath, LOCUS_MD_TEMPLATE);
|
|
42738
42782
|
result.directoriesCreated.push(".locus/LOCUS.md");
|
|
42739
42783
|
}
|
|
@@ -42746,24 +42790,24 @@ class ConfigManager {
|
|
|
42746
42790
|
LOCUS_CONFIG.projectDir
|
|
42747
42791
|
];
|
|
42748
42792
|
for (const subdir of locusSubdirs) {
|
|
42749
|
-
const subdirPath =
|
|
42750
|
-
if (!
|
|
42793
|
+
const subdirPath = join14(locusConfigDir, subdir);
|
|
42794
|
+
if (!existsSync15(subdirPath)) {
|
|
42751
42795
|
mkdirSync7(subdirPath, { recursive: true });
|
|
42752
42796
|
result.directoriesCreated.push(`.locus/${subdir}`);
|
|
42753
42797
|
}
|
|
42754
42798
|
}
|
|
42755
42799
|
const contextFilePath = getLocusPath(this.projectPath, "projectContextFile");
|
|
42756
|
-
if (!
|
|
42800
|
+
if (!existsSync15(contextFilePath)) {
|
|
42757
42801
|
writeFileSync7(contextFilePath, DEFAULT_CONTEXT_MD);
|
|
42758
42802
|
result.directoriesCreated.push(".locus/project/context.md");
|
|
42759
42803
|
}
|
|
42760
42804
|
const progressFilePath = getLocusPath(this.projectPath, "projectProgressFile");
|
|
42761
|
-
if (!
|
|
42805
|
+
if (!existsSync15(progressFilePath)) {
|
|
42762
42806
|
writeFileSync7(progressFilePath, DEFAULT_PROGRESS_MD);
|
|
42763
42807
|
result.directoriesCreated.push(".locus/project/progress.md");
|
|
42764
42808
|
}
|
|
42765
|
-
const gitignorePath =
|
|
42766
|
-
const gitignoreBefore =
|
|
42809
|
+
const gitignorePath = join14(this.projectPath, ".gitignore");
|
|
42810
|
+
const gitignoreBefore = existsSync15(gitignorePath) ? readFileSync11(gitignorePath, "utf-8") : "";
|
|
42767
42811
|
updateGitignore(this.projectPath);
|
|
42768
42812
|
const gitignoreAfter = readFileSync11(gitignorePath, "utf-8");
|
|
42769
42813
|
if (gitignoreBefore !== gitignoreAfter) {
|
|
@@ -43744,8 +43788,8 @@ function showPlanHelp() {
|
|
|
43744
43788
|
}
|
|
43745
43789
|
// src/commands/review.ts
|
|
43746
43790
|
init_index_node();
|
|
43747
|
-
import { existsSync as
|
|
43748
|
-
import { join as
|
|
43791
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "node:fs";
|
|
43792
|
+
import { join as join15 } from "node:path";
|
|
43749
43793
|
import { parseArgs as parseArgs6 } from "node:util";
|
|
43750
43794
|
async function reviewCommand(args) {
|
|
43751
43795
|
const subcommand = args[0];
|
|
@@ -43884,12 +43928,12 @@ async function reviewLocalCommand(args) {
|
|
|
43884
43928
|
`);
|
|
43885
43929
|
return;
|
|
43886
43930
|
}
|
|
43887
|
-
const reviewsDir =
|
|
43888
|
-
if (!
|
|
43931
|
+
const reviewsDir = join15(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.reviewsDir);
|
|
43932
|
+
if (!existsSync16(reviewsDir)) {
|
|
43889
43933
|
mkdirSync8(reviewsDir, { recursive: true });
|
|
43890
43934
|
}
|
|
43891
43935
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
43892
|
-
const reportPath =
|
|
43936
|
+
const reportPath = join15(reviewsDir, `review-${timestamp}.md`);
|
|
43893
43937
|
writeFileSync8(reportPath, report, "utf-8");
|
|
43894
43938
|
console.log(`
|
|
43895
43939
|
${c.success("✔")} ${c.success("Review complete!")}`);
|
|
@@ -43994,8 +44038,8 @@ ${c.info(`Received ${signal}. Stopping agents and cleaning up worktrees...`)}`);
|
|
|
43994
44038
|
// src/commands/telegram.ts
|
|
43995
44039
|
init_index_node();
|
|
43996
44040
|
import { spawn as spawn4 } from "node:child_process";
|
|
43997
|
-
import { existsSync as
|
|
43998
|
-
import { join as
|
|
44041
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
44042
|
+
import { join as join16 } from "node:path";
|
|
43999
44043
|
import { createInterface as createInterface3 } from "node:readline";
|
|
44000
44044
|
function ask2(question) {
|
|
44001
44045
|
const rl = createInterface3({
|
|
@@ -44231,8 +44275,8 @@ function runBotCommand(projectPath) {
|
|
|
44231
44275
|
`);
|
|
44232
44276
|
process.exit(1);
|
|
44233
44277
|
}
|
|
44234
|
-
const monorepoTelegramEntry =
|
|
44235
|
-
const isMonorepo =
|
|
44278
|
+
const monorepoTelegramEntry = join16(projectPath, "packages/telegram/src/index.ts");
|
|
44279
|
+
const isMonorepo = existsSync17(monorepoTelegramEntry);
|
|
44236
44280
|
let cmd;
|
|
44237
44281
|
let args;
|
|
44238
44282
|
if (isMonorepo) {
|
|
@@ -44351,24 +44395,13 @@ async function upgradeCommand() {
|
|
|
44351
44395
|
// src/commands/version.ts
|
|
44352
44396
|
init_index_node();
|
|
44353
44397
|
import { execSync as execSync4 } from "node:child_process";
|
|
44354
|
-
import { existsSync as existsSync17, readFileSync as readFileSync12 } from "node:fs";
|
|
44355
|
-
import { join as join16 } from "node:path";
|
|
44356
44398
|
function getTelegramVersion() {
|
|
44357
|
-
const monorepoPath = join16(process.cwd(), "packages/telegram/package.json");
|
|
44358
|
-
if (existsSync17(monorepoPath)) {
|
|
44359
|
-
try {
|
|
44360
|
-
const pkg = JSON.parse(readFileSync12(monorepoPath, "utf-8"));
|
|
44361
|
-
if (pkg.name === "@locusai/telegram") {
|
|
44362
|
-
return pkg.version || null;
|
|
44363
|
-
}
|
|
44364
|
-
} catch {}
|
|
44365
|
-
}
|
|
44366
44399
|
try {
|
|
44367
|
-
const
|
|
44400
|
+
const output = execSync4("npm list -g @locusai/telegram --depth=0 --json", {
|
|
44368
44401
|
encoding: "utf-8",
|
|
44369
44402
|
stdio: ["pipe", "pipe", "pipe"]
|
|
44370
44403
|
});
|
|
44371
|
-
const parsed = JSON.parse(
|
|
44404
|
+
const parsed = JSON.parse(output);
|
|
44372
44405
|
return parsed.dependencies?.["@locusai/telegram"]?.version || null;
|
|
44373
44406
|
} catch {}
|
|
44374
44407
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@locusai/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "CLI for Locus - AI-native project management platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"author": "",
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@locusai/sdk": "^0.9.
|
|
35
|
+
"@locusai/sdk": "^0.9.5"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {}
|
|
38
38
|
}
|