cortex-agents 4.0.8 → 4.1.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.
@@ -23,6 +23,8 @@ tools:
23
23
  session_list: true
24
24
  branch_status: true
25
25
  branch_create: true
26
+ worktree_create: true
27
+ worktree_list: true
26
28
  docs_list: true
27
29
  github_status: true
28
30
  github_issues: true
@@ -141,8 +143,9 @@ After committing the plan, use the **question tool** with these exact options:
141
143
  **Only after the user selects an option**, execute the corresponding action:
142
144
 
143
145
  - **User chose "Create a worktree"**:
144
- - Use `worktree_create` with `name` derived from the suggested branch slug and `type` from the plan type
145
- - Report the worktree path so the user can navigate to it
146
+ - Use `worktree_create` with `name` derived from the suggested branch slug, `type` from the plan type, and `fromBranch` set to the suggested branch name from `plan_commit`
147
+ - The tool auto-deduplicates if the branch already exists (appends `-2`, `-3`, etc.)
148
+ - Report the worktree path and **actual branch name** (may differ from suggestion if deduplicated)
146
149
  - Suggest: "Navigate to the worktree and run OpenCode with the Implement agent to begin implementation"
147
150
 
148
151
  - **User chose "Create a branch"**:
@@ -329,6 +332,8 @@ sequenceDiagram
329
332
  - `session_save` - Save session summary
330
333
  - `branch_status` - Check current git state
331
334
  - `branch_create` - Create a new branch (used during handoff to implementation)
335
+ - `worktree_create` - Create an isolated worktree for parallel development (used during handoff)
336
+ - `worktree_list` - List existing worktrees (check before creating)
332
337
  - `github_status` - Check GitHub CLI availability, auth, and detect projects
333
338
  - `github_issues` - List/filter GitHub issues for work item selection
334
339
  - `github_projects` - List GitHub Project boards and their work items
