@locusai/cli 0.9.10 → 0.9.12

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.
@@ -30921,12 +30921,31 @@ class WorktreeManager {
30921
30921
  const status = this.git("status --porcelain", worktreePath).trim();
30922
30922
  return status.length > 0;
30923
30923
  }
30924
- commitChanges(worktreePath, message) {
30925
- if (!this.hasChanges(worktreePath)) {
30924
+ hasCommitsAhead(worktreePath, baseBranch) {
30925
+ try {
30926
+ const count = this.git(`rev-list --count "${baseBranch}..HEAD"`, worktreePath).trim();
30927
+ return Number.parseInt(count, 10) > 0;
30928
+ } catch {
30929
+ return false;
30930
+ }
30931
+ }
30932
+ commitChanges(worktreePath, message, baseBranch) {
30933
+ const hasUncommittedChanges = this.hasChanges(worktreePath);
30934
+ if (!hasUncommittedChanges) {
30935
+ if (baseBranch && this.hasCommitsAhead(worktreePath, baseBranch)) {
30936
+ const hash3 = this.git("rev-parse HEAD", worktreePath).trim();
30937
+ this.log(`Agent already committed changes (${hash3.slice(0, 8)}); skipping additional commit`, "info");
30938
+ return hash3;
30939
+ }
30926
30940
  this.log("No changes to commit", "info");
30927
30941
  return null;
30928
30942
  }
30929
30943
  this.git("add -A", worktreePath);
30944
+ const staged = this.git("diff --cached --name-only", worktreePath).trim();
30945
+ if (!staged) {
30946
+ this.log("No changes to commit", "info");
30947
+ return null;
30948
+ }
30930
30949
  this.gitExec(["commit", "-m", message], worktreePath);
30931
30950
  const hash2 = this.git("rev-parse HEAD", worktreePath).trim();
30932
30951
  this.log(`Committed: ${hash2.slice(0, 8)}`, "success");
@@ -30949,8 +30968,8 @@ class WorktreeManager {
30949
30968
  } catch {}
30950
30969
  this.gitExec(["push", "--force-with-lease", "-u", remote, branch], worktreePath);
30951
30970
  this.log(`Pushed ${branch} to ${remote} with --force-with-lease`, "success");
30971
+ return branch;
30952
30972
  }
30953
- return branch;
30954
30973
  }
30955
30974
  getBranch(worktreePath) {
30956
30975
  return this.git("rev-parse --abbrev-ref HEAD", worktreePath).trim();
@@ -31175,7 +31194,9 @@ ${comment.text}
31175
31194
  prompt += `## Instructions
31176
31195
  1. Complete this task.
31177
31196
  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.
31178
- 3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).`;
31197
+ 3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
31198
+ 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.
31199
+ 5. **Progress**: Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically.`;
31179
31200
  return prompt;
31180
31201
  }
31181
31202
  async buildGenericPrompt(query) {
@@ -31242,7 +31263,9 @@ There is an index file in the .locus/codebase-index.json and if you need you can
31242
31263
  }
31243
31264
  prompt += `## Instructions
31244
31265
  1. Execute the prompt based on the provided project context.
31245
- 2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).`;
31266
+ 2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
31267
+ 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.
31268
+ 4. **Progress**: Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically.`;
31246
31269
  return prompt;
31247
31270
  }
31248
31271
  getProjectConfig() {
@@ -31505,7 +31528,7 @@ class AgentWorker {
31505
31528
  executor: taskExecutor
31506
31529
  };
31507
31530
  }
