sequant 1.10.0 → 1.10.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.
@@ -107,8 +107,9 @@ export function getWorktreeChangedFiles(worktreePath) {
107
107
  /**
108
108
  * Create or reuse a worktree for an issue
109
109
  * @param baseBranch - Optional branch to use as base instead of origin/main (for chain mode)
110
+ * @param chainMode - If true and branch exists, rebase onto baseBranch instead of using as-is
110
111
  */
111
- async function ensureWorktree(issueNumber, title, verbose, packageManager, baseBranch) {
112
+ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseBranch, chainMode) {
112
113
  const gitRoot = getGitRoot();
113
114
  if (!gitRoot) {
114
115
  console.log(chalk.red(" ❌ Not in a git repository"));
@@ -129,6 +130,7 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
129
130
  path: existingPath,
130
131
  branch,
131
132
  existed: true,
133
+ rebased: false,
132
134
  };
133
135
  }
134
136
  // Check if branch exists (but no worktree)
@@ -172,11 +174,16 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
172
174
  }
173
175
  // Create the worktree
174
176
  let createResult;
177
+ let needsRebase = false;
175
178
  if (branchExists) {
176
179
  // Use existing branch
177
180
  createResult = spawnSync("git", ["worktree", "add", worktreePath, branch], {
178
181
  stdio: "pipe",
179
182
  });
183
+ // In chain mode with existing branch, mark for rebase onto previous chain link
184
+ if (chainMode && baseBranch) {
185
+ needsRebase = true;
186
+ }
180
187
  }
181
188
  else {
182
189
  // Create new branch from base reference (origin/main or previous branch in chain)
@@ -187,6 +194,39 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
187
194
  console.log(chalk.red(` ❌ Failed to create worktree: ${error}`));
188
195
  return null;
189
196
  }
197
+ // Rebase existing branch onto chain base if needed
198
+ let rebased = false;
199
+ if (needsRebase) {
200
+ if (verbose) {
201
+ console.log(chalk.gray(` 🔄 Rebasing existing branch onto previous chain link (${baseRef})...`));
202
+ }
203
+ const rebaseResult = spawnSync("git", ["-C", worktreePath, "rebase", baseRef], {
204
+ stdio: "pipe",
205
+ });
206
+ if (rebaseResult.status !== 0) {
207
+ const rebaseError = rebaseResult.stderr.toString();
208
+ // Check if it's a conflict
209
+ if (rebaseError.includes("CONFLICT") ||
210
+ rebaseError.includes("could not apply")) {
211
+ console.log(chalk.yellow(` ⚠️ Rebase conflict detected. Aborting rebase and keeping original branch state.`));
212
+ console.log(chalk.yellow(` ℹ️ Branch ${branch} is not properly chained. Manual rebase may be required.`));
213
+ // Abort the rebase to restore branch state
214
+ spawnSync("git", ["-C", worktreePath, "rebase", "--abort"], {
215
+ stdio: "pipe",
216
+ });
217
+ }
218
+ else {
219
+ console.log(chalk.yellow(` ⚠️ Rebase failed: ${rebaseError.trim()}`));
220
+ console.log(chalk.yellow(` ℹ️ Continuing with branch in its original state.`));
221
+ }
222
+ }
223
+ else {
224
+ rebased = true;
225
+ if (verbose) {
226
+ console.log(chalk.green(` ✅ Branch rebased onto ${baseRef}`));
227
+ }
228
+ }
229
+ }
190
230
  // Copy .env.local if it exists
191
231
  const envLocalSrc = path.join(gitRoot, ".env.local");
192
232
  const envLocalDst = path.join(worktreePath, ".env.local");
@@ -225,6 +265,7 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
225
265
  path: worktreePath,
226
266
  branch,
227
267
  existed: false,
268
+ rebased,
228
269
  };
229
270
  }
230
271
  /**
@@ -236,7 +277,7 @@ async function ensureWorktrees(issues, verbose, packageManager, baseBranch) {
236
277
  const baseDisplay = baseBranch || "main";
237
278
  console.log(chalk.blue(`\n 📂 Preparing worktrees from ${baseDisplay}...`));
238
279
  for (const issue of issues) {
239
- const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, baseBranch);
280
+ const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, baseBranch, false);
240
281
  if (worktree) {
241
282
  worktrees.set(issue.number, worktree);
242
283
  }
@@ -260,7 +301,8 @@ async function ensureWorktreesChain(issues, verbose, packageManager, baseBranch)
260
301
  // First issue starts from the specified base branch (or main)
261
302
  let previousBranch = baseBranch;
262
303
  for (const issue of issues) {
263
- const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, previousBranch);
304
+ const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, previousBranch, // Chain from previous branch (or base branch for first issue)
305
+ true);
264
306
  if (worktree) {
265
307
  worktrees.set(issue.number, worktree);
266
308
  previousBranch = worktree.branch; // Next issue will branch from this
@@ -273,8 +315,13 @@ async function ensureWorktreesChain(issues, verbose, packageManager, baseBranch)
273
315
  }
274
316
  const created = Array.from(worktrees.values()).filter((w) => !w.existed).length;
275
317
  const reused = Array.from(worktrees.values()).filter((w) => w.existed).length;
318
+ const rebased = Array.from(worktrees.values()).filter((w) => w.rebased).length;
276
319
  if (created > 0 || reused > 0) {
277
- console.log(chalk.gray(` Chained worktrees: ${created} created, ${reused} reused`));
320
+ let msg = ` Chained worktrees: ${created} created, ${reused} reused`;
321
+ if (rebased > 0) {
322
+ msg += `, ${rebased} rebased`;
323
+ }
324
+ console.log(chalk.gray(msg));
278
325
  }
279
326
  // Show chain structure
280
327
  if (worktrees.size > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sequant",
3
- "version": "1.10.0",
3
+ "version": "1.10.1",
4
4
  "description": "Quantize your development workflow - Sequential AI phases with quality gates",
5
5
  "type": "module",
6
6
  "bin": {