opencode-swarm-plugin 0.30.7 → 0.31.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,135 @@
1
1
  # opencode-swarm-plugin
2
2
 
3
+ ## 0.31.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`19995a6`](https://github.com/joelhooks/swarm-tools/commit/19995a68dd1283de1d13afa6fc028bd1273d1b27) Thanks [@joelhooks](https://github.com/joelhooks)! - ## 🐝 Squashed the BigInt Date Bug
8
+
9
+ PGLite returns BIGINT columns as JavaScript `bigint` type. The `Date` constructor throws when given a bigint:
10
+
11
+ ```javascript
12
+ new Date(1734628445371n); // TypeError: Cannot convert a BigInt value to a number
13
+ ```
14
+
15
+ This caused `Invalid Date` errors in all hive operations (`hive_query`, `hive_create`, etc).
16
+
17
+ **Fix:** Wrap timestamps in `Number()` before passing to `Date`:
18
+
19
+ ```typescript
20
+ // Before (broken)
21
+ new Date(cell.created_at);
22
+
23
+ // After (works with both number and bigint)
24
+ new Date(Number(cell.created_at));
25
+ ```
26
+
27
+ **Files fixed:**
28
+
29
+ - `swarm-mail/src/hive/jsonl.ts` - JSONL export functions
30
+ - `opencode-swarm-plugin/src/hive.ts` - `formatCellForOutput()`
31
+
32
+ **Tests added:** 6 new tests covering bigint date handling edge cases.
33
+
34
+ - Updated dependencies [[`19995a6`](https://github.com/joelhooks/swarm-tools/commit/19995a68dd1283de1d13afa6fc028bd1273d1b27)]:
35
+ - swarm-mail@1.1.1
36
+
37
+ ## 0.31.0
38
+
39
+ ### Minor Changes
40
+
41
+ - [`39593d7`](https://github.com/joelhooks/swarm-tools/commit/39593d7ee817c683ad1877af52ad5f2ca140c4e2) Thanks [@joelhooks](https://github.com/joelhooks)! - ## Smart ID Resolution: Git-Style Partial Hashes for Hive
42
+
43
+ ```
44
+ ┌─────────────────────────────────────────────────────────────┐
45
+ │ BEFORE: hive_close(id="opencode-swarm-monorepo-lf2p4u-mjcadqq3fb9") │
46
+ │ AFTER: hive_close(id="mjcadqq3fb9") │
47
+ └─────────────────────────────────────────────────────────────┘
48
+ ```
49
+
50
+ Cell IDs got long. Now you can use just the hash portion.
51
+
52
+ **What changed:**
53
+
54
+ ### swarm-mail
55
+
56
+ - Added `resolvePartialId(adapter, partialId)` to resolve partial hashes to full cell IDs
57
+ - Supports exact match, prefix match, suffix match, and substring match
58
+ - Returns helpful error messages for ambiguous matches ("Found 3 cells matching 'abc': ...")
59
+ - 36 new tests covering all resolution scenarios
60
+
61
+ ### opencode-swarm-plugin
62
+
63
+ - `hive_update`, `hive_close`, `hive_start` now accept partial IDs
64
+ - Resolution happens transparently - full ID returned in response
65
+ - Backward compatible - full IDs still work
66
+
67
+ **JSONL Fix (bonus):**
68
+
69
+ - `serializeToJSONL()` now adds trailing newline for POSIX compliance
70
+ - Prevents parse errors when appending to existing files
71
+
72
+ **Why it matters:**
73
+
74
+ - Less typing, fewer copy-paste errors
75
+ - Matches git's partial SHA workflow (muscle memory)
76
+ - Ambiguous matches fail fast with actionable error messages
77
+
78
+ > "The best interface is no interface" - Golden Krishna
79
+ > (But if you must have one, make it forgive typos)
80
+
81
+ ***
82
+
83
+ ## Auto-Sync at Key Events
84
+
85
+ ```
86
+ ┌─────────────────────────────────────────┐
87
+ │ hive_create_epic → auto-sync │
88
+ │ swarm_complete → auto-sync │
89
+ │ process.exit → safety net sync │
90
+ └─────────────────────────────────────────┘
91
+ ```
92
+
93
+ Cells no longer get lost when processes exit unexpectedly.
94
+
95
+ **What changed:**
96
+
97
+ - `hive_create_epic` syncs after creating epic + subtasks (workers can see them immediately)
98
+ - `swarm_complete` syncs before worker exits (completed work persists)
99
+ - `process.on('beforeExit')` hook catches any remaining dirty cells
100
+
101
+ **Why it matters:**
102
+
103
+ - Spawned workers couldn't see cells created by coordinator (race condition)
104
+ - Worker crashes could lose completed work
105
+ - Now the lazy-write pattern has strategic checkpoints
106
+
107
+ ***
108
+
109
+ ## Removed Arbitrary Subtask Limits
110
+
111
+ ```
112
+ BEFORE: max_subtasks capped at 10 (why tho?)
113
+ AFTER: no limit - LLM decides based on task complexity
114
+ ```
115
+
116
+ **What changed:**
117
+
118
+ - Removed `.max(10)` from `swarm_decompose` and `swarm_plan_prompt`
119
+ - `max_subtasks` is now optional with no default
120
+ - Prompt says "as many as needed" instead of "2-10"
121
+
122
+ **Why it matters:**
123
+
124
+ - Complex epics need more than 10 subtasks
125
+ - Arbitrary limits force awkward decomposition
126
+ - Trust the coordinator to make good decisions
127
+
128
+ ### Patch Changes
129
+
130
+ - Updated dependencies [[`39593d7`](https://github.com/joelhooks/swarm-tools/commit/39593d7ee817c683ad1877af52ad5f2ca140c4e2)]:
131
+ - swarm-mail@1.1.0
132
+
3
133
  ## 0.30.7
4
134
 
5
135
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"hive.d.ts","sourceRoot":"","sources":["../src/hive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hive.d.ts","sourceRoot":"","sources":["../src/hive.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -967,7 +967,7 @@ export declare const allTools: {
967
967
  "risk-based": "risk-based";
968
968
  auto: "auto";
969
969
  }>>;
970
- max_subtasks: import("zod").ZodDefault<import("zod").ZodNumber>;
970
+ max_subtasks: import("zod").ZodOptional<import("zod").ZodNumber>;
971
971
  context: import("zod").ZodOptional<import("zod").ZodString>;
972
972
  query_cass: import("zod").ZodOptional<import("zod").ZodBoolean>;
973
973
  cass_limit: import("zod").ZodOptional<import("zod").ZodNumber>;
@@ -975,8 +975,8 @@ export declare const allTools: {
975
975
  };
976
976
  execute(args: {
977
977
  task: string;
978
- max_subtasks: number;
979
978
  strategy?: "file-based" | "feature-based" | "risk-based" | "auto" | undefined;
979
+ max_subtasks?: number | undefined;
980
980
  context?: string | undefined;
981
981
  query_cass?: boolean | undefined;
982
982
  cass_limit?: number | undefined;
@@ -987,14 +987,14 @@ export declare const allTools: {
987
987
  description: string;
988
988
  args: {
989
989
  task: import("zod").ZodString;
990
- max_subtasks: import("zod").ZodDefault<import("zod").ZodNumber>;
990
+ max_subtasks: import("zod").ZodOptional<import("zod").ZodNumber>;
991
991
  context: import("zod").ZodOptional<import("zod").ZodString>;
992
992
  query_cass: import("zod").ZodOptional<import("zod").ZodBoolean>;
993
993
  cass_limit: import("zod").ZodOptional<import("zod").ZodNumber>;
994
994
  };
995
995
  execute(args: {
996
996
  task: string;
997
- max_subtasks: number;
997
+ max_subtasks?: number | undefined;
998
998
  context?: string | undefined;
999
999
  query_cass?: boolean | undefined;
1000
1000
  cass_limit?: number | undefined;
@@ -1014,7 +1014,7 @@ export declare const allTools: {
1014
1014
  args: {
1015
1015
  task: import("zod").ZodString;
1016
1016
  context: import("zod").ZodOptional<import("zod").ZodString>;
1017
- max_subtasks: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
1017
+ max_subtasks: import("zod").ZodOptional<import("zod").ZodNumber>;
1018
1018
  strategy: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEnum<{
1019
1019
  "file-based": "file-based";
1020
1020
  "feature-based": "feature-based";
@@ -1025,10 +1025,10 @@ export declare const allTools: {
1025
1025
  };
1026
1026
  execute(args: {
1027
1027
  task: string;
1028
- max_subtasks: number;
1029
1028
  strategy: "file-based" | "feature-based" | "risk-based" | "auto";
1030
1029
  query_cass: boolean;
1031
1030
  context?: string | undefined;
1031
+ max_subtasks?: number | undefined;
1032
1032
  }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
1033
1033
  };
1034
1034
  readonly swarm_plan_interactive: {
package/dist/index.js CHANGED
@@ -27084,7 +27084,8 @@ import {
27084
27084
  FlushManager,
27085
27085
  importFromJSONL,
27086
27086
  syncMemories,
27087
- getSwarmMail
27087
+ getSwarmMail,
27088
+ resolvePartialId
27088
27089
  } from "swarm-mail";
27089
27090
  import { existsSync, readFileSync } from "node:fs";
27090
27091
  import { join } from "node:path";
@@ -27935,6 +27936,43 @@ async function importJsonlToPGLite(projectPath) {
27935
27936
  return { imported, updated, errors: errors3 };
27936
27937
  }
27937
27938
  var adapterCache = new Map;
27939
+ var exitHookRegistered = false;
27940
+ var exitHookRunning = false;
27941
+ function registerExitHook() {
27942
+ if (exitHookRegistered) {
27943
+ return;
27944
+ }
27945
+ exitHookRegistered = true;
27946
+ process.on("beforeExit", async (code) => {
27947
+ if (exitHookRunning) {
27948
+ return;
27949
+ }
27950
+ exitHookRunning = true;
27951
+ try {
27952
+ const flushPromises = [];
27953
+ for (const [projectKey, adapter] of adapterCache.entries()) {
27954
+ const flushPromise = (async () => {
27955
+ try {
27956
+ ensureHiveDirectory(projectKey);
27957
+ const flushManager = new FlushManager({
27958
+ adapter,
27959
+ projectKey,
27960
+ outputPath: `${projectKey}/.hive/issues.jsonl`
27961
+ });
27962
+ await flushManager.flush();
27963
+ } catch (error45) {
27964
+ console.warn(`[hive exit hook] Failed to flush ${projectKey}:`, error45 instanceof Error ? error45.message : String(error45));
27965
+ }
27966
+ })();
27967
+ flushPromises.push(flushPromise);
27968
+ }
27969
+ await Promise.all(flushPromises);
27970
+ } finally {
27971
+ exitHookRunning = false;
27972
+ }
27973
+ });
27974
+ }
27975
+ registerExitHook();
27938
27976
  async function getHiveAdapter(projectKey) {
27939
27977
  if (adapterCache.has(projectKey)) {
27940
27978
  return adapterCache.get(projectKey);
@@ -27980,9 +28018,9 @@ function formatCellForOutput(adapterCell) {
27980
28018
  status: adapterCell.status,
27981
28019
  priority: adapterCell.priority,
27982
28020
  issue_type: adapterCell.type,
27983
- created_at: new Date(adapterCell.created_at).toISOString(),
27984
- updated_at: new Date(adapterCell.updated_at).toISOString(),
27985
- closed_at: adapterCell.closed_at ? new Date(adapterCell.closed_at).toISOString() : undefined,
28021
+ created_at: new Date(Number(adapterCell.created_at)).toISOString(),
28022
+ updated_at: new Date(Number(adapterCell.updated_at)).toISOString(),
28023
+ closed_at: adapterCell.closed_at ? new Date(Number(adapterCell.closed_at)).toISOString() : undefined,
27986
28024
  parent_id: adapterCell.parent_id || undefined,
27987
28025
  dependencies: [],
27988
28026
  metadata: {}
@@ -28089,6 +28127,17 @@ var hive_create_epic = tool({
28089
28127
  console.warn("[hive_create_epic] Failed to emit DecompositionGeneratedEvent:", error45);
28090
28128
  }
28091
28129
  }
28130
+ try {
28131
+ ensureHiveDirectory(projectKey);
28132
+ const flushManager = new FlushManager({
28133
+ adapter,
28134
+ projectKey,
28135
+ outputPath: `${projectKey}/.hive/issues.jsonl`
28136
+ });
28137
+ await flushManager.flush();
28138
+ } catch (error45) {
28139
+ console.warn("[hive_create_epic] Failed to sync to JSONL:", error45);
28140
+ }
28092
28141
  return JSON.stringify(result, null, 2);
28093
28142
  } catch (error45) {
28094
28143
  const rollbackErrors = [];
@@ -28153,7 +28202,7 @@ var hive_query = tool({
28153
28202
  var hive_update = tool({
28154
28203
  description: "Update cell status/description",
28155
28204
  args: {
28156
- id: tool.schema.string().describe("Cell ID"),
28205
+ id: tool.schema.string().describe("Cell ID or partial hash"),
28157
28206
  status: tool.schema.enum(["open", "in_progress", "blocked", "closed"]).optional().describe("New status"),
28158
28207
  description: tool.schema.string().optional().describe("New description"),
28159
28208
  priority: tool.schema.number().min(0).max(3).optional().describe("New priority")
@@ -28163,27 +28212,34 @@ var hive_update = tool({
28163
28212
  const projectKey = getHiveWorkingDirectory();
28164
28213
  const adapter = await getHiveAdapter(projectKey);
28165
28214
  try {
28215
+ const cellId = await resolvePartialId(adapter, projectKey, validated.id) || validated.id;
28166
28216
  let cell;
28167
28217
  if (validated.status) {
28168
- cell = await adapter.changeCellStatus(projectKey, validated.id, validated.status);
28218
+ cell = await adapter.changeCellStatus(projectKey, cellId, validated.status);
28169
28219
  }
28170
28220
  if (validated.description !== undefined || validated.priority !== undefined) {
28171
- cell = await adapter.updateCell(projectKey, validated.id, {
28221
+ cell = await adapter.updateCell(projectKey, cellId, {
28172
28222
  description: validated.description,
28173
28223
  priority: validated.priority
28174
28224
  });
28175
28225
  } else if (!validated.status) {
28176
- const existingCell = await adapter.getCell(projectKey, validated.id);
28226
+ const existingCell = await adapter.getCell(projectKey, cellId);
28177
28227
  if (!existingCell) {
28178
28228
  throw new HiveError(`Cell not found: ${validated.id}`, "hive_update");
28179
28229
  }
28180
28230
  cell = existingCell;
28181
28231
  }
28182
- await adapter.markDirty(projectKey, validated.id);
28232
+ await adapter.markDirty(projectKey, cellId);
28183
28233
  const formatted = formatCellForOutput(cell);
28184
28234
  return JSON.stringify(formatted, null, 2);
28185
28235
  } catch (error45) {
28186
28236
  const message = error45 instanceof Error ? error45.message : String(error45);
28237
+ if (message.includes("Ambiguous hash")) {
28238
+ throw new HiveError(`Ambiguous ID '${validated.id}': multiple cells match. Please provide more characters.`, "hive_update");
28239
+ }
28240
+ if (message.includes("Bead not found") || message.includes("Cell not found")) {
28241
+ throw new HiveError(`No cell found matching ID '${validated.id}'`, "hive_update");
28242
+ }
28187
28243
  throw new HiveError(`Failed to update cell: ${message}`, "hive_update");
28188
28244
  }
28189
28245
  }
@@ -28191,7 +28247,7 @@ var hive_update = tool({
28191
28247
  var hive_close = tool({
28192
28248
  description: "Close a cell with reason",
28193
28249
  args: {
28194
- id: tool.schema.string().describe("Cell ID"),
28250
+ id: tool.schema.string().describe("Cell ID or partial hash"),
28195
28251
  reason: tool.schema.string().describe("Completion reason")
28196
28252
  },
28197
28253
  async execute(args, ctx) {
@@ -28199,11 +28255,18 @@ var hive_close = tool({
28199
28255
  const projectKey = getHiveWorkingDirectory();
28200
28256
  const adapter = await getHiveAdapter(projectKey);
28201
28257
  try {
28202
- const cell = await adapter.closeCell(projectKey, validated.id, validated.reason);
28203
- await adapter.markDirty(projectKey, validated.id);
28258
+ const cellId = await resolvePartialId(adapter, projectKey, validated.id) || validated.id;
28259
+ const cell = await adapter.closeCell(projectKey, cellId, validated.reason);
28260
+ await adapter.markDirty(projectKey, cellId);
28204
28261
  return `Closed ${cell.id}: ${validated.reason}`;
28205
28262
  } catch (error45) {
28206
28263
  const message = error45 instanceof Error ? error45.message : String(error45);
28264
+ if (message.includes("Ambiguous hash")) {
28265
+ throw new HiveError(`Ambiguous ID '${validated.id}': multiple cells match. Please provide more characters.`, "hive_close");
28266
+ }
28267
+ if (message.includes("Bead not found") || message.includes("Cell not found")) {
28268
+ throw new HiveError(`No cell found matching ID '${validated.id}'`, "hive_close");
28269
+ }
28207
28270
  throw new HiveError(`Failed to close cell: ${message}`, "hive_close");
28208
28271
  }
28209
28272
  }
@@ -28211,17 +28274,24 @@ var hive_close = tool({
28211
28274
  var hive_start = tool({
28212
28275
  description: "Mark a cell as in-progress (shortcut for update --status in_progress)",
28213
28276
  args: {
28214
- id: tool.schema.string().describe("Cell ID")
28277
+ id: tool.schema.string().describe("Cell ID or partial hash")
28215
28278
  },
28216
28279
  async execute(args, ctx) {
28217
28280
  const projectKey = getHiveWorkingDirectory();
28218
28281
  const adapter = await getHiveAdapter(projectKey);
28219
28282
  try {
28220
- const cell = await adapter.changeCellStatus(projectKey, args.id, "in_progress");
28221
- await adapter.markDirty(projectKey, args.id);
28283
+ const cellId = await resolvePartialId(adapter, projectKey, args.id) || args.id;
28284
+ const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
28285
+ await adapter.markDirty(projectKey, cellId);
28222
28286
  return `Started: ${cell.id}`;
28223
28287
  } catch (error45) {
28224
28288
  const message = error45 instanceof Error ? error45.message : String(error45);
28289
+ if (message.includes("Ambiguous hash")) {
28290
+ throw new HiveError(`Ambiguous ID '${args.id}': multiple cells match. Please provide more characters.`, "hive_start");
28291
+ }
28292
+ if (message.includes("Bead not found") || message.includes("Cell not found")) {
28293
+ throw new HiveError(`No cell found matching ID '${args.id}'`, "hive_start");
28294
+ }
28225
28295
  throw new HiveError(`Failed to start cell: ${message}`, "hive_start");
28226
28296
  }
28227
28297
  }
@@ -30685,7 +30755,7 @@ Agents MUST update their bead status as they work. No silent progress.
30685
30755
 
30686
30756
  ## Requirements
30687
30757
 
30688
- 1. **Break into 2-{max_subtasks} independent subtasks** that can run in parallel
30758
+ 1. **Break into independent subtasks** that can run in parallel (as many as needed)
30689
30759
  2. **Assign files** - each subtask must specify which files it will modify
30690
30760
  3. **No file overlap** - files cannot appear in multiple subtasks (they get exclusive locks)
30691
30761
  4. **Order by dependency** - if subtask B needs subtask A's output, A must come first in the array
@@ -30758,7 +30828,7 @@ Agents MUST update their bead status as they work. No silent progress.
30758
30828
 
30759
30829
  ## Requirements
30760
30830
 
30761
- 1. **Break into 2-{max_subtasks} independent subtasks** that can run in parallel
30831
+ 1. **Break into independent subtasks** that can run in parallel (as many as needed)
30762
30832
  2. **Assign files** - each subtask must specify which files it will modify
30763
30833
  3. **No file overlap** - files cannot appear in multiple subtasks (they get exclusive locks)
30764
30834
  4. **Order by dependency** - if subtask B needs subtask A's output, A must come first in the array
@@ -30924,10 +30994,10 @@ var swarm_decompose = tool({
30924
30994
  description: "Generate decomposition prompt for breaking task into parallelizable subtasks. Optionally queries CASS for similar past tasks.",
30925
30995
  args: {
30926
30996
  task: tool.schema.string().min(1).describe("Task description to decompose"),
30927
- max_subtasks: tool.schema.number().int().min(2).max(10).default(5).describe("Maximum number of subtasks (default: 5)"),
30997
+ max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
30928
30998
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
30929
30999
  query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
30930
- cass_limit: tool.schema.number().int().min(1).max(10).optional().describe("Max CASS results to include (default: 3)")
31000
+ cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)")
30931
31001
  },
30932
31002
  async execute(args) {
30933
31003
  const { formatMemoryQueryForDecomposition: formatMemoryQueryForDecomposition2 } = await Promise.resolve().then(() => (init_learning(), exports_learning));
@@ -31055,7 +31125,7 @@ var swarm_delegate_planning = tool({
31055
31125
  args: {
31056
31126
  task: tool.schema.string().min(1).describe("The task to decompose"),
31057
31127
  context: tool.schema.string().optional().describe("Additional context to include"),
31058
- max_subtasks: tool.schema.number().int().min(2).max(10).optional().default(5).describe("Maximum number of subtasks (default: 5)"),
31128
+ max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
31059
31129
  strategy: tool.schema.enum(["auto", "file-based", "feature-based", "risk-based"]).optional().default("auto").describe("Decomposition strategy (default: auto-detect)"),
31060
31130
  query_cass: tool.schema.boolean().optional().default(true).describe("Query CASS for similar past tasks (default: true)")
31061
31131
  },
@@ -34356,6 +34426,21 @@ This will be recorded as a negative learning signal.`;
34356
34426
  }
34357
34427
  }, null, 2);
34358
34428
  }
34429
+ let syncSuccess = false;
34430
+ let syncError;
34431
+ try {
34432
+ const previousWorkingDir = getHiveWorkingDirectory();
34433
+ setHiveWorkingDirectory(args.project_key);
34434
+ try {
34435
+ const syncResult = await hive_sync.execute({ auto_pull: false }, _ctx);
34436
+ syncSuccess = !syncResult.includes("error");
34437
+ } finally {
34438
+ setHiveWorkingDirectory(previousWorkingDir);
34439
+ }
34440
+ } catch (error45) {
34441
+ syncError = error45 instanceof Error ? error45.message : String(error45);
34442
+ console.warn(`[swarm_complete] Auto-sync failed (non-fatal): ${syncError}`);
34443
+ }
34359
34444
  try {
34360
34445
  const epicId3 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
34361
34446
  const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
@@ -34441,6 +34526,8 @@ This will be recorded as a negative learning signal.`;
34441
34526
  bead_id: args.bead_id,
34442
34527
  closed: true,
34443
34528
  reservations_released: true,
34529
+ synced: syncSuccess,
34530
+ sync_error: syncError,
34444
34531
  message_sent: messageSent,
34445
34532
  message_error: messageError,
34446
34533
  agent_registration: {
@@ -35117,7 +35204,7 @@ Agents MUST update their cell status as they work. No silent progress.
35117
35204
 
35118
35205
  ## Requirements
35119
35206
 
35120
- 1. **Break into 2-{max_subtasks} independent subtasks** that can run in parallel
35207
+ 1. **Break into independent subtasks** that can run in parallel (as many as needed)
35121
35208
  2. **Assign files** - each subtask must specify which files it will modify
35122
35209
  3. **No file overlap** - files cannot appear in multiple subtasks (they get exclusive locks)
35123
35210
  4. **Order by dependency** - if subtask B needs subtask A's output, A must come first in the array
@@ -35745,10 +35832,10 @@ var swarm_plan_prompt = tool({
35745
35832
  args: {
35746
35833
  task: tool.schema.string().min(1).describe("Task description to decompose"),
35747
35834
  strategy: tool.schema.enum(["file-based", "feature-based", "risk-based", "auto"]).optional().describe("Decomposition strategy (default: auto-detect)"),
35748
- max_subtasks: tool.schema.number().int().min(2).max(10).default(5).describe("Maximum number of subtasks (default: 5)"),
35835
+ max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
35749
35836
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
35750
35837
  query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
35751
- cass_limit: tool.schema.number().int().min(1).max(10).optional().describe("Max CASS results to include (default: 3)"),
35838
+ cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)"),
35752
35839
  include_skills: tool.schema.boolean().optional().describe("Include available skills in context (default: true)")
35753
35840
  },
35754
35841
  async execute(args) {