@locusai/sdk 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/codebase-indexer-service.d.ts.map +1 -1
- package/dist/agent/reviewer-worker.d.ts +0 -1
- package/dist/agent/reviewer-worker.d.ts.map +1 -1
- package/dist/agent/worker.d.ts +0 -2
- package/dist/agent/worker.d.ts.map +1 -1
- package/dist/agent/worker.js +135 -331
- package/dist/ai/claude-runner.d.ts +1 -0
- package/dist/ai/claude-runner.d.ts.map +1 -1
- package/dist/ai/codex-runner.d.ts +1 -1
- package/dist/ai/codex-runner.d.ts.map +1 -1
- package/dist/ai/factory.d.ts +2 -0
- package/dist/ai/factory.d.ts.map +1 -1
- package/dist/core/config.d.ts +2 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/prompt-builder.d.ts +4 -5
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/index-node.d.ts +1 -1
- package/dist/index-node.d.ts.map +1 -1
- package/dist/index-node.js +396 -721
- package/dist/planning/agents/cross-task-reviewer.d.ts +0 -14
- package/dist/planning/agents/cross-task-reviewer.d.ts.map +1 -1
- package/dist/planning/agents/planner.d.ts +11 -5
- package/dist/planning/agents/planner.d.ts.map +1 -1
- package/dist/planning/index.d.ts +1 -1
- package/dist/planning/index.d.ts.map +1 -1
- package/dist/planning/plan-manager.d.ts +0 -1
- package/dist/planning/plan-manager.d.ts.map +1 -1
- package/dist/planning/planning-meeting.d.ts +11 -12
- package/dist/planning/planning-meeting.d.ts.map +1 -1
- package/dist/planning/sprint-plan.d.ts +7 -3
- package/dist/planning/sprint-plan.d.ts.map +1 -1
- package/dist/utils/json-extractor.d.ts +6 -2
- package/dist/utils/json-extractor.d.ts.map +1 -1
- package/dist/utils/structured-output.d.ts +14 -0
- package/dist/utils/structured-output.d.ts.map +1 -0
- package/package.json +5 -4
- package/dist/project/knowledge-base.d.ts +0 -24
- package/dist/project/knowledge-base.d.ts.map +0 -1
- package/dist/worktree/index.d.ts +0 -2
- package/dist/worktree/index.d.ts.map +0 -1
- package/dist/worktree/worktree-config.d.ts +0 -2
- package/dist/worktree/worktree-config.d.ts.map +0 -1
- package/dist/worktree/worktree-manager.d.ts +0 -2
- package/dist/worktree/worktree-manager.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codebase-indexer-service.d.ts","sourceRoot":"","sources":["../../src/agent/codebase-indexer-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,KAAK,CAAC;CACZ;AAED;;GAEG;AACH,qBAAa,sBAAsB;IAGrB,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAkB;gBAEb,IAAI,EAAE,0BAA0B;IAI9C,OAAO,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"codebase-indexer-service.d.ts","sourceRoot":"","sources":["../../src/agent/codebase-indexer-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,KAAK,CAAC;CACZ;AAED;;GAEG;AACH,qBAAa,sBAAsB;IAGrB,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAkB;gBAEb,IAAI,EAAE,0BAA0B;IAI9C,OAAO,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAmD5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviewer-worker.d.ts","sourceRoot":"","sources":["../../src/agent/reviewer-worker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"reviewer-worker.d.ts","sourceRoot":"","sources":["../../src/agent/reviewer-worker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,iBAAiB,CAAC;AAa5D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IASb,OAAO,CAAC,MAAM;IAR1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,gBAAgB,CAAK;gBAET,MAAM,EAAE,cAAc;IA4B1C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAgB;IAe1E;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;YACW,QAAQ;IAiFtB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAgBf,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiE3B"}
|
package/dist/agent/worker.d.ts
CHANGED
|
@@ -16,7 +16,6 @@ export declare class AgentWorker {
|
|
|
16
16
|
private client;
|
|
17
17
|
private aiRunner;
|
|
18
18
|
private taskExecutor;
|
|
19
|
-
private knowledgeBase;
|
|
20
19
|
private gitWorkflow;
|
|
21
20
|
private maxTasks;
|
|
22
21
|
private tasksCompleted;
|
|
@@ -32,7 +31,6 @@ export declare class AgentWorker {
|
|
|
32
31
|
* Execute a single task in the current branch.
|
|
33
32
|
*/
|
|
34
33
|
private executeTask;
|
|
35
|
-
private updateProgress;
|
|
36
34
|
private startHeartbeat;
|
|
37
35
|
private stopHeartbeat;
|
|
38
36
|
private sendHeartbeat;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/agent/worker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/agent/worker.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAgBV,OAAO,CAAC,MAAM;IAf1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAc;IAGjC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,aAAa,CAAuB;IAG5C,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,aAAa,CAAgB;gBAEjB,MAAM,EAAE,YAAY;IAqDxC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAgB;YAmB5D,eAAe;YAcf,WAAW;IAgDzB;;OAEG;YACW,WAAW;IAoCzB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAoBf,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA8I3B"}
|
package/dist/agent/worker.js
CHANGED
|
@@ -522,9 +522,6 @@ var init_src = __esm(() => {
|
|
|
522
522
|
|
|
523
523
|
// src/core/config.ts
|
|
524
524
|
function getLocusPath(projectPath, fileName) {
|
|
525
|
-
if (fileName === "projectContextFile" || fileName === "projectProgressFile") {
|
|
526
|
-
return import_node_path.join(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.projectDir, LOCUS_CONFIG[fileName]);
|
|
527
|
-
}
|
|
528
525
|
return import_node_path.join(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG[fileName]);
|
|
529
526
|
}
|
|
530
527
|
function getAgentArtifactsPath(projectPath, agentId) {
|
|
@@ -552,14 +549,12 @@ var init_config = __esm(() => {
|
|
|
552
549
|
settingsFile: "settings.json",
|
|
553
550
|
indexFile: "codebase-index.json",
|
|
554
551
|
contextFile: "LOCUS.md",
|
|
552
|
+
learningsFile: "LEARNINGS.md",
|
|
555
553
|
artifactsDir: "artifacts",
|
|
556
554
|
documentsDir: "documents",
|
|
557
555
|
sessionsDir: "sessions",
|
|
558
556
|
reviewsDir: "reviews",
|
|
559
|
-
plansDir: "plans"
|
|
560
|
-
projectDir: "project",
|
|
561
|
-
projectContextFile: "context.md",
|
|
562
|
-
projectProgressFile: "progress.md"
|
|
557
|
+
plansDir: "plans"
|
|
563
558
|
};
|
|
564
559
|
LOCUS_GITIGNORE_PATTERNS = [
|
|
565
560
|
"# Locus AI - Session data (user-specific, can grow large)",
|
|
@@ -577,11 +572,8 @@ var init_config = __esm(() => {
|
|
|
577
572
|
"# Locus AI - Settings (contains API key, telegram config, etc.)",
|
|
578
573
|
".locus/settings.json",
|
|
579
574
|
"",
|
|
580
|
-
"# Locus AI - Configuration (contains project context,
|
|
581
|
-
".locus/config.json"
|
|
582
|
-
"",
|
|
583
|
-
"# Locus AI - Project progress (contains project progress, etc.)",
|
|
584
|
-
".locus/project/progress.md"
|
|
575
|
+
"# Locus AI - Configuration (contains project context, etc.)",
|
|
576
|
+
".locus/config.json"
|
|
585
577
|
];
|
|
586
578
|
});
|
|
587
579
|
|
|
@@ -820,17 +812,22 @@ class ClaudeRunner {
|
|
|
820
812
|
});
|
|
821
813
|
});
|
|
822
814
|
}
|
|
823
|
-
|
|
815
|
+
buildCliArgs() {
|
|
824
816
|
const args = [
|
|
825
|
-
"--dangerously-skip-permissions",
|
|
826
817
|
"--print",
|
|
827
|
-
"--verbose",
|
|
828
818
|
"--output-format",
|
|
829
819
|
"stream-json",
|
|
820
|
+
"--verbose",
|
|
821
|
+
"--dangerously-skip-permissions",
|
|
822
|
+
"--no-session-persistence",
|
|
830
823
|
"--include-partial-messages",
|
|
831
824
|
"--model",
|
|
832
825
|
this.model
|
|
833
826
|
];
|
|
827
|
+
return args;
|
|
828
|
+
}
|
|
829
|
+
async* runStream(prompt) {
|
|
830
|
+
const args = this.buildCliArgs();
|
|
834
831
|
const env = getAugmentedEnv({
|
|
835
832
|
FORCE_COLOR: "1",
|
|
836
833
|
TERM: "xterm-256color"
|
|
@@ -1070,16 +1067,7 @@ class ClaudeRunner {
|
|
|
1070
1067
|
}
|
|
1071
1068
|
executeRun(prompt) {
|
|
1072
1069
|
return new Promise((resolve2, reject) => {
|
|
1073
|
-
const args =
|
|
1074
|
-
"--dangerously-skip-permissions",
|
|
1075
|
-
"--print",
|
|
1076
|
-
"--verbose",
|
|
1077
|
-
"--output-format",
|
|
1078
|
-
"stream-json",
|
|
1079
|
-
"--include-partial-messages",
|
|
1080
|
-
"--model",
|
|
1081
|
-
this.model
|
|
1082
|
-
];
|
|
1070
|
+
const args = this.buildCliArgs();
|
|
1083
1071
|
const env = getAugmentedEnv({
|
|
1084
1072
|
FORCE_COLOR: "1",
|
|
1085
1073
|
TERM: "xterm-256color"
|
|
@@ -1200,7 +1188,7 @@ class CodexRunner {
|
|
|
1200
1188
|
eventEmitter;
|
|
1201
1189
|
currentToolName;
|
|
1202
1190
|
timeoutMs;
|
|
1203
|
-
constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CODEX], log,
|
|
1191
|
+
constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CODEX], log, reasoningEffort, timeoutMs) {
|
|
1204
1192
|
this.projectPath = projectPath;
|
|
1205
1193
|
this.model = model;
|
|
1206
1194
|
this.log = log;
|
|
@@ -1531,7 +1519,7 @@ function createAiRunner(provider, config) {
|
|
|
1531
1519
|
const model = config.model ?? DEFAULT_MODEL[resolvedProvider];
|
|
1532
1520
|
switch (resolvedProvider) {
|
|
1533
1521
|
case PROVIDER.CODEX:
|
|
1534
|
-
return new CodexRunner(config.projectPath, model, config.log, config.
|
|
1522
|
+
return new CodexRunner(config.projectPath, model, config.log, config.reasoningEffort ?? "high", config.timeoutMs);
|
|
1535
1523
|
default:
|
|
1536
1524
|
return new ClaudeRunner(config.projectPath, model, config.log, config.timeoutMs);
|
|
1537
1525
|
}
|
|
@@ -1638,102 +1626,6 @@ var init_git_utils = __esm(() => {
|
|
|
1638
1626
|
import_node_child_process3 = require("node:child_process");
|
|
1639
1627
|
});
|
|
1640
1628
|
|
|
1641
|
-
// src/project/knowledge-base.ts
|
|
1642
|
-
class KnowledgeBase {
|
|
1643
|
-
contextPath;
|
|
1644
|
-
progressPath;
|
|
1645
|
-
constructor(projectPath) {
|
|
1646
|
-
this.contextPath = getLocusPath(projectPath, "projectContextFile");
|
|
1647
|
-
this.progressPath = getLocusPath(projectPath, "projectProgressFile");
|
|
1648
|
-
}
|
|
1649
|
-
readContext() {
|
|
1650
|
-
if (!import_node_fs3.existsSync(this.contextPath)) {
|
|
1651
|
-
return "";
|
|
1652
|
-
}
|
|
1653
|
-
return import_node_fs3.readFileSync(this.contextPath, "utf-8");
|
|
1654
|
-
}
|
|
1655
|
-
readProgress() {
|
|
1656
|
-
if (!import_node_fs3.existsSync(this.progressPath)) {
|
|
1657
|
-
return "";
|
|
1658
|
-
}
|
|
1659
|
-
return import_node_fs3.readFileSync(this.progressPath, "utf-8");
|
|
1660
|
-
}
|
|
1661
|
-
updateContext(content) {
|
|
1662
|
-
this.ensureDir(this.contextPath);
|
|
1663
|
-
import_node_fs3.writeFileSync(this.contextPath, content);
|
|
1664
|
-
}
|
|
1665
|
-
updateProgress(entry) {
|
|
1666
|
-
this.ensureDir(this.progressPath);
|
|
1667
|
-
const existing = this.readProgress();
|
|
1668
|
-
const timestamp = (entry.timestamp ?? new Date).toISOString();
|
|
1669
|
-
const label = entry.role === "user" ? "User" : "Assistant";
|
|
1670
|
-
const line = `**${label}** (${timestamp}):
|
|
1671
|
-
${entry.content}`;
|
|
1672
|
-
const updated = existing ? `${existing}
|
|
1673
|
-
|
|
1674
|
-
---
|
|
1675
|
-
|
|
1676
|
-
${line}` : `# Conversation History
|
|
1677
|
-
|
|
1678
|
-
${line}`;
|
|
1679
|
-
import_node_fs3.writeFileSync(this.progressPath, updated);
|
|
1680
|
-
}
|
|
1681
|
-
getFullContext() {
|
|
1682
|
-
const context = this.readContext();
|
|
1683
|
-
const parts = [];
|
|
1684
|
-
if (context.trim()) {
|
|
1685
|
-
parts.push(context.trim());
|
|
1686
|
-
}
|
|
1687
|
-
return parts.join(`
|
|
1688
|
-
|
|
1689
|
-
---
|
|
1690
|
-
|
|
1691
|
-
`);
|
|
1692
|
-
}
|
|
1693
|
-
initialize(info) {
|
|
1694
|
-
this.ensureDir(this.contextPath);
|
|
1695
|
-
this.ensureDir(this.progressPath);
|
|
1696
|
-
const techStackList = info.techStack.map((t) => `- ${t}`).join(`
|
|
1697
|
-
`);
|
|
1698
|
-
const contextContent = `# Project: ${info.name}
|
|
1699
|
-
|
|
1700
|
-
## Mission
|
|
1701
|
-
${info.mission}
|
|
1702
|
-
|
|
1703
|
-
## Tech Stack
|
|
1704
|
-
${techStackList}
|
|
1705
|
-
|
|
1706
|
-
## Architecture
|
|
1707
|
-
<!-- Describe your high-level architecture here -->
|
|
1708
|
-
|
|
1709
|
-
## Key Decisions
|
|
1710
|
-
<!-- Document important technical decisions and their rationale -->
|
|
1711
|
-
|
|
1712
|
-
## Feature Areas
|
|
1713
|
-
<!-- List your main feature areas and their status -->
|
|
1714
|
-
`;
|
|
1715
|
-
const progressContent = `# Conversation History
|
|
1716
|
-
`;
|
|
1717
|
-
import_node_fs3.writeFileSync(this.contextPath, contextContent);
|
|
1718
|
-
import_node_fs3.writeFileSync(this.progressPath, progressContent);
|
|
1719
|
-
}
|
|
1720
|
-
get exists() {
|
|
1721
|
-
return import_node_fs3.existsSync(this.contextPath) || import_node_fs3.existsSync(this.progressPath);
|
|
1722
|
-
}
|
|
1723
|
-
ensureDir(filePath) {
|
|
1724
|
-
const dir = import_node_path5.dirname(filePath);
|
|
1725
|
-
if (!import_node_fs3.existsSync(dir)) {
|
|
1726
|
-
import_node_fs3.mkdirSync(dir, { recursive: true });
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
}
|
|
1730
|
-
var import_node_fs3, import_node_path5;
|
|
1731
|
-
var init_knowledge_base = __esm(() => {
|
|
1732
|
-
init_config();
|
|
1733
|
-
import_node_fs3 = require("node:fs");
|
|
1734
|
-
import_node_path5 = require("node:path");
|
|
1735
|
-
});
|
|
1736
|
-
|
|
1737
1629
|
// src/agent/git-workflow.ts
|
|
1738
1630
|
class GitWorkflow {
|
|
1739
1631
|
config;
|
|
@@ -1985,223 +1877,157 @@ class PromptBuilder {
|
|
|
1985
1877
|
constructor(projectPath) {
|
|
1986
1878
|
this.projectPath = projectPath;
|
|
1987
1879
|
}
|
|
1988
|
-
async build(task
|
|
1989
|
-
let prompt = `# Task: ${task.title}
|
|
1990
|
-
|
|
1991
|
-
`;
|
|
1880
|
+
async build(task) {
|
|
1992
1881
|
const roleText = this.roleToText(task.assigneeRole);
|
|
1882
|
+
const description = task.description || "No description provided.";
|
|
1883
|
+
const context = this.getProjectContext();
|
|
1884
|
+
const learnings = this.getLearningsContent();
|
|
1885
|
+
const knowledgeBase = this.getKnowledgeBaseSection();
|
|
1886
|
+
let sections = "";
|
|
1993
1887
|
if (roleText) {
|
|
1994
|
-
|
|
1888
|
+
sections += `
|
|
1889
|
+
<role>
|
|
1995
1890
|
You are acting as a ${roleText}.
|
|
1996
|
-
|
|
1891
|
+
</role>
|
|
1997
1892
|
`;
|
|
1998
1893
|
}
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
`;
|
|
2003
|
-
const projectConfig = this.getProjectConfig();
|
|
2004
|
-
if (projectConfig) {
|
|
2005
|
-
prompt += `## Project Metadata
|
|
2006
|
-
`;
|
|
2007
|
-
prompt += `- Version: ${projectConfig.version || "Unknown"}
|
|
2008
|
-
`;
|
|
2009
|
-
prompt += `- Created At: ${projectConfig.createdAt || "Unknown"}
|
|
2010
|
-
|
|
2011
|
-
`;
|
|
2012
|
-
}
|
|
2013
|
-
let serverContext = null;
|
|
2014
|
-
if (options.taskContext) {
|
|
2015
|
-
try {
|
|
2016
|
-
serverContext = JSON.parse(options.taskContext);
|
|
2017
|
-
} catch {
|
|
2018
|
-
serverContext = { context: options.taskContext };
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
2022
|
-
let hasLocalContext = false;
|
|
2023
|
-
if (import_node_fs4.existsSync(contextPath)) {
|
|
2024
|
-
try {
|
|
2025
|
-
const context = import_node_fs4.readFileSync(contextPath, "utf-8");
|
|
2026
|
-
if (context.trim().length > 20) {
|
|
2027
|
-
prompt += `## Project Context (Local)
|
|
1894
|
+
if (context) {
|
|
1895
|
+
sections += `
|
|
1896
|
+
<project_context>
|
|
2028
1897
|
${context}
|
|
2029
|
-
|
|
1898
|
+
</project_context>
|
|
2030
1899
|
`;
|
|
2031
|
-
hasLocalContext = true;
|
|
2032
|
-
}
|
|
2033
|
-
} catch (err) {
|
|
2034
|
-
console.warn(`Warning: Could not read context file: ${err}`);
|
|
2035
|
-
}
|
|
2036
1900
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
${fallback}
|
|
2042
|
-
|
|
1901
|
+
sections += `
|
|
1902
|
+
<knowledge_base>
|
|
1903
|
+
${knowledgeBase}
|
|
1904
|
+
</knowledge_base>
|
|
2043
1905
|
`;
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
if (project) {
|
|
2051
|
-
prompt += `- Project: ${project.name || "Unknown"}
|
|
2052
|
-
`;
|
|
2053
|
-
if (!hasLocalContext && project.techStack?.length) {
|
|
2054
|
-
prompt += `- Tech Stack: ${project.techStack.join(", ")}
|
|
2055
|
-
`;
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
if (serverContext.context) {
|
|
2059
|
-
prompt += `
|
|
2060
|
-
${serverContext.context}
|
|
2061
|
-
`;
|
|
2062
|
-
}
|
|
2063
|
-
prompt += `
|
|
1906
|
+
if (learnings) {
|
|
1907
|
+
sections += `
|
|
1908
|
+
<learnings>
|
|
1909
|
+
These are accumulated lessons from past tasks. Follow them to avoid repeating mistakes:
|
|
1910
|
+
${learnings}
|
|
1911
|
+
</learnings>
|
|
2064
1912
|
`;
|
|
2065
1913
|
}
|
|
2066
|
-
prompt += this.getProjectStructure();
|
|
2067
|
-
prompt += `## Project Knowledge Base
|
|
2068
|
-
`;
|
|
2069
|
-
prompt += `You have access to the following documentation directories for context:
|
|
2070
|
-
`;
|
|
2071
|
-
prompt += `- Artifacts: \`.locus/artifacts\`
|
|
2072
|
-
`;
|
|
2073
|
-
prompt += `- Documents: \`.locus/documents\`
|
|
2074
|
-
`;
|
|
2075
|
-
prompt += `If you need more information about the project strategies, plans, or architecture, please read files in these directories.
|
|
2076
|
-
|
|
2077
|
-
`;
|
|
2078
1914
|
if (task.docs && task.docs.length > 0) {
|
|
2079
|
-
|
|
2080
|
-
`;
|
|
2081
|
-
prompt += `> Full content available on server. Rely on Task Description for specific requirements.
|
|
2082
|
-
|
|
2083
|
-
`;
|
|
1915
|
+
let docsContent = "";
|
|
2084
1916
|
for (const doc of task.docs) {
|
|
2085
1917
|
const content = doc.content || "";
|
|
2086
1918
|
const limit = 800;
|
|
2087
1919
|
const preview = content.slice(0, limit);
|
|
2088
1920
|
const isTruncated = content.length > limit;
|
|
2089
|
-
|
|
1921
|
+
docsContent += `### ${doc.title}
|
|
2090
1922
|
${preview}${isTruncated ? `
|
|
2091
1923
|
...(truncated)...` : ""}
|
|
2092
1924
|
|
|
2093
1925
|
`;
|
|
2094
1926
|
}
|
|
1927
|
+
sections += `
|
|
1928
|
+
<documents>
|
|
1929
|
+
${docsContent.trimEnd()}
|
|
1930
|
+
</documents>
|
|
1931
|
+
`;
|
|
2095
1932
|
}
|
|
2096
1933
|
if (task.acceptanceChecklist && task.acceptanceChecklist.length > 0) {
|
|
2097
|
-
|
|
2098
|
-
`;
|
|
1934
|
+
let criteria = "";
|
|
2099
1935
|
for (const item of task.acceptanceChecklist) {
|
|
2100
|
-
|
|
1936
|
+
criteria += `- ${item.done ? "[x]" : "[ ]"} ${item.text}
|
|
2101
1937
|
`;
|
|
2102
1938
|
}
|
|
2103
|
-
|
|
1939
|
+
sections += `
|
|
1940
|
+
<acceptance_criteria>
|
|
1941
|
+
${criteria.trimEnd()}
|
|
1942
|
+
</acceptance_criteria>
|
|
2104
1943
|
`;
|
|
2105
1944
|
}
|
|
2106
1945
|
if (task.comments && task.comments.length > 0) {
|
|
2107
1946
|
const filteredComments = task.comments.filter((comment) => comment.author !== "system");
|
|
2108
1947
|
const comments = filteredComments.slice(0, 3);
|
|
2109
|
-
|
|
1948
|
+
if (comments.length > 0) {
|
|
1949
|
+
let commentsContent = "";
|
|
1950
|
+
for (const comment of comments) {
|
|
1951
|
+
const date = new Date(comment.createdAt).toLocaleString();
|
|
1952
|
+
commentsContent += `- ${comment.author} (${date}): ${comment.text}
|
|
2110
1953
|
`;
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
1954
|
+
}
|
|
1955
|
+
sections += `
|
|
1956
|
+
<feedback>
|
|
1957
|
+
${commentsContent.trimEnd()}
|
|
1958
|
+
</feedback>
|
|
2114
1959
|
`;
|
|
2115
1960
|
}
|
|
2116
|
-
prompt += `
|
|
2117
|
-
`;
|
|
2118
1961
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
1962
|
+
return `<task_execution>
|
|
1963
|
+
Complete this task: ${task.title}
|
|
1964
|
+
|
|
1965
|
+
<description>
|
|
1966
|
+
${description}
|
|
1967
|
+
</description>
|
|
1968
|
+
${sections}
|
|
1969
|
+
<rules>
|
|
1970
|
+
- Complete the task as described
|
|
1971
|
+
- Save any high-level documentation (PRDs, technical drafts, architecture docs) in \`.locus/artifacts/\`
|
|
1972
|
+
- Use relative paths from the project root at all times — no absolute local paths
|
|
1973
|
+
- Do NOT run \`git add\`, \`git commit\`, \`git push\`, or create branches — Locus handles git automatically
|
|
1974
|
+
</rules>
|
|
1975
|
+
</task_execution>`;
|
|
2126
1976
|
}
|
|
2127
1977
|
async buildGenericPrompt(query) {
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
1978
|
+
const context = this.getProjectContext();
|
|
1979
|
+
const learnings = this.getLearningsContent();
|
|
1980
|
+
const knowledgeBase = this.getKnowledgeBaseSection();
|
|
1981
|
+
let sections = "";
|
|
1982
|
+
if (context) {
|
|
1983
|
+
sections += `
|
|
1984
|
+
<project_context>
|
|
1985
|
+
${context}
|
|
1986
|
+
</project_context>
|
|
2134
1987
|
`;
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
1988
|
+
}
|
|
1989
|
+
sections += `
|
|
1990
|
+
<knowledge_base>
|
|
1991
|
+
${knowledgeBase}
|
|
1992
|
+
</knowledge_base>
|
|
2138
1993
|
`;
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
1994
|
+
if (learnings) {
|
|
1995
|
+
sections += `
|
|
1996
|
+
<learnings>
|
|
1997
|
+
These are accumulated lessons from past tasks. Follow them to avoid repeating mistakes:
|
|
1998
|
+
${learnings}
|
|
1999
|
+
</learnings>
|
|
2143
2000
|
`;
|
|
2144
2001
|
}
|
|
2002
|
+
return `<direct_execution>
|
|
2003
|
+
Execute this prompt: ${query}
|
|
2004
|
+
${sections}
|
|
2005
|
+
<rules>
|
|
2006
|
+
- Execute the prompt based on the provided project context
|
|
2007
|
+
- Use relative paths from the project root at all times — no absolute local paths
|
|
2008
|
+
- Do NOT run \`git add\`, \`git commit\`, \`git push\`, or create branches — Locus handles git automatically
|
|
2009
|
+
</rules>
|
|
2010
|
+
</direct_execution>`;
|
|
2011
|
+
}
|
|
2012
|
+
getProjectContext() {
|
|
2145
2013
|
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
2146
|
-
|
|
2147
|
-
if (import_node_fs4.existsSync(contextPath)) {
|
|
2014
|
+
if (import_node_fs3.existsSync(contextPath)) {
|
|
2148
2015
|
try {
|
|
2149
|
-
const context =
|
|
2016
|
+
const context = import_node_fs3.readFileSync(contextPath, "utf-8");
|
|
2150
2017
|
if (context.trim().length > 20) {
|
|
2151
|
-
|
|
2152
|
-
${context}
|
|
2153
|
-
|
|
2154
|
-
`;
|
|
2155
|
-
hasLocalContext = true;
|
|
2018
|
+
return context;
|
|
2156
2019
|
}
|
|
2157
2020
|
} catch (err) {
|
|
2158
2021
|
console.warn(`Warning: Could not read context file: ${err}`);
|
|
2159
2022
|
}
|
|
2160
2023
|
}
|
|
2161
|
-
|
|
2162
|
-
const fallback = this.getFallbackContext();
|
|
2163
|
-
if (fallback) {
|
|
2164
|
-
prompt += `## Project Context (README Fallback)
|
|
2165
|
-
${fallback}
|
|
2166
|
-
|
|
2167
|
-
`;
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
prompt += this.getProjectStructure();
|
|
2171
|
-
prompt += `## Project Knowledge Base
|
|
2172
|
-
`;
|
|
2173
|
-
prompt += `You have access to the following documentation directories for context:
|
|
2174
|
-
`;
|
|
2175
|
-
prompt += `- Artifacts: \`.locus/artifacts\` (local-only, not synced to cloud)
|
|
2176
|
-
`;
|
|
2177
|
-
prompt += `- Documents: \`.locus/documents\` (synced from cloud)
|
|
2178
|
-
`;
|
|
2179
|
-
prompt += `If you need more information about the project strategies, plans, or architecture, please read files in these directories.
|
|
2180
|
-
|
|
2181
|
-
`;
|
|
2182
|
-
prompt += `## Instructions
|
|
2183
|
-
1. Execute the prompt based on the provided project context.
|
|
2184
|
-
2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
|
|
2185
|
-
3. **Git**: Do NOT run \`git add\`, \`git commit\`, \`git push\`, or create branches. The Locus system handles all git operations automatically after your execution completes.
|
|
2186
|
-
4. **Progress**: Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically.`;
|
|
2187
|
-
return prompt;
|
|
2188
|
-
}
|
|
2189
|
-
getProjectConfig() {
|
|
2190
|
-
const configPath = getLocusPath(this.projectPath, "configFile");
|
|
2191
|
-
if (import_node_fs4.existsSync(configPath)) {
|
|
2192
|
-
try {
|
|
2193
|
-
return JSON.parse(import_node_fs4.readFileSync(configPath, "utf-8"));
|
|
2194
|
-
} catch {
|
|
2195
|
-
return null;
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
return null;
|
|
2024
|
+
return this.getFallbackContext() || null;
|
|
2199
2025
|
}
|
|
2200
2026
|
getFallbackContext() {
|
|
2201
|
-
const readmePath =
|
|
2202
|
-
if (
|
|
2027
|
+
const readmePath = import_node_path5.join(this.projectPath, "README.md");
|
|
2028
|
+
if (import_node_fs3.existsSync(readmePath)) {
|
|
2203
2029
|
try {
|
|
2204
|
-
const content =
|
|
2030
|
+
const content = import_node_fs3.readFileSync(readmePath, "utf-8");
|
|
2205
2031
|
const limit = 1000;
|
|
2206
2032
|
return content.slice(0, limit) + (content.length > limit ? `
|
|
2207
2033
|
...(truncated)...` : "");
|
|
@@ -2211,32 +2037,28 @@ ${fallback}
|
|
|
2211
2037
|
}
|
|
2212
2038
|
return "";
|
|
2213
2039
|
}
|
|
2214
|
-
|
|
2040
|
+
getKnowledgeBaseSection() {
|
|
2041
|
+
return `You have access to the following documentation directories for context:
|
|
2042
|
+
- Artifacts: \`.locus/artifacts\` (local-only, not synced to cloud)
|
|
2043
|
+
- Documents: \`.locus/documents\` (synced from cloud)
|
|
2044
|
+
If you need more information about the project strategies, plans, or architecture, read files in these directories.`;
|
|
2045
|
+
}
|
|
2046
|
+
getLearningsContent() {
|
|
2047
|
+
const learningsPath = getLocusPath(this.projectPath, "learningsFile");
|
|
2048
|
+
if (!import_node_fs3.existsSync(learningsPath)) {
|
|
2049
|
+
return null;
|
|
2050
|
+
}
|
|
2215
2051
|
try {
|
|
2216
|
-
const
|
|
2217
|
-
const
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
return import_node_fs4.statSync(import_node_path6.join(this.projectPath, e)).isDirectory();
|
|
2222
|
-
} catch {
|
|
2223
|
-
return false;
|
|
2224
|
-
}
|
|
2225
|
-
});
|
|
2226
|
-
if (folders.length === 0)
|
|
2227
|
-
return "";
|
|
2228
|
-
let structure = `## Project Structure
|
|
2229
|
-
`;
|
|
2230
|
-
structure += `Key directories in this project:
|
|
2231
|
-
`;
|
|
2232
|
-
for (const folder of folders) {
|
|
2233
|
-
structure += `- \`${folder}/\`
|
|
2234
|
-
`;
|
|
2052
|
+
const content = import_node_fs3.readFileSync(learningsPath, "utf-8");
|
|
2053
|
+
const lines = content.split(`
|
|
2054
|
+
`).filter((l) => l.startsWith("- "));
|
|
2055
|
+
if (lines.length === 0) {
|
|
2056
|
+
return null;
|
|
2235
2057
|
}
|
|
2236
|
-
return
|
|
2237
|
-
|
|
2058
|
+
return lines.join(`
|
|
2059
|
+
`);
|
|
2238
2060
|
} catch {
|
|
2239
|
-
return
|
|
2061
|
+
return null;
|
|
2240
2062
|
}
|
|
2241
2063
|
}
|
|
2242
2064
|
roleToText(role) {
|
|
@@ -2259,11 +2081,11 @@ ${fallback}
|
|
|
2259
2081
|
}
|
|
2260
2082
|
}
|
|
2261
2083
|
}
|
|
2262
|
-
var
|
|
2084
|
+
var import_node_fs3, import_node_path5, import_shared2;
|
|
2263
2085
|
var init_prompt_builder = __esm(() => {
|
|
2264
2086
|
init_config();
|
|
2265
|
-
|
|
2266
|
-
|
|
2087
|
+
import_node_fs3 = require("node:fs");
|
|
2088
|
+
import_node_path5 = require("node:path");
|
|
2267
2089
|
import_shared2 = require("@locusai/shared");
|
|
2268
2090
|
});
|
|
2269
2091
|
|
|
@@ -2381,7 +2203,6 @@ class AgentWorker {
|
|
|
2381
2203
|
client;
|
|
2382
2204
|
aiRunner;
|
|
2383
2205
|
taskExecutor;
|
|
2384
|
-
knowledgeBase;
|
|
2385
2206
|
gitWorkflow;
|
|
2386
2207
|
maxTasks = 50;
|
|
2387
2208
|
tasksCompleted = 0;
|
|
@@ -2421,7 +2242,6 @@ class AgentWorker {
|
|
|
2421
2242
|
projectPath,
|
|
2422
2243
|
log
|
|
2423
2244
|
});
|
|
2424
|
-
this.knowledgeBase = new KnowledgeBase(projectPath);
|
|
2425
2245
|
this.gitWorkflow = new GitWorkflow(config, log);
|
|
2426
2246
|
const providerLabel = provider === "codex" ? "Codex" : "Claude";
|
|
2427
2247
|
this.log(`Using ${providerLabel} CLI for all phases`, "info");
|
|
@@ -2495,20 +2315,6 @@ class AgentWorker {
|
|
|
2495
2315
|
};
|
|
2496
2316
|
}
|
|
2497
2317
|
}
|
|
2498
|
-
updateProgress(task, summary) {
|
|
2499
|
-
try {
|
|
2500
|
-
this.knowledgeBase.updateProgress({
|
|
2501
|
-
role: "user",
|
|
2502
|
-
content: task.title
|
|
2503
|
-
});
|
|
2504
|
-
this.knowledgeBase.updateProgress({
|
|
2505
|
-
role: "assistant",
|
|
2506
|
-
content: summary
|
|
2507
|
-
});
|
|
2508
|
-
} catch (err) {
|
|
2509
|
-
this.log(`Failed to update progress: ${err instanceof Error ? err.message : String(err)}`, "warn");
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
2318
|
startHeartbeat() {
|
|
2513
2319
|
this.sendHeartbeat();
|
|
2514
2320
|
this.heartbeatInterval = setInterval(() => this.sendHeartbeat(), 60000);
|
|
@@ -2583,7 +2389,6 @@ Branch: \`${result.branch}\`` : "";
|
|
|
2583
2389
|
this.tasksCompleted++;
|
|
2584
2390
|
this.completedTaskList.push({ title: task.title, id: task.id });
|
|
2585
2391
|
this.taskSummaries.push(result.summary);
|
|
2586
|
-
this.updateProgress(task, result.summary);
|
|
2587
2392
|
}
|
|
2588
2393
|
} else {
|
|
2589
2394
|
this.log(`Failed: ${task.title} - ${result.summary}`, "error");
|
|
@@ -2628,7 +2433,6 @@ var init_worker = __esm(() => {
|
|
|
2628
2433
|
init_config();
|
|
2629
2434
|
init_git_utils();
|
|
2630
2435
|
init_src();
|
|
2631
|
-
init_knowledge_base();
|
|
2632
2436
|
init_colors();
|
|
2633
2437
|
init_git_workflow();
|
|
2634
2438
|
init_task_executor();
|