@locusai/sdk 0.12.0 → 0.12.1

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.
Files changed (44) hide show
  1. package/dist/agent/codebase-indexer-service.d.ts.map +1 -1
  2. package/dist/agent/reviewer-worker.d.ts +0 -1
  3. package/dist/agent/reviewer-worker.d.ts.map +1 -1
  4. package/dist/agent/worker.d.ts +0 -2
  5. package/dist/agent/worker.d.ts.map +1 -1
  6. package/dist/agent/worker.js +135 -331
  7. package/dist/ai/claude-runner.d.ts +1 -0
  8. package/dist/ai/claude-runner.d.ts.map +1 -1
  9. package/dist/ai/codex-runner.d.ts +1 -1
  10. package/dist/ai/codex-runner.d.ts.map +1 -1
  11. package/dist/ai/factory.d.ts +2 -0
  12. package/dist/ai/factory.d.ts.map +1 -1
  13. package/dist/core/config.d.ts +2 -4
  14. package/dist/core/config.d.ts.map +1 -1
  15. package/dist/core/prompt-builder.d.ts +4 -5
  16. package/dist/core/prompt-builder.d.ts.map +1 -1
  17. package/dist/index-node.d.ts +1 -1
  18. package/dist/index-node.d.ts.map +1 -1
  19. package/dist/index-node.js +396 -721
  20. package/dist/planning/agents/cross-task-reviewer.d.ts +0 -14
  21. package/dist/planning/agents/cross-task-reviewer.d.ts.map +1 -1
  22. package/dist/planning/agents/planner.d.ts +11 -5
  23. package/dist/planning/agents/planner.d.ts.map +1 -1
  24. package/dist/planning/index.d.ts +1 -1
  25. package/dist/planning/index.d.ts.map +1 -1
  26. package/dist/planning/plan-manager.d.ts +0 -1
  27. package/dist/planning/plan-manager.d.ts.map +1 -1
  28. package/dist/planning/planning-meeting.d.ts +11 -12
  29. package/dist/planning/planning-meeting.d.ts.map +1 -1
  30. package/dist/planning/sprint-plan.d.ts +7 -3
  31. package/dist/planning/sprint-plan.d.ts.map +1 -1
  32. package/dist/utils/json-extractor.d.ts +6 -2
  33. package/dist/utils/json-extractor.d.ts.map +1 -1
  34. package/dist/utils/structured-output.d.ts +14 -0
  35. package/dist/utils/structured-output.d.ts.map +1 -0
  36. package/package.json +5 -4
  37. package/dist/project/knowledge-base.d.ts +0 -24
  38. package/dist/project/knowledge-base.d.ts.map +0 -1
  39. package/dist/worktree/index.d.ts +0 -2
  40. package/dist/worktree/index.d.ts.map +0 -1
  41. package/dist/worktree/worktree-config.d.ts +0 -2
  42. package/dist/worktree/worktree-config.d.ts.map +0 -1
  43. package/dist/worktree/worktree-manager.d.ts +0 -2
  44. 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;CA2C5C"}
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"}
@@ -19,7 +19,6 @@ export declare class ReviewerWorker {
19
19
  private client;
20
20
  private aiRunner;
21
21
  private prService;
22
- private knowledgeBase;
23
22
  private heartbeatInterval;
24
23
  private currentTaskId;
25
24
  private maxReviews;
@@ -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;AAc5D,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;IAUb,OAAO,CAAC,MAAM;IAT1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,gBAAgB,CAAK;gBAET,MAAM,EAAE,cAAc;IA6B1C,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;CAiF3B"}
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"}
@@ -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":"AAUA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAiBV,OAAO,CAAC,MAAM;IAhB1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,aAAa,CAAgB;IACrC,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;IAwDxC,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;IAkBtB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAoBf,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgJ3B"}
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"}
@@ -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, progress, etc.)",
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
- async* runStream(prompt) {
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, timeoutMs, reasoningEffort) {
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.timeoutMs, config.reasoningEffort ?? "high");
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, options = {}) {
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
- prompt += `## Role
1888
+ sections += `
1889
+ <role>
1995
1890
  You are acting as a ${roleText}.
1996
-
1891
+ </role>
1997
1892
  `;
1998
1893
  }
1999
- prompt += `## Description
2000
- ${task.description || "No description provided."}
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
- if (!hasLocalContext) {
2038
- const fallback = this.getFallbackContext();
2039
- if (fallback) {
2040
- prompt += `## Project Context (README Fallback)
2041
- ${fallback}
2042
-
1901
+ sections += `
1902
+ <knowledge_base>
1903
+ ${knowledgeBase}
1904
+ </knowledge_base>
2043
1905
  `;
2044
- }
2045
- }
2046
- if (serverContext) {
2047
- prompt += `## Project Context (Server)
2048
- `;
2049
- const project = serverContext.project;
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
- prompt += `## Attached Documents (Summarized)
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
- prompt += `### Doc: ${doc.title}
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
- prompt += `## Acceptance Criteria
2098
- `;
1934
+ let criteria = "";
2099
1935
  for (const item of task.acceptanceChecklist) {
2100
- prompt += `- ${item.done ? "[x]" : "[ ]"} ${item.text}
1936
+ criteria += `- ${item.done ? "[x]" : "[ ]"} ${item.text}
2101
1937
  `;
2102
1938
  }
2103
- prompt += `
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
- prompt += `## Task Comments & Feedback
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
- for (const comment of comments) {
2112
- const date = new Date(comment.createdAt).toLocaleString();
2113
- prompt += `- ${comment.author} (${date}): ${comment.text}
1954
+ }
1955
+ sections += `
1956
+ <feedback>
1957
+ ${commentsContent.trimEnd()}
1958
+ </feedback>
2114
1959
  `;
2115
1960
  }
2116
- prompt += `
2117
- `;
2118
1961
  }
2119
- prompt += `## Instructions
2120
- 1. Complete this task.
2121
- 2. **Artifact Management**: If you create any high-level documentation (PRDs, technical drafts, architecture docs), you MUST save them in \`.locus/artifacts/\`. Do NOT create them in the root directory.
2122
- 3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
2123
- 4. **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.
2124
- 5. **Progress**: Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically.`;
2125
- return prompt;
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
- let prompt = `# Direct Execution
2129
-
2130
- `;
2131
- prompt += `## Prompt
2132
- ${query}
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
- const projectConfig = this.getProjectConfig();
2136
- if (projectConfig) {
2137
- prompt += `## Project Metadata
1988
+ }
1989
+ sections += `
1990
+ <knowledge_base>
1991
+ ${knowledgeBase}
1992
+ </knowledge_base>
2138
1993
  `;
2139
- prompt += `- Version: ${projectConfig.version || "Unknown"}
2140
- `;
2141
- prompt += `- Created At: ${projectConfig.createdAt || "Unknown"}
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
- let hasLocalContext = false;
2147
- if (import_node_fs4.existsSync(contextPath)) {
2014
+ if (import_node_fs3.existsSync(contextPath)) {
2148
2015
  try {
2149
- const context = import_node_fs4.readFileSync(contextPath, "utf-8");
2016
+ const context = import_node_fs3.readFileSync(contextPath, "utf-8");
2150
2017
  if (context.trim().length > 20) {
2151
- prompt += `## Project Context (Local)
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
- if (!hasLocalContext) {
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 = import_node_path6.join(this.projectPath, "README.md");
2202
- if (import_node_fs4.existsSync(readmePath)) {
2027
+ const readmePath = import_node_path5.join(this.projectPath, "README.md");
2028
+ if (import_node_fs3.existsSync(readmePath)) {
2203
2029
  try {
2204
- const content = import_node_fs4.readFileSync(readmePath, "utf-8");
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
- getProjectStructure() {
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 entries = import_node_fs4.readdirSync(this.projectPath);
2217
- const folders = entries.filter((e) => {
2218
- if (e.startsWith(".") || e === "node_modules")
2219
- return false;
2220
- try {
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 `${structure}
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 import_node_fs4, import_node_path6, import_shared2;
2084
+ var import_node_fs3, import_node_path5, import_shared2;
2263
2085
  var init_prompt_builder = __esm(() => {
2264
2086
  init_config();
2265
- import_node_fs4 = require("node:fs");
2266
- import_node_path6 = require("node:path");
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();