31508
- commitAndPushWorktree(worktreePath, task2) {
31531
+ commitAndPushWorktree(worktreePath, task2, baseBranch) {
31509
31532
  if (!this.worktreeManager) {
31510
31533
  return { branch: null, pushed: false, pushFailed: false };
31511
31534
  }
@@ -31522,7 +31545,7 @@ class AgentWorker {
31522
31545
 
31523
31546
  ${trailers.join(`
31524
31547
  `)}`;
31525
- const hash2 = this.worktreeManager.commitChanges(worktreePath, commitMessage);
31548
+ const hash2 = this.worktreeManager.commitChanges(worktreePath, commitMessage, baseBranch);
31526
31549
  if (!hash2) {
31527
31550
  this.log("No changes to commit for this task", "info");
31528
31551
  return {
@@ -31612,7 +31635,7 @@ ${trailers.join(`
31612
31635
  let prError = null;
31613
31636
  let noChanges = false;
31614
31637
  if (result.success && worktreePath) {
31615
- const commitResult = this.commitAndPushWorktree(worktreePath, fullTask);
31638
+ const commitResult = this.commitAndPushWorktree(worktreePath, fullTask, baseBranch ?? undefined);
31616
31639
  taskBranch = commitResult.branch;
31617
31640
  branchPushed = commitResult.pushed;
31618
31641
  keepBranch = taskBranch !== null;
package/bin/locus.js CHANGED
@@ -6379,7 +6379,10 @@ var init_config = __esm(() => {
6379
6379
  ".locus/settings.json",
6380
6380
  "",
6381
6381
  "# Locus AI - Configuration (contains project context, progress, etc.)",
6382
- ".locus/config.json"
6382
+ ".locus/config.json",
6383
+ "",
6384
+ "# Locus AI - Project progress (contains project progress, etc.)",
6385
+ ".locus/project/progress.md"
6383
6386
  ];
6384
6387
  });
6385
6388
 
@@ -38251,7 +38254,9 @@ ${comment.text}
38251
38254
  prompt += `## Instructions
38252
38255
  1. Complete this task.
38253
38256
  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.
38254
- 3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).`;
38257
+ 3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
38258
+ 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.
38259
+ 5. **Progress**: Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically.`;
38255
38260
  return prompt;
38256
38261
  }
38257
38262
  async buildGenericPrompt(query) {
@@ -38318,7 +38323,9 @@ There is an index file in the .locus/codebase-index.json and if you need you can
38318
38323
  }
38319
38324
  prompt += `## Instructions
38320
38325
  1. Execute the prompt based on the provided project context.
38321
- 2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).`;
38326
+ 2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
38327
+ 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.
38328
+ 4. **Progress**: Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically.`;
38322
38329
  return prompt;
38323
38330
  }
38324
38331
  getProjectConfig() {
@@ -38607,12 +38614,31 @@ class WorktreeManager {
38607
38614
  const status = this.git("status --porcelain", worktreePath).trim();
38608
38615
  return status.length > 0;
38609
38616
  }
38610
- commitChanges(worktreePath, message) {
38611
- if (!this.hasChanges(worktreePath)) {
38617
+ hasCommitsAhead(worktreePath, baseBranch) {
38618
+ try {
38619
+ const count = this.git(`rev-list --count "${baseBranch}..HEAD"`, worktreePath).trim();
38620
+ return Number.parseInt(count, 10) > 0;
38621
+ } catch {
38622
+ return false;
38623
+ }
38624
+ }
38625
+ commitChanges(worktreePath, message, baseBranch) {
38626
+ const hasUncommittedChanges = this.hasChanges(worktreePath);
38627
+ if (!hasUncommittedChanges) {
38628
+ if (baseBranch && this.hasCommitsAhead(worktreePath, baseBranch)) {
38629
+ const hash3 = this.git("rev-parse HEAD", worktreePath).trim();
38630
+ this.log(`Agent already committed changes (${hash3.slice(0, 8)}); skipping additional commit`, "info");
38631
+ return hash3;
38632
+ }
38612
38633
  this.log("No changes to commit", "info");
38613
38634
  return null;
38614
38635
  }
38615
38636
  this.git("add -A", worktreePath);
38637
+ const staged = this.git("diff --cached --name-only", worktreePath).trim();
38638
+ if (!staged) {
38639
+ this.log("No changes to commit", "info");
38640
+ return null;
38641
+ }
38616
38642
  this.gitExec(["commit", "-m", message], worktreePath);
38617
38643
  const hash2 = this.git("rev-parse HEAD", worktreePath).trim();
38618
38644
  this.log(`Committed: ${hash2.slice(0, 8)}`, "success");
@@ -38635,8 +38661,8 @@ class WorktreeManager {
38635
38661
  } catch {}
38636
38662
  this.gitExec(["push", "--force-with-lease", "-u", remote, branch], worktreePath);
38637
38663
  this.log(`Pushed ${branch} to ${remote} with --force-with-lease`, "success");
38664
+ return branch;
38638
38665
  }
38639
- return branch;
38640
38666
  }
38641
38667
  getBranch(worktreePath) {
38642
38668
  return this.git("rev-parse --abbrev-ref HEAD", worktreePath).trim();
@@ -38875,7 +38901,7 @@ class AgentWorker {
38875
38901
  executor: taskExecutor
38876
38902
  };
38877
38903
  }
38878
- commitAndPushWorktree(worktreePath, task2) {
38904
+ commitAndPushWorktree(worktreePath, task2, baseBranch) {
38879
38905
  if (!this.worktreeManager) {
38880
38906
  return { branch: null, pushed: false, pushFailed: false };
38881
38907
  }
@@ -38892,7 +38918,7 @@ class AgentWorker {
38892
38918
 
38893
38919
  ${trailers.join(`
38894
38920
  `)}`;
38895
- const hash2 = this.worktreeManager.commitChanges(worktreePath, commitMessage);
38921
+ const hash2 = this.worktreeManager.commitChanges(worktreePath, commitMessage, baseBranch);
38896
38922
  if (!hash2) {
38897
38923
  this.log("No changes to commit for this task", "info");
38898
38924
  return {
@@ -38982,7 +39008,7 @@ ${trailers.join(`
38982
39008
  let prError = null;
38983
39009
  let noChanges = false;
38984
39010
  if (result.success && worktreePath) {
38985
- const commitResult = this.commitAndPushWorktree(worktreePath, fullTask);
39011
+ const commitResult = this.commitAndPushWorktree(worktreePath, fullTask, baseBranch ?? undefined);
38986
39012
  taskBranch = commitResult.branch;
38987
39013
  branchPushed = commitResult.pushed;
38988
39014
  keepBranch = taskBranch !== null;
@@ -42665,6 +42691,13 @@ Complex tasks must be planned before writing code. Create \`.locus/plans/<task-n
42665
42691
  - No new dependencies without explicit approval.
42666
42692
  - Never put raw secrets or credentials in the codebase.
42667
42693
 
42694
+ ## Git
42695
+
42696
+ - Do NOT run \`git add\`, \`git commit\`, \`git push\`, or create branches.
42697
+ - The Locus system handles all git operations (commit, push, PR creation) automatically after your execution completes.
42698
+ - Focus only on making file changes — the orchestrator takes care of version control.
42699
+ - Do NOT modify \`.locus/project/progress.md\`. The system updates it automatically. Changes to this file are excluded from commits to prevent merge conflicts across concurrent agents.
42700
+
42668
42701
  ## Avoiding Hallucinated / Slop Code
42669
42702
 
42670
42703
  - Ask before assuming. If requirements are ambiguous, incomplete, or could be interpreted multiple ways, stop and ask clarifying questions rather than guessing.
@@ -42808,8 +42841,9 @@ class ConfigManager {
42808
42841
  writeFileSync7(settingsPath, JSON.stringify(ordered, null, 2), "utf-8");
42809
42842
  }
42810
42843
  }
42811
- if (!existsSync15(locusMdPath)) {
42812
- writeFileSync7(locusMdPath, LOCUS_MD_TEMPLATE);
42844
+ const locusMdExisted = existsSync15(locusMdPath);
42845
+ writeFileSync7(locusMdPath, LOCUS_MD_TEMPLATE);
42846
+ if (!locusMdExisted) {
42813
42847
  result.directoriesCreated.push(".locus/LOCUS.md");
42814
42848
  }
42815
42849
  const locusSubdirs = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locusai/cli",
3
- "version": "0.9.10",
3
+ "version": "0.9.12",
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.10"
35
+ "@locusai/sdk": "^0.9.12"
36
36
  },
37
37
  "devDependencies": {}
38
38
  }