@@ -1 +1 @@
1
- {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/tools/worktree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASvD,KAAK,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;EA0H1C;AAED,eAAO,MAAM,IAAI;;;;CAiCf,CAAC;AAEH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;EAyG1C;AAED,eAAO,MAAM,IAAI;;;;;;;;CAgDf,CAAC"}
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/tools/worktree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASvD,KAAK,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;EAgJ1C;AAED,eAAO,MAAM,IAAI;;;;CAiCf,CAAC;AAEH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;EAyG1C;AAED,eAAO,MAAM,IAAI;;;;;;;;CAgDf,CAAC"}
@@ -2,7 +2,7 @@ import { tool } from "@opencode-ai/plugin";
2
2
  import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import { git } from "../utils/shell.js";
5
- import { detectWorktreeInfo } from "../utils/worktree-detect.js";
5
+ import { detectWorktreeInfo, deduplicateBranch } from "../utils/worktree-detect.js";
6
6
  const WORKTREE_ROOT = ".worktrees";
7
7
  /**
8
8
  * Factory function that creates the worktree_create tool with access
@@ -26,7 +26,9 @@ export function createCreate(client) {
26
26
  },
27
27
  async execute(args, context) {
28
28
  const { name, type, fromBranch } = args;
29
- const branchName = fromBranch || `${type}/${name}`;
29
+ let branchName = fromBranch || `${type}/${name}`;
30
+ const originalBranch = branchName;
31
+ let deduplicated = false;
30
32
  const worktreePath = path.join(context.worktree, WORKTREE_ROOT, name);
31
33
  const absoluteWorktreePath = path.resolve(worktreePath);
32
34
  // Check if we're in a git repository
@@ -58,21 +60,30 @@ Use worktree_list to see existing worktrees.`;
58
60
  try {
59
61
  await git(context.worktree, "worktree", "add", "-b", fromBranch, absoluteWorktreePath);
60
62
  }
61
- catch (error2) {
63
+ catch {
64
+ // Both failed — try deduplication
62
65
  try {
63
- await client.tui.showToast({
64
- body: {
65
- title: `Worktree: ${name}`,
66
- message: `Failed to create from branch '${fromBranch}': ${error2.message || error2}`,
67
- variant: "error",
68
- duration: 8000,
69
- },
70
- });
66
+ const uniqueBranch = await deduplicateBranch(context.worktree, fromBranch);
67
+ await git(context.worktree, "worktree", "add", "-b", uniqueBranch, absoluteWorktreePath);
68
+ branchName = uniqueBranch;
69
+ deduplicated = true;
71
70
  }
72
- catch {
73
- // Toast failure is non-fatal
71
+ catch (error3) {
72
+ try {
73
+ await client.tui.showToast({
74
+ body: {
75
+ title: `Worktree: ${name}`,
76
+ message: `Failed to create from branch '${fromBranch}': ${error3.message || error3}`,
77
+ variant: "error",
78
+ duration: 8000,
79
+ },
80
+ });
81
+ }
82
+ catch {
83
+ // Toast failure is non-fatal
84
+ }
85
+ return `\u2717 Error creating worktree from branch '${fromBranch}': ${error3.message || error3}`;
74
86
  }
75
- return `\u2717 Error creating worktree from branch '${fromBranch}': ${error2.message || error2}`;
76
87
  }
77
88
  }
78
89
  }
@@ -86,21 +97,30 @@ Use worktree_list to see existing worktrees.`;
86
97
  try {
87
98
  await git(context.worktree, "worktree", "add", absoluteWorktreePath, branchName);
88
99
  }
89
- catch (error2) {
100
+ catch {
101
+ // Both failed — try deduplication
90
102
  try {
91
- await client.tui.showToast({
92
- body: {
93
- title: `Worktree: ${name}`,
94
- message: `Failed to create: ${error2.message || error2}`,
95
- variant: "error",
96
- duration: 8000,
97
- },
98
- });
103
+ const uniqueBranch = await deduplicateBranch(context.worktree, branchName);
104
+ await git(context.worktree, "worktree", "add", "-b", uniqueBranch, absoluteWorktreePath);
105
+ branchName = uniqueBranch;
106
+ deduplicated = true;
99
107
  }
100
- catch {
101
- // Toast failure is non-fatal
108
+ catch (error3) {
109
+ try {
110
+ await client.tui.showToast({
111
+ body: {
112
+ title: `Worktree: ${name}`,
113
+ message: `Failed to create: ${error3.message || error3}`,
114
+ variant: "error",
115
+ duration: 8000,
116
+ },
117
+ });
118
+ }
119
+ catch {
120
+ // Toast failure is non-fatal
121
+ }
122
+ return `\u2717 Error creating worktree: ${error3.message || error3}`;
102
123
  }
103
- return `\u2717 Error creating worktree: ${error2.message || error2}`;
104
124
  }
105
125
  }
106
126
  }
@@ -119,10 +139,13 @@ Use worktree_list to see existing worktrees.`;
119
139
  catch {
120
140
  // Toast failure is non-fatal
121
141
  }
142
+ const dedupeNote = deduplicated
143
+ ? `\n\nNote: Branch '${originalBranch}' was unavailable. Using '${branchName}' instead.`
144
+ : "";
122
145
  return `\u2713 Created worktree successfully
123
146
 
124
147
  Branch: ${branchName}${fromLabel}
125
- Path: ${absoluteWorktreePath}
148
+ Path: ${absoluteWorktreePath}${dedupeNote}
126
149
 
127
150
  To work in this worktree:
128
151
  cd ${absoluteWorktreePath}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Finds a unique branch name by appending -2, -3, etc. if the base name exists.
3
+ * Returns the first available candidate from baseName-2 through baseName-10.
4
+ */
5
+ export declare function deduplicateBranch(cwd: string, baseName: string): Promise<string>;
1
6
  /**
2
7
  * Information about the current worktree context.
3
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"worktree-detect.d.ts","sourceRoot":"","sources":["../../src/utils/worktree-detect.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,UAAU,EAAE,OAAO,CAAC;IACpB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqC3E"}
1
+ {"version":3,"file":"worktree-detect.d.ts","sourceRoot":"","sources":["../../src/utils/worktree-detect.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOtF;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,UAAU,EAAE,OAAO,CAAC;IACpB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqC3E"}
@@ -1,5 +1,18 @@
1
1
  import * as path from "path";
2
2
  import { git } from "./shell.js";
3
+ /**
4
+ * Finds a unique branch name by appending -2, -3, etc. if the base name exists.
5
+ * Returns the first available candidate from baseName-2 through baseName-10.
6
+ */
7
+ export async function deduplicateBranch(cwd, baseName) {
8
+ for (let i = 2; i <= 10; i++) {
9
+ const candidate = `${baseName}-${i}`;
10
+ const { stdout } = await git(cwd, "branch", "--list", candidate);
11
+ if (!stdout.trim())
12
+ return candidate;
13
+ }
14
+ throw new Error(`Could not find unique branch name after 10 attempts (base: ${baseName})`);
15
+ }
3
16
  /**
4
17
  * Detect whether the current git directory is a linked worktree.
5
18
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortex-agents",
3
- "version": "4.0.8",
3
+ "version": "4.1.0",
4
4
  "description": "Supercharge OpenCode with structured workflows, intelligent agents, and automated development practices",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",