opencode-swarm-plugin 0.31.2 → 0.31.4

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.
@@ -1,9 +1,9 @@
1
1
  $ bun build ./src/index.ts --outdir ./dist --target node --external @electric-sql/pglite --external swarm-mail && bun build ./src/plugin.ts --outfile ./dist/plugin.js --target node --external @electric-sql/pglite --external swarm-mail && tsc
2
- Bundled 812 modules in 141ms
2
+ Bundled 812 modules in 79ms
3
3
 
4
4
  index.js 1.71 MB (entry point)
5
5
 
6
- Bundled 813 modules in 37ms
6
+ Bundled 813 modules in 41ms
7
7
 
8
8
  plugin.js 1.68 MB (entry point)
9
9
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # opencode-swarm-plugin
2
2
 
3
+ ## 0.31.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`70ff3e0`](https://github.com/joelhooks/swarm-tools/commit/70ff3e054cd1991154f7631ce078798de1076ba8)]:
8
+ - swarm-mail@1.2.0
9
+
10
+ ## 0.31.3
11
+
12
+ ### Patch Changes
13
+
14
+ - [`fdddd27`](https://github.com/joelhooks/swarm-tools/commit/fdddd27f9c8627f7de2b9f108827c66c7040b049) Thanks [@joelhooks](https://github.com/joelhooks)! - ## 🐝 Short Hashes Now Welcome
15
+
16
+ The WorkerHandoff schema was too strict - it rejected short project names and partial hashes.
17
+
18
+ **Before:** Required 3+ hyphen-separated segments (regex nightmare)
19
+
20
+ ```
21
+ /^[a-z0-9]+(-[a-z0-9]+){2,}(\.[\w-]+)?$/
22
+ ```
23
+
24
+ **After:** Any non-empty string, validated at runtime via `resolvePartialId()`
25
+
26
+ Now you can use:
27
+
28
+ - Full IDs: `opencode-swarm-monorepo-lf2p4u-mjd4pjujc7e`
29
+ - Short hashes: `mjd4pjujc7e`
30
+ - Partial hashes: `mjd4pjuj`
31
+
32
+ The hive tools already had smart ID resolution - we just needed to stop blocking it at the schema level.
33
+
3
34
  ## 0.31.2
4
35
 
5
36
  ### Patch Changes
package/dist/index.js CHANGED
@@ -27478,7 +27478,7 @@ var QuerySwarmContextsArgsSchema = exports_external.object({
27478
27478
  // src/schemas/worker-handoff.ts
27479
27479
  init_zod();
27480
27480
  var WorkerHandoffContractSchema = exports_external.object({
27481
- task_id: exports_external.string().regex(/^[a-z0-9]+(-[a-z0-9]+){2,}(\.[\w-]+)?$/, "Invalid task ID format (expected: project-slug-hash with minimum 3 segments)"),
27481
+ task_id: exports_external.string().min(1, "Task ID cannot be empty"),
27482
27482
  files_owned: exports_external.array(exports_external.string()).default([]),
27483
27483
  files_readonly: exports_external.array(exports_external.string()).default([]),
27484
27484
  dependencies_completed: exports_external.array(exports_external.string()).default([]),
package/dist/plugin.js CHANGED
@@ -27451,7 +27451,7 @@ var QuerySwarmContextsArgsSchema = exports_external.object({
27451
27451
  // src/schemas/worker-handoff.ts
27452
27452
  init_zod();
27453
27453
  var WorkerHandoffContractSchema = exports_external.object({
27454
- task_id: exports_external.string().regex(/^[a-z0-9]+(-[a-z0-9]+){2,}(\.[\w-]+)?$/, "Invalid task ID format (expected: project-slug-hash with minimum 3 segments)"),
27454
+ task_id: exports_external.string().min(1, "Task ID cannot be empty"),
27455
27455
  files_owned: exports_external.array(exports_external.string()).default([]),
27456
27456
  files_readonly: exports_external.array(exports_external.string()).default([]),
27457
27457
  dependencies_completed: exports_external.array(exports_external.string()).default([]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm-plugin",
3
- "version": "0.31.2",
3
+ "version": "0.31.4",
4
4
  "description": "Multi-agent swarm coordination for OpenCode with learning capabilities, beads integration, and Agent Mail",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -39,7 +39,7 @@
39
39
  "gray-matter": "^4.0.3",
40
40
  "ioredis": "^5.4.1",
41
41
  "minimatch": "^10.1.1",
42
- "swarm-mail": "1.1.1",
42
+ "swarm-mail": "1.2.0",
43
43
  "zod": "4.1.8"
44
44
  },
45
45
  "devDependencies": {
@@ -662,6 +662,39 @@ describe("beads integration", () => {
662
662
  }
663
663
  });
664
664
 
665
+ it("short hashes work with all ID-taking tools", async () => {
666
+ // Use last 6-8 chars of hash (or full hash if short)
667
+ const shortHash = hash.substring(Math.max(0, hash.length - 8));
668
+
669
+ try {
670
+ // Test hive_update
671
+ await hive_update.execute(
672
+ { id: shortHash, description: "Updated via short hash" },
673
+ mockContext,
674
+ );
675
+
676
+ // Test hive_start
677
+ await hive_start.execute({ id: shortHash }, mockContext);
678
+
679
+ // Test hive_close
680
+ const result = await hive_close.execute(
681
+ { id: shortHash, reason: "Closed via short hash" },
682
+ mockContext,
683
+ );
684
+
685
+ expect(result).toContain("Closed");
686
+ expect(result).toContain(fullId);
687
+ } catch (error) {
688
+ // If ambiguous, verify error message is helpful
689
+ if (error instanceof Error && error.message.includes("Ambiguous")) {
690
+ expect(error.message).toMatch(/ambiguous.*multiple/i);
691
+ expect(error.message).toContain(shortHash);
692
+ } else {
693
+ throw error;
694
+ }
695
+ }
696
+ });
697
+
665
698
  describe("hive_update", () => {
666
699
  it("accepts full cell ID (no resolution needed)", async () => {
667
700
  const result = await hive_update.execute(
@@ -81,9 +81,9 @@ describe("WorkerHandoffContractSchema", () => {
81
81
  }
82
82
  });
83
83
 
84
- test("invalid task_id format fails", () => {
84
+ test("empty task_id fails", () => {
85
85
  const invalidContract = {
86
- task_id: "invalid-format", // Missing hash component
86
+ task_id: "", // Empty string not allowed
87
87
  files_owned: ["src/auth.ts"],
88
88
  files_readonly: [],
89
89
  dependencies_completed: [],
@@ -92,6 +92,37 @@ describe("WorkerHandoffContractSchema", () => {
92
92
 
93
93
  const result = WorkerHandoffContractSchema.safeParse(invalidContract);
94
94
  expect(result.success).toBe(false);
95
+ if (!result.success) {
96
+ expect(result.error.issues[0].message).toContain("cannot be empty");
97
+ }
98
+ });
99
+
100
+ test("short project name with hash is valid", () => {
101
+ // Regression test: single-word project names like "swarm-lf2p4u-abc123" should work
102
+ const shortProjectContract = {
103
+ task_id: "swarm-lf2p4u-abc123", // Only 2 segments before timestamp
104
+ files_owned: ["src/auth.ts"],
105
+ files_readonly: [],
106
+ dependencies_completed: [],
107
+ success_criteria: ["Auth works"],
108
+ };
109
+
110
+ const result = WorkerHandoffContractSchema.safeParse(shortProjectContract);
111
+ expect(result.success).toBe(true);
112
+ });
113
+
114
+ test("partial hash is valid (resolvePartialId will expand it)", () => {
115
+ // Partial hashes should be accepted - resolvePartialId will expand them
116
+ const partialHashContract = {
117
+ task_id: "mjd4pjuj", // Short hash only
118
+ files_owned: ["src/auth.ts"],
119
+ files_readonly: [],
120
+ dependencies_completed: [],
121
+ success_criteria: ["Auth works"],
122
+ };
123
+
124
+ const result = WorkerHandoffContractSchema.safeParse(partialHashContract);
125
+ expect(result.success).toBe(true);
95
126
  });
96
127
  });
97
128
 
@@ -18,17 +18,17 @@ import { z } from "zod";
18
18
  export const WorkerHandoffContractSchema = z.object({
19
19
  /**
20
20
  * Cell ID for this subtask.
21
- * Format: `{project}-{hash}` or `{project}-{hash}.{index}`
22
- * Example: `opencode-swarm-monorepo-lf2p4u-abc123`
21
+ * Can be a full cell ID, hash, or partial hash.
22
+ * Examples:
23
+ * - Full ID: `opencode-swarm-monorepo-lf2p4u-abc123`
24
+ * - Hash only: `lf2p4u`
25
+ * - Partial hash: `mjd4pjuj`
23
26
  *
24
- * Requires at least 3 segments (project can be multi-word, must have hash).
27
+ * The hive tools use resolvePartialId() to expand short IDs before lookup.
25
28
  */
26
29
  task_id: z
27
30
  .string()
28
- .regex(
29
- /^[a-z0-9]+(-[a-z0-9]+){2,}(\.[\w-]+)?$/,
30
- "Invalid task ID format (expected: project-slug-hash with minimum 3 segments)",
31
- ),
31
+ .min(1, "Task ID cannot be empty"),
32
32
 
33
33
  /**
34
34
  * Files this worker owns (exclusive write access).