opencode-swarm 7.110.2 → 7.111.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.
@@ -12,7 +12,7 @@ import {
12
12
  detectPosixWrites,
13
13
  detectWindowsWrites,
14
14
  resolveWriteTargets
15
- } from "./index-smk3st51.js";
15
+ } from "./index-7xfh4k71.js";
16
16
  import {
17
17
  checkFileAuthority,
18
18
  classifyFile,
@@ -245,27 +245,48 @@ async function provisionWorktree(directory, id, sessionId, options) {
245
245
  }
246
246
  if (current.path)
247
247
  entries.push(current);
248
- const branchIsActiveSomewhere = entries.some((e) => e.branch === `refs/heads/${branchName}`);
249
248
  const expectedPathIsRegistered = entries.some((e) => e.path === expectedPath);
250
- if (branchIsActiveSomewhere || expectedPathIsRegistered) {
249
+ const branchIsActiveAtExpectedPath = entries.some((e) => e.branch === `refs/heads/${branchName}` && e.path === expectedPath);
250
+ const branchIsActiveElsewhere = entries.some((e) => e.branch === `refs/heads/${branchName}` && e.path !== expectedPath);
251
+ if (branchIsActiveElsewhere || expectedPathIsRegistered && !branchIsActiveAtExpectedPath) {
251
252
  return {
252
253
  error: `Branch already exists and worktree is active: ${branchName} (owned by another session)`
253
254
  };
254
255
  }
255
- console.warn(`[swarm] adopting existing branch ${branchName} (stale worktree)`);
256
- const adoptResult = await runGit(["worktree", "add", "-f", worktreePath, branchName], directory);
257
- if (adoptResult.exitCode !== 0) {
256
+ const aheadResult = await runGit(["rev-list", "--count", `HEAD..${branchName}`], directory);
257
+ if (aheadResult.exitCode !== 0) {
258
258
  return {
259
- error: `Failed to adopt existing worktree: ${adoptResult.stderr.trim() || adoptResult.stdout.trim()}`
259
+ error: `Failed to inspect stale worktree branch: ${aheadResult.stderr.trim() || aheadResult.stdout.trim()}`
260
260
  };
261
261
  }
262
- return {
263
- worktreePath,
264
- branchName,
265
- purpose: options.purpose,
266
- id,
267
- sessionId
268
- };
262
+ const aheadCount = Number.parseInt(aheadResult.stdout.trim(), 10);
263
+ if (!Number.isFinite(aheadCount) || aheadCount > 0) {
264
+ return {
265
+ error: `Branch already exists and has unmerged commits: ${branchName}`
266
+ };
267
+ }
268
+ if (branchIsActiveAtExpectedPath) {
269
+ const clean = await isCleanWorktree(worktreePath);
270
+ if (!clean) {
271
+ return {
272
+ error: `Branch already exists and expected worktree is dirty: ${branchName}`
273
+ };
274
+ }
275
+ const removeResult = await removeWorktree(worktreePath, directory, {
276
+ force: true,
277
+ worktreeDir: options.worktreeDir
278
+ });
279
+ if (!("success" in removeResult)) {
280
+ return { error: removeResult.error };
281
+ }
282
+ }
283
+ const deleteResult = await runGit(["branch", "-d", branchName], directory);
284
+ if (deleteResult.exitCode !== 0) {
285
+ return {
286
+ error: `Failed to delete stale worktree branch: ${deleteResult.stderr.trim() || deleteResult.stdout.trim()}`
287
+ };
288
+ }
289
+ await runGit(["worktree", "prune"], directory);
269
290
  }
270
291
  const addResult = await runGit(["worktree", "add", "-b", branchName, worktreePath, "HEAD"], directory);
271
292
  if (addResult.exitCode !== 0) {
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-4k3gh2nz.js";
4
+ } from "./index-9ptp9kky.js";
5
5
  import {
6
6
  handleGuardrailLog
7
7
  } from "./index-5rfxzgmt.js";
@@ -24,6 +24,7 @@ import {
24
24
  handleBenchmarkCommand,
25
25
  handleBrainstormCommand,
26
26
  handleCheckpointCommand,
27
+ handleCiSimulateCommand,
27
28
  handleClarifyCommand,
28
29
  handleCloseCommand,
29
30
  handleCodebaseReviewCommand,
@@ -80,7 +81,7 @@ import {
80
81
  handleWriteRetroCommand,
81
82
  normalizeSwarmCommandInput,
82
83
  resolveCommand
83
- } from "./index-smk3st51.js";
84
+ } from "./index-7xfh4k71.js";
84
85
  import"./index-53z1afgh.js";
85
86
  import"./index-c8s9a3zh.js";
86
87
  import"./index-xddysq89.js";
@@ -104,7 +105,7 @@ import"./index-jt58s751.js";
104
105
  import"./index-wvrj16f0.js";
105
106
  import"./index-q1exe2b3.js";
106
107
  import"./index-vzzt3ygr.js";
107
- import"./index-dm35e55e.js";
108
+ import"./index-dnbca696.js";
108
109
  import"./index-r3j3458j.js";
109
110
  import"./index-jtqkh8jf.js";
110
111
  import"./index-5e4e2hvv.js";
@@ -407,6 +408,7 @@ export {
407
408
  handleCodebaseReviewCommand,
408
409
  handleCloseCommand,
409
410
  handleClarifyCommand,
411
+ handleCiSimulateCommand,
410
412
  handleCheckpointCommand,
411
413
  handleBrainstormCommand,
412
414
  handleBenchmarkCommand,
package/dist/cli/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  getPluginLockFilePaths,
8
8
  package_default,
9
9
  resolveCommand
10
- } from "./index-smk3st51.js";
10
+ } from "./index-7xfh4k71.js";
11
11
  import"./index-53z1afgh.js";
12
12
  import"./index-c8s9a3zh.js";
13
13
  import"./index-xddysq89.js";
@@ -29,7 +29,7 @@ import"./index-jt58s751.js";
29
29
  import"./index-wvrj16f0.js";
30
30
  import"./index-q1exe2b3.js";
31
31
  import"./index-vzzt3ygr.js";
32
- import"./index-dm35e55e.js";
32
+ import"./index-dnbca696.js";
33
33
  import"./index-r3j3458j.js";
34
34
  import"./index-jtqkh8jf.js";
35
35
  import"./index-5e4e2hvv.js";
@@ -0,0 +1,16 @@
1
+ import * as fs from 'node:fs';
2
+ type RunResult = {
3
+ exitCode: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ stdoutTruncated?: boolean;
7
+ stderrTruncated?: boolean;
8
+ };
9
+ declare function runCommand(cmd: string[], cwd: string, timeout: number): Promise<RunResult>;
10
+ export declare const _internals: {
11
+ runCommand: typeof runCommand;
12
+ now: () => number;
13
+ mkdirSync: typeof fs.mkdirSync;
14
+ };
15
+ export declare function handleCiSimulateCommand(directory: string, args: string[]): Promise<string>;
16
+ export {};
@@ -7,6 +7,7 @@ export { handleAutoProceedCommand } from './auto-proceed';
7
7
  export { handleBenchmarkCommand } from './benchmark';
8
8
  export { handleBrainstormCommand } from './brainstorm';
9
9
  export { handleCheckpointCommand } from './checkpoint';
10
+ export { handleCiSimulateCommand } from './ci-simulate';
10
11
  export { handleClarifyCommand } from './clarify';
11
12
  export { handleCloseCommand } from './close';
12
13
  export { handleCodebaseReviewCommand } from './codebase-review';
@@ -10,6 +10,15 @@
10
10
  * /swarm pr status → show session subscriptions
11
11
  */
12
12
  import { listActive } from '../background/pr-subscriptions.js';
13
+ type MergeGroupRun = {
14
+ databaseId: number;
15
+ headBranch: string;
16
+ status: string;
17
+ conclusion: string | null;
18
+ url: string;
19
+ displayTitle?: string;
20
+ name?: string;
21
+ };
13
22
  /**
14
23
  * Format an epoch-ms timestamp as a human-friendly relative time string.
15
24
  *
@@ -17,12 +26,19 @@ import { listActive } from '../background/pr-subscriptions.js';
17
26
  * uses the largest whole unit (seconds, minutes, hours, or days).
18
27
  */
19
28
  declare function formatRelativeTime(epochMs: number): string;
29
+ declare function parseMergeGroupRuns(raw: string, prNumber: number): MergeGroupRun[];
30
+ declare function listMergeGroupRuns(directory: string, repoFullName: string, prNumber: number): Promise<{
31
+ runs: MergeGroupRun[];
32
+ error?: string;
33
+ }>;
20
34
  /**
21
35
  * Exposed for unit testing via _internals.
22
36
  */
23
37
  export declare const _internals: {
24
38
  formatRelativeTime: typeof formatRelativeTime;
25
39
  listActive: typeof listActive;
40
+ listMergeGroupRuns: typeof listMergeGroupRuns;
41
+ parseMergeGroupRuns: typeof parseMergeGroupRuns;
26
42
  };
27
43
  /**
28
44
  * Show PR monitor subscription status for the current session.
@@ -548,6 +548,14 @@ export declare const COMMAND_REGISTRY: {
548
548
  readonly aliasOf: "pr status";
549
549
  readonly deprecated: true;
550
550
  };
551
+ readonly 'ci-simulate': {
552
+ readonly handler: (ctx: CommandContext) => Promise<string>;
553
+ readonly description: "Create a temporary merge-result worktree and run CI before merge queue entry";
554
+ readonly args: "[--base origin/main] [--head <ref>]";
555
+ readonly details: "Creates a detached temporary worktree under .swarm/ci-simulate from the base ref, merges the current worktree HEAD (or --head ref), runs fixed local CI gates (typecheck, Biome CI, build, unit/integration/security/smoke tests, drift check), then removes the worktree and prunes metadata. Intended as a pre-queue merge_group simulation helper.";
556
+ readonly category: "agent";
557
+ readonly toolPolicy: "agent";
558
+ };
551
559
  readonly 'deep-dive': {
552
560
  readonly handler: (ctx: CommandContext) => CommandResult;
553
561
  readonly description: "Launch deep codebase audit with parallel explorer waves, dual reviewers, and critic challenge [scope]";
@@ -85,4 +85,5 @@ export declare function dispatchFullAutoOversight(input: DispatchFullAutoOversig
85
85
  */
86
86
  export declare const _internals: {
87
87
  resetSequence: () => void;
88
+ sleep: (ms: number) => Promise<void>;
88
89
  };
@@ -83,6 +83,8 @@ interface MessageWithParts {
83
83
  parts: MessagePart[];
84
84
  }
85
85
  declare function resolveDelegatedPlanTaskId(args: Record<string, unknown>, knownPlanTaskIds?: ReadonlySet<string>): string | null;
86
+ export declare function hasReviewedTaskRows(output: string): boolean;
87
+ export declare function parseReviewedTaskIdsFromSetDispatchOutput(output: string): string[];
86
88
  declare function buildParallelExecutionGuidance(directory: string | undefined, sessionID: string, session: AgentSessionState): Promise<string | null>;
87
89
  /**
88
90
  * Resolves the correct task ID for evidence recording by chaining: