opencode-swarm-plugin 0.16.0 → 0.17.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.
- package/.beads/issues.jsonl +5 -0
- package/README.md +41 -25
- package/bin/swarm.ts +35 -5
- package/dist/index.js +39 -39
- package/dist/plugin.js +39 -39
- package/package.json +1 -1
- package/src/beads.ts +30 -21
- package/src/mandate-storage.ts +14 -6
- package/src/mandates.ts +3 -3
- package/src/swarm.ts +24 -9
package/.beads/issues.jsonl
CHANGED
|
@@ -966,6 +966,11 @@
|
|
|
966
966
|
{"id":"opencode-swarm-plugin-gpse","title":"Workflow test epic","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-08T07:49:11.489232-08:00","updated_at":"2025-12-08T07:49:11.696115-08:00","closed_at":"2025-12-08T07:49:11.696115-08:00"}
|
|
967
967
|
{"id":"opencode-swarm-plugin-gpse.1","title":"Step 1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T07:49:11.52435-08:00","updated_at":"2025-12-08T07:49:11.619347-08:00","closed_at":"2025-12-08T07:49:11.619347-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-gpse.1","depends_on_id":"opencode-swarm-plugin-gpse","type":"parent-child","created_at":"2025-12-08T07:49:11.524725-08:00","created_by":"daemon"}]}
|
|
968
968
|
{"id":"opencode-swarm-plugin-gpse.2","title":"Step 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T07:49:11.56095-08:00","updated_at":"2025-12-08T07:49:11.671061-08:00","closed_at":"2025-12-08T07:49:11.671061-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-gpse.2","depends_on_id":"opencode-swarm-plugin-gpse","type":"parent-child","created_at":"2025-12-08T07:49:11.561312-08:00","created_by":"daemon"}]}
|
|
969
|
+
{"id":"opencode-swarm-plugin-gpusl","title":"DX Improvements: Actionable Errors \u0026 Troubleshooting","description":"Improve developer experience with actionable error messages that tell users HOW to fix problems, add troubleshooting docs, and enhance CLI doctor output.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-13T15:21:23.537986-08:00","updated_at":"2025-12-13T15:26:06.152115-08:00","closed_at":"2025-12-13T15:26:06.152115-08:00"}
|
|
970
|
+
{"id":"opencode-swarm-plugin-gpusl.1","title":"Add troubleshooting section to README","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T15:21:23.645841-08:00","updated_at":"2025-12-13T15:24:59.766004-08:00","closed_at":"2025-12-13T15:24:59.766004-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-gpusl.1","depends_on_id":"opencode-swarm-plugin-gpusl","type":"parent-child","created_at":"2025-12-13T15:21:23.64819-08:00","created_by":"daemon"}]}
|
|
971
|
+
{"id":"opencode-swarm-plugin-gpusl.2","title":"Make BeadError and SwarmError actionable","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T15:21:23.728838-08:00","updated_at":"2025-12-13T15:25:01.061305-08:00","closed_at":"2025-12-13T15:25:01.061305-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-gpusl.2","depends_on_id":"opencode-swarm-plugin-gpusl","type":"parent-child","created_at":"2025-12-13T15:21:23.730994-08:00","created_by":"daemon"}]}
|
|
972
|
+
{"id":"opencode-swarm-plugin-gpusl.3","title":"Make MandateError and storage errors actionable","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T15:21:23.806569-08:00","updated_at":"2025-12-13T15:25:02.21639-08:00","closed_at":"2025-12-13T15:25:02.21639-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-gpusl.3","depends_on_id":"opencode-swarm-plugin-gpusl","type":"parent-child","created_at":"2025-12-13T15:21:23.808361-08:00","created_by":"daemon"}]}
|
|
973
|
+
{"id":"opencode-swarm-plugin-gpusl.4","title":"Enhance CLI doctor with fix suggestions","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T15:21:23.868538-08:00","updated_at":"2025-12-13T15:25:03.179053-08:00","closed_at":"2025-12-13T15:25:03.179053-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-gpusl.4","depends_on_id":"opencode-swarm-plugin-gpusl","type":"parent-child","created_at":"2025-12-13T15:21:23.869987-08:00","created_by":"daemon"}]}
|
|
969
974
|
{"id":"opencode-swarm-plugin-gq4y","title":"Update test bead","description":"Updated description","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T11:12:26.032848-08:00","updated_at":"2025-12-08T11:12:28.256366-08:00","closed_at":"2025-12-08T11:12:28.256366-08:00"}
|
|
970
975
|
{"id":"opencode-swarm-plugin-gr8j","title":"Update test bead","description":"Original description","status":"closed","priority":0,"issue_type":"task","created_at":"2025-12-08T11:11:08.754659-08:00","updated_at":"2025-12-08T11:11:11.067841-08:00","closed_at":"2025-12-08T11:11:11.067841-08:00"}
|
|
971
976
|
{"id":"opencode-swarm-plugin-gswv","title":"Bead to start","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T07:53:44.538704-08:00","updated_at":"2025-12-08T07:53:46.579794-08:00","closed_at":"2025-12-08T07:53:46.579794-08:00"}
|
package/README.md
CHANGED
|
@@ -29,19 +29,15 @@ swarm setup
|
|
|
29
29
|
The setup wizard handles everything:
|
|
30
30
|
|
|
31
31
|
```
|
|
32
|
-
┌ opencode-swarm-plugin v0.
|
|
32
|
+
┌ opencode-swarm-plugin v0.16.0
|
|
33
33
|
│
|
|
34
34
|
◇ Checking dependencies...
|
|
35
35
|
│
|
|
36
36
|
◆ OpenCode
|
|
37
37
|
◆ Beads
|
|
38
|
-
|
|
39
|
-
▲
|
|
40
|
-
▲
|
|
41
|
-
│
|
|
42
|
-
◆ Install optional dependencies?
|
|
43
|
-
│ ◻ Swarm Mail - Multi-agent coordination
|
|
44
|
-
│ ◻ Redis - Rate limiting
|
|
38
|
+
▲ CASS (optional)
|
|
39
|
+
▲ UBS (optional)
|
|
40
|
+
▲ semantic-memory (optional)
|
|
45
41
|
│
|
|
46
42
|
◇ Setting up OpenCode integration...
|
|
47
43
|
│
|
|
@@ -271,16 +267,14 @@ What NOT to do...
|
|
|
271
267
|
|
|
272
268
|
## Dependencies
|
|
273
269
|
|
|
274
|
-
| Dependency | Purpose
|
|
275
|
-
| ------------------------------------------------------------------------------------------------------ |
|
|
276
|
-
| [OpenCode](https://opencode.ai) | Plugin host
|
|
277
|
-
| [Beads](https://github.com/steveyegge/beads) | Git-backed issue tracking
|
|
278
|
-
| [
|
|
279
|
-
| [
|
|
280
|
-
| [
|
|
281
|
-
| [
|
|
282
|
-
| [semantic-memory](https://github.com/joelhooks/semantic-memory) | Learning persistence | No |
|
|
283
|
-
| [Redis](https://redis.io) | Rate limiting (SQLite fallback available) | No |
|
|
270
|
+
| Dependency | Purpose | Required |
|
|
271
|
+
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | -------- |
|
|
272
|
+
| [OpenCode](https://opencode.ai) | Plugin host | Yes |
|
|
273
|
+
| [Beads](https://github.com/steveyegge/beads) | Git-backed issue tracking | Yes |
|
|
274
|
+
| [CASS (Coding Agent Session Search)](https://github.com/Dicklesworthstone/coding_agent_session_search) | Historical context from past sessions | No |
|
|
275
|
+
| [UBS (Ultimate Bug Scanner)](https://github.com/Dicklesworthstone/ultimate_bug_scanner) | Pre-completion bug scanning using AI-powered static analysis | No |
|
|
276
|
+
| [semantic-memory](https://github.com/joelhooks/semantic-memory) | Learning persistence | No |
|
|
277
|
+
| [Redis](https://redis.io) | Rate limiting (SQLite fallback available) | No |
|
|
284
278
|
|
|
285
279
|
All dependencies are checked and can be installed via `swarm setup`.
|
|
286
280
|
|
|
@@ -298,13 +292,7 @@ curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_sca
|
|
|
298
292
|
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/coding_agent_session_search/main/install.sh | bash -s -- --easy-mode
|
|
299
293
|
```
|
|
300
294
|
|
|
301
|
-
**
|
|
302
|
-
|
|
303
|
-
```bash
|
|
304
|
-
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh" | bash -s -- --yes
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
> **Note:** The embedded Swarm Mail (PGLite in-process) is now the primary option and works out of the box with no external dependencies. MCP Agent Mail (external Go server) is still supported for advanced use cases requiring a separate server process.
|
|
295
|
+
> **Note:** Swarm Mail is now embedded (PGLite in-process) and works out of the box with no external dependencies. No Go or external servers required.
|
|
308
296
|
|
|
309
297
|
## Tools Reference
|
|
310
298
|
|
|
@@ -584,6 +572,34 @@ bun test
|
|
|
584
572
|
bun run build
|
|
585
573
|
```
|
|
586
574
|
|
|
575
|
+
## Troubleshooting
|
|
576
|
+
|
|
577
|
+
### 1. First Step: Run Doctor
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
swarm doctor
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
This checks all dependencies and shows their installation status.
|
|
584
|
+
|
|
585
|
+
### 2. Common Issues
|
|
586
|
+
|
|
587
|
+
| Issue | Cause | Solution |
|
|
588
|
+
| --------------------------- | ---------------------------------- | ------------------------------------------------- |
|
|
589
|
+
| `beads: command not found` | Beads CLI not installed | `npm install -g @joelhooks/beads` |
|
|
590
|
+
| `bd: command not found` | Same as above | `npm install -g @joelhooks/beads` |
|
|
591
|
+
| Verification Gate fails | TypeScript errors or test failures | Fix errors shown, or use `skip_verification=true` |
|
|
592
|
+
| File reservation conflict | Another agent has the file | Wait for release, or check `swarmmail_inbox` |
|
|
593
|
+
| `Mandate not found` | ID doesn't exist | Use `mandate_list` to see available mandates |
|
|
594
|
+
| Swarm Mail connection error | Database not initialized | Run `swarm setup` again |
|
|
595
|
+
| `Agent not registered` | Session not initialized | Call `swarmmail_init` first |
|
|
596
|
+
|
|
597
|
+
### 3. Getting Help
|
|
598
|
+
|
|
599
|
+
- Run `swarm doctor` for dependency status
|
|
600
|
+
- Check `swarmmail_health` for database status
|
|
601
|
+
- File issues at: https://github.com/joelhooks/opencode-swarm-plugin/issues
|
|
602
|
+
|
|
587
603
|
## License
|
|
588
604
|
|
|
589
605
|
MIT
|
package/bin/swarm.ts
CHANGED
|
@@ -670,6 +670,34 @@ If you discover a reusable pattern worth preserving:
|
|
|
670
670
|
// Commands
|
|
671
671
|
// ============================================================================
|
|
672
672
|
|
|
673
|
+
/**
|
|
674
|
+
* Get the fix command for a dependency
|
|
675
|
+
* Returns null for manual installs (those show a link instead)
|
|
676
|
+
*/
|
|
677
|
+
function getFixCommand(dep: Dependency): string | null {
|
|
678
|
+
switch (dep.name) {
|
|
679
|
+
case "OpenCode":
|
|
680
|
+
return "brew install sst/tap/opencode";
|
|
681
|
+
case "Beads":
|
|
682
|
+
return "curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash";
|
|
683
|
+
case "Go":
|
|
684
|
+
return "brew install go (or visit https://go.dev/dl/)";
|
|
685
|
+
case "semantic-memory":
|
|
686
|
+
return "npm install -g semantic-memory";
|
|
687
|
+
case "Redis":
|
|
688
|
+
return "brew install redis && brew services start redis";
|
|
689
|
+
case "MCP Agent Mail":
|
|
690
|
+
return "See: https://github.com/Dicklesworthstone/mcp_agent_mail";
|
|
691
|
+
case "CASS (Coding Agent Session Search)":
|
|
692
|
+
return "See: https://github.com/Dicklesworthstone/coding_agent_session_search";
|
|
693
|
+
case "UBS (Ultimate Bug Scanner)":
|
|
694
|
+
return "See: https://github.com/Dicklesworthstone/ultimate_bug_scanner";
|
|
695
|
+
default:
|
|
696
|
+
// Fallback to generic install command if available
|
|
697
|
+
return dep.installType !== "manual" ? dep.install : null;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
673
701
|
async function doctor() {
|
|
674
702
|
p.intro("swarm doctor v" + VERSION);
|
|
675
703
|
|
|
@@ -689,7 +717,10 @@ async function doctor() {
|
|
|
689
717
|
p.log.success(dep.name + (version ? " v" + version : ""));
|
|
690
718
|
} else {
|
|
691
719
|
p.log.error(dep.name + " - not found");
|
|
692
|
-
|
|
720
|
+
const fixCmd = getFixCommand(dep);
|
|
721
|
+
if (fixCmd) {
|
|
722
|
+
p.log.message(dim(" └─ Fix: " + fixCmd));
|
|
723
|
+
}
|
|
693
724
|
}
|
|
694
725
|
}
|
|
695
726
|
|
|
@@ -701,10 +732,9 @@ async function doctor() {
|
|
|
701
732
|
);
|
|
702
733
|
} else {
|
|
703
734
|
p.log.warn(dep.name + " - not found (" + dep.description + ")");
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
p.log.message(" See: " + dep.install);
|
|
735
|
+
const fixCmd = getFixCommand(dep);
|
|
736
|
+
if (fixCmd) {
|
|
737
|
+
p.log.message(dim(" └─ Fix: " + fixCmd));
|
|
708
738
|
}
|
|
709
739
|
}
|
|
710
740
|
}
|
package/dist/index.js
CHANGED
|
@@ -29841,7 +29841,7 @@ function parseBead(output) {
|
|
|
29841
29841
|
const parsed = JSON.parse(output);
|
|
29842
29842
|
const data = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
29843
29843
|
if (!data) {
|
|
29844
|
-
throw new BeadError("No bead data in response", "parse");
|
|
29844
|
+
throw new BeadError("No bead data in response. The bd CLI may not be installed or returned unexpected output. Try: Run 'bd --version' to verify installation, or check if .beads/ directory exists in project.", "parse");
|
|
29845
29845
|
}
|
|
29846
29846
|
return BeadSchema.parse(data);
|
|
29847
29847
|
} catch (error45) {
|
|
@@ -29851,7 +29851,7 @@ function parseBead(output) {
|
|
|
29851
29851
|
if (error45 instanceof BeadError) {
|
|
29852
29852
|
throw error45;
|
|
29853
29853
|
}
|
|
29854
|
-
throw new BeadError(`Failed to parse bead JSON: ${output}`, "parse");
|
|
29854
|
+
throw new BeadError(`Failed to parse bead JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`, "parse");
|
|
29855
29855
|
}
|
|
29856
29856
|
}
|
|
29857
29857
|
function parseBeads(output) {
|
|
@@ -29862,7 +29862,7 @@ function parseBeads(output) {
|
|
|
29862
29862
|
if (error45 instanceof exports_external.ZodError) {
|
|
29863
29863
|
throw new BeadValidationError(`Invalid beads data: ${error45.message}`, error45);
|
|
29864
29864
|
}
|
|
29865
|
-
throw new BeadError(`Failed to parse beads JSON: ${output}`, "parse");
|
|
29865
|
+
throw new BeadError(`Failed to parse beads JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`, "parse");
|
|
29866
29866
|
}
|
|
29867
29867
|
}
|
|
29868
29868
|
var beads_create = tool({
|
|
@@ -29879,14 +29879,14 @@ var beads_create = tool({
|
|
|
29879
29879
|
const cmdParts = buildCreateCommand(validated);
|
|
29880
29880
|
const result = await runBdCommand(cmdParts.slice(1));
|
|
29881
29881
|
if (result.exitCode !== 0) {
|
|
29882
|
-
throw new BeadError(`Failed to create bead: ${result.stderr}
|
|
29882
|
+
throw new BeadError(`Failed to create bead because bd command exited with code ${result.exitCode}. Error: ${result.stderr}. Try: Check if beads initialized with 'bd init' in project root, or verify .beads/ directory exists.`, cmdParts.join(" "), result.exitCode, result.stderr);
|
|
29883
29883
|
}
|
|
29884
29884
|
const stdout = result.stdout.trim();
|
|
29885
29885
|
if (!stdout) {
|
|
29886
|
-
throw new BeadError("bd create returned empty output", cmdParts.join(" "), 0, "Empty stdout");
|
|
29886
|
+
throw new BeadError("bd create returned empty output because command produced no response. Try: Check if bd is properly installed with 'bd --version', or run 'bd list' to test basic functionality.", cmdParts.join(" "), 0, "Empty stdout");
|
|
29887
29887
|
}
|
|
29888
29888
|
if (stdout.startsWith("error:") || stdout.startsWith("Error:")) {
|
|
29889
|
-
throw new BeadError(`bd create failed: ${stdout}
|
|
29889
|
+
throw new BeadError(`bd create failed because command returned error in stdout: ${stdout}. Try: Check error message above, verify beads initialized with 'bd init', or check .beads/issues.jsonl for corruption.`, cmdParts.join(" "), 0, stdout);
|
|
29890
29890
|
}
|
|
29891
29891
|
const bead = parseBead(stdout);
|
|
29892
29892
|
return JSON.stringify(bead, null, 2);
|
|
@@ -29918,7 +29918,7 @@ var beads_create_epic = tool({
|
|
|
29918
29918
|
});
|
|
29919
29919
|
const epicResult = await runBdCommand(epicCmd.slice(1));
|
|
29920
29920
|
if (epicResult.exitCode !== 0) {
|
|
29921
|
-
throw new BeadError(`Failed to create epic: ${epicResult.stderr}
|
|
29921
|
+
throw new BeadError(`Failed to create epic because bd command failed: ${epicResult.stderr}. Try: Verify beads initialized with 'bd init', check if .beads/ directory is writable, or run 'bd list' to test basic functionality.`, epicCmd.join(" "), epicResult.exitCode);
|
|
29922
29922
|
}
|
|
29923
29923
|
const epic = parseBead(epicResult.stdout);
|
|
29924
29924
|
created.push(epic);
|
|
@@ -29936,7 +29936,7 @@ var beads_create_epic = tool({
|
|
|
29936
29936
|
});
|
|
29937
29937
|
const subtaskResult = await runBdCommand(subtaskCmd.slice(1));
|
|
29938
29938
|
if (subtaskResult.exitCode !== 0) {
|
|
29939
|
-
throw new BeadError(`Failed to create subtask: ${subtaskResult.stderr}
|
|
29939
|
+
throw new BeadError(`Failed to create subtask because bd command failed: ${subtaskResult.stderr}. Try: Check if parent epic exists with 'bd show ${epic.id}', verify .beads/issues.jsonl is not corrupted, or check for invalid characters in title.`, subtaskCmd.join(" "), subtaskResult.exitCode);
|
|
29940
29940
|
}
|
|
29941
29941
|
const subtaskBead = parseBead(subtaskResult.stdout);
|
|
29942
29942
|
created.push(subtaskBead);
|
|
@@ -29992,7 +29992,7 @@ ${rollbackErrors.join(`
|
|
|
29992
29992
|
|
|
29993
29993
|
No beads to rollback.`;
|
|
29994
29994
|
}
|
|
29995
|
-
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}
|
|
29995
|
+
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}. Try: If rollback failed, manually close beads with 'bd close <id> --reason "Rollback"', check .beads/issues.jsonl for partial state, or re-run beads_create_epic with corrected parameters.`, "beads_create_epic", 1);
|
|
29996
29996
|
}
|
|
29997
29997
|
}
|
|
29998
29998
|
});
|
|
@@ -30020,7 +30020,7 @@ var beads_query = tool({
|
|
|
30020
30020
|
}
|
|
30021
30021
|
const result = await runBdCommand(cmd.slice(1));
|
|
30022
30022
|
if (result.exitCode !== 0) {
|
|
30023
|
-
throw new BeadError(`Failed to query beads: ${result.stderr}
|
|
30023
|
+
throw new BeadError(`Failed to query beads because bd command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory exists, or run 'bd --version' to check CLI version.`, cmd.join(" "), result.exitCode);
|
|
30024
30024
|
}
|
|
30025
30025
|
const beads = parseBeads(result.stdout);
|
|
30026
30026
|
const limited = beads.slice(0, validated.limit);
|
|
@@ -30050,7 +30050,7 @@ var beads_update = tool({
|
|
|
30050
30050
|
cmd.push("--json");
|
|
30051
30051
|
const result = await runBdCommand(cmd.slice(1));
|
|
30052
30052
|
if (result.exitCode !== 0) {
|
|
30053
|
-
throw new BeadError(`Failed to update bead: ${result.stderr}
|
|
30053
|
+
throw new BeadError(`Failed to update bead because bd command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${validated.id}', check for invalid status values, or inspect .beads/issues.jsonl for corruption.`, cmd.join(" "), result.exitCode);
|
|
30054
30054
|
}
|
|
30055
30055
|
const bead = parseBead(result.stdout);
|
|
30056
30056
|
return JSON.stringify(bead, null, 2);
|
|
@@ -30074,7 +30074,7 @@ var beads_close = tool({
|
|
|
30074
30074
|
];
|
|
30075
30075
|
const result = await runBdCommand(cmd.slice(1));
|
|
30076
30076
|
if (result.exitCode !== 0) {
|
|
30077
|
-
throw new BeadError(`Failed to close bead: ${result.stderr}
|
|
30077
|
+
throw new BeadError(`Failed to close bead because bd command failed: ${result.stderr}. Try: Verify bead exists and is not already closed with 'beads_query(status="closed")' or 'bd show ${validated.id}', check if bead ID is correct.`, cmd.join(" "), result.exitCode);
|
|
30078
30078
|
}
|
|
30079
30079
|
const bead = parseBead(result.stdout);
|
|
30080
30080
|
return `Closed ${bead.id}: ${validated.reason}`;
|
|
@@ -30094,7 +30094,7 @@ var beads_start = tool({
|
|
|
30094
30094
|
"--json"
|
|
30095
30095
|
]);
|
|
30096
30096
|
if (result.exitCode !== 0) {
|
|
30097
|
-
throw new BeadError(`Failed to start bead: ${result.stderr}
|
|
30097
|
+
throw new BeadError(`Failed to start bead because bd update command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${args.id}', check if already in_progress with 'beads_query(status="in_progress")', or use beads_update directly.`, `bd update ${args.id} --status in_progress --json`, result.exitCode);
|
|
30098
30098
|
}
|
|
30099
30099
|
const bead = parseBead(result.stdout);
|
|
30100
30100
|
return `Started: ${bead.id}`;
|
|
@@ -30106,7 +30106,7 @@ var beads_ready = tool({
|
|
|
30106
30106
|
async execute(args, ctx) {
|
|
30107
30107
|
const result = await runBdCommand(["ready", "--json"]);
|
|
30108
30108
|
if (result.exitCode !== 0) {
|
|
30109
|
-
throw new BeadError(`Failed to get ready beads: ${result.stderr}
|
|
30109
|
+
throw new BeadError(`Failed to get ready beads because bd ready command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory is readable, or run 'bd list --json' to test basic query.`, "bd ready --json", result.exitCode);
|
|
30110
30110
|
}
|
|
30111
30111
|
const beads = parseBeads(result.stdout);
|
|
30112
30112
|
if (beads.length === 0) {
|
|
@@ -30139,7 +30139,7 @@ var beads_sync = tool({
|
|
|
30139
30139
|
};
|
|
30140
30140
|
const flushResult = await withTimeout(runBdCommand(["sync", "--flush-only"]), TIMEOUT_MS, "bd sync --flush-only");
|
|
30141
30141
|
if (flushResult.exitCode !== 0) {
|
|
30142
|
-
throw new BeadError(`Failed to flush beads: ${flushResult.stderr}
|
|
30142
|
+
throw new BeadError(`Failed to flush beads because bd sync failed: ${flushResult.stderr}. Try: Check if .beads/ directory is writable, verify no corrupted JSONL files, or run 'bd list' to test basic beads functionality.`, "bd sync --flush-only", flushResult.exitCode);
|
|
30143
30143
|
}
|
|
30144
30144
|
const beadsStatusResult = await runGitCommand([
|
|
30145
30145
|
"status",
|
|
@@ -30150,11 +30150,11 @@ var beads_sync = tool({
|
|
|
30150
30150
|
if (hasChanges) {
|
|
30151
30151
|
const addResult = await runGitCommand(["add", ".beads/"]);
|
|
30152
30152
|
if (addResult.exitCode !== 0) {
|
|
30153
|
-
throw new BeadError(`Failed to stage beads: ${addResult.stderr}
|
|
30153
|
+
throw new BeadError(`Failed to stage beads because git add failed: ${addResult.stderr}. Try: Check if .beads/ directory exists, verify git is initialized with 'git status', or check for .gitignore patterns blocking .beads/.`, "git add .beads/", addResult.exitCode);
|
|
30154
30154
|
}
|
|
30155
30155
|
const commitResult = await withTimeout(runGitCommand(["commit", "-m", "chore: sync beads"]), TIMEOUT_MS, "git commit");
|
|
30156
30156
|
if (commitResult.exitCode !== 0 && !commitResult.stdout.includes("nothing to commit")) {
|
|
30157
|
-
throw new BeadError(`Failed to commit beads: ${commitResult.stderr}
|
|
30157
|
+
throw new BeadError(`Failed to commit beads because git commit failed: ${commitResult.stderr}. Try: Check git config (user.name, user.email) with 'git config --list', verify working tree is clean, or check for pre-commit hooks blocking commit.`, "git commit", commitResult.exitCode);
|
|
30158
30158
|
}
|
|
30159
30159
|
}
|
|
30160
30160
|
if (autoPull) {
|
|
@@ -30193,7 +30193,7 @@ var beads_sync = tool({
|
|
|
30193
30193
|
}
|
|
30194
30194
|
}
|
|
30195
30195
|
if (pullResult.exitCode !== 0) {
|
|
30196
|
-
throw new BeadError(`Failed to pull: ${pullResult.stderr}
|
|
30196
|
+
throw new BeadError(`Failed to pull because git pull --rebase failed: ${pullResult.stderr}. Try: Resolve merge conflicts manually with 'git status', check if remote is accessible with 'git remote -v', or use skip_verification to bypass automatic pull.`, "git pull --rebase", pullResult.exitCode);
|
|
30197
30197
|
}
|
|
30198
30198
|
const importResult = await withTimeout(runBdCommand(["sync", "--import-only"]), TIMEOUT_MS, "bd sync --import-only");
|
|
30199
30199
|
if (importResult.exitCode !== 0) {
|
|
@@ -30202,7 +30202,7 @@ var beads_sync = tool({
|
|
|
30202
30202
|
}
|
|
30203
30203
|
const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
|
|
30204
30204
|
if (pushResult.exitCode !== 0) {
|
|
30205
|
-
throw new BeadError(`Failed to push: ${pushResult.stderr}
|
|
30205
|
+
throw new BeadError(`Failed to push because git push failed: ${pushResult.stderr}. Try: Check if remote branch is up to date with 'git pull --rebase', verify push permissions, check remote URL with 'git remote -v', or force push with 'git push --force-with-lease' if safe.`, "git push", pushResult.exitCode);
|
|
30206
30206
|
}
|
|
30207
30207
|
const statusResult = await runGitCommand(["status", "--porcelain"]);
|
|
30208
30208
|
const status = statusResult.stdout.trim();
|
|
@@ -30222,7 +30222,7 @@ var beads_link_thread = tool({
|
|
|
30222
30222
|
async execute(args, ctx) {
|
|
30223
30223
|
const queryResult = await runBdCommand(["show", args.bead_id, "--json"]);
|
|
30224
30224
|
if (queryResult.exitCode !== 0) {
|
|
30225
|
-
throw new BeadError(`Failed to get bead: ${queryResult.stderr}
|
|
30225
|
+
throw new BeadError(`Failed to get bead because bd show command failed: ${queryResult.stderr}. Try: Verify bead ID is correct with 'beads_query()', check if bead exists with 'bd list --json', or check .beads/issues.jsonl for valid entries.`, `bd show ${args.bead_id} --json`, queryResult.exitCode);
|
|
30226
30226
|
}
|
|
30227
30227
|
const bead = parseBead(queryResult.stdout);
|
|
30228
30228
|
const existingDesc = bead.description || "";
|
|
@@ -30241,7 +30241,7 @@ ${threadMarker}` : threadMarker;
|
|
|
30241
30241
|
"--json"
|
|
30242
30242
|
]);
|
|
30243
30243
|
if (updateResult.exitCode !== 0) {
|
|
30244
|
-
throw new BeadError(`Failed to update bead: ${updateResult.stderr}
|
|
30244
|
+
throw new BeadError(`Failed to update bead because bd update command failed: ${updateResult.stderr}. Try: Verify bead exists with 'bd show ${args.bead_id}', check for invalid characters in description, or inspect .beads/issues.jsonl for corruption.`, `bd update ${args.bead_id} -d ...`, updateResult.exitCode);
|
|
30245
30245
|
}
|
|
30246
30246
|
return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
|
|
30247
30247
|
}
|
|
@@ -34015,7 +34015,7 @@ async function runVerificationGate(filesTouched, skipUbs = false) {
|
|
|
34015
34015
|
};
|
|
34016
34016
|
if (!ubsStep.passed) {
|
|
34017
34017
|
ubsStep.error = `Found ${ubsResult.summary.critical} critical bugs`;
|
|
34018
|
-
blockers.push(`UBS
|
|
34018
|
+
blockers.push(`UBS found ${ubsResult.summary.critical} critical bug(s). Try: Run 'ubs scan ${filesTouched.join(" ")}' to see details, fix critical bugs in reported files, or use skip_ubs_scan=true to bypass (not recommended).`);
|
|
34019
34019
|
}
|
|
34020
34020
|
steps.push(ubsStep);
|
|
34021
34021
|
} else {
|
|
@@ -34032,12 +34032,12 @@ async function runVerificationGate(filesTouched, skipUbs = false) {
|
|
|
34032
34032
|
const typecheckStep = await runTypecheckVerification();
|
|
34033
34033
|
steps.push(typecheckStep);
|
|
34034
34034
|
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
34035
|
-
blockers.push(`Typecheck: ${typecheckStep.error?.slice(0, 100) || "
|
|
34035
|
+
blockers.push(`Typecheck failed: ${typecheckStep.error?.slice(0, 100) || "type errors found"}. Try: Run 'tsc --noEmit' to see full errors, check tsconfig.json configuration, or fix reported type errors in modified files.`);
|
|
34036
34036
|
}
|
|
34037
34037
|
const testStep = await runTestVerification(filesTouched);
|
|
34038
34038
|
steps.push(testStep);
|
|
34039
34039
|
if (!testStep.passed && !testStep.skipped) {
|
|
34040
|
-
blockers.push(`Tests: ${testStep.error?.slice(0, 100) || "
|
|
34040
|
+
blockers.push(`Tests failed: ${testStep.error?.slice(0, 100) || "test failures"}. Try: Run 'bun test ${testStep.command.split(" ").slice(2).join(" ")}' to see full output, check test assertions, or fix failing tests in modified files.`);
|
|
34041
34041
|
}
|
|
34042
34042
|
const passedCount = steps.filter((s) => s.passed).length;
|
|
34043
34043
|
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
@@ -34092,8 +34092,8 @@ async function runUbsScan(files) {
|
|
|
34092
34092
|
}
|
|
34093
34093
|
};
|
|
34094
34094
|
} catch (error45) {
|
|
34095
|
-
console.error(`[swarm] CRITICAL: UBS scan failed to parse JSON output:`, error45);
|
|
34096
|
-
console.error(`[swarm] Raw output
|
|
34095
|
+
console.error(`[swarm] CRITICAL: UBS scan failed to parse JSON output because output is malformed:`, error45);
|
|
34096
|
+
console.error(`[swarm] Raw output: ${output}. Try: Run 'ubs doctor' to check installation, verify UBS version with 'ubs --version' (need v1.0.0+), or check if UBS supports --json flag.`);
|
|
34097
34097
|
return {
|
|
34098
34098
|
exitCode: result.exitCode,
|
|
34099
34099
|
bugs: [],
|
|
@@ -34183,7 +34183,7 @@ var swarm_complete = tool({
|
|
|
34183
34183
|
error: s.error?.slice(0, 200)
|
|
34184
34184
|
}))
|
|
34185
34185
|
},
|
|
34186
|
-
hint: "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
34186
|
+
hint: verificationResult.blockers.length > 0 ? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.` : "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
34187
34187
|
gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
|
|
34188
34188
|
}, null, 2);
|
|
34189
34189
|
}
|
|
@@ -34194,12 +34194,12 @@ var swarm_complete = tool({
|
|
|
34194
34194
|
if (ubsResult && ubsResult.summary.critical > 0) {
|
|
34195
34195
|
return JSON.stringify({
|
|
34196
34196
|
success: false,
|
|
34197
|
-
error:
|
|
34197
|
+
error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
|
|
34198
34198
|
ubs_scan: {
|
|
34199
34199
|
critical_count: ubsResult.summary.critical,
|
|
34200
34200
|
bugs: ubsResult.bugs.filter((b) => b.severity === "critical")
|
|
34201
34201
|
},
|
|
34202
|
-
hint:
|
|
34202
|
+
hint: `Fix these critical bugs: ${ubsResult.bugs.filter((b) => b.severity === "critical").map((b) => `${b.file}:${b.line} - ${b.message}`).slice(0, 3).join("; ")}. Try: Run 'ubs scan ${args.files_touched?.join(" ") || "."} --json' for full report, fix reported issues, or use skip_ubs_scan=true to bypass (not recommended).`
|
|
34203
34203
|
}, null, 2);
|
|
34204
34204
|
}
|
|
34205
34205
|
}
|
|
@@ -34225,7 +34225,7 @@ var swarm_complete = tool({
|
|
|
34225
34225
|
}
|
|
34226
34226
|
const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
|
|
34227
34227
|
if (closeResult.exitCode !== 0) {
|
|
34228
|
-
throw new SwarmError(`Failed to close bead: ${closeResult.stderr.toString()}
|
|
34228
|
+
throw new SwarmError(`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`, "complete");
|
|
34229
34229
|
}
|
|
34230
34230
|
try {
|
|
34231
34231
|
await releaseSwarmFiles({
|
|
@@ -35403,7 +35403,7 @@ class SemanticMemoryMandateStorage {
|
|
|
35403
35403
|
async update(id, updates) {
|
|
35404
35404
|
const existing = await this.get(id);
|
|
35405
35405
|
if (!existing) {
|
|
35406
|
-
throw new Error(`Mandate ${id} not found
|
|
35406
|
+
throw new Error(`Mandate '${id}' not found. Use list() to see available mandates.`);
|
|
35407
35407
|
}
|
|
35408
35408
|
const updated = { ...existing, ...updates };
|
|
35409
35409
|
await this.store(updated);
|
|
@@ -35411,7 +35411,7 @@ class SemanticMemoryMandateStorage {
|
|
|
35411
35411
|
async vote(vote) {
|
|
35412
35412
|
const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
|
|
35413
35413
|
if (existing) {
|
|
35414
|
-
throw new Error(`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}
|
|
35414
|
+
throw new Error(`Agent '${vote.agent_name}' has already voted on mandate '${vote.mandate_id}'. Each agent can vote once per mandate to ensure fair consensus.`);
|
|
35415
35415
|
}
|
|
35416
35416
|
await this.storeInternal(this.config.collections.votes, vote, {
|
|
35417
35417
|
id: vote.id,
|
|
@@ -35502,7 +35502,7 @@ class InMemoryMandateStorage {
|
|
|
35502
35502
|
async update(id, updates) {
|
|
35503
35503
|
const existing = await this.get(id);
|
|
35504
35504
|
if (!existing) {
|
|
35505
|
-
throw new Error(`Mandate ${id} not found
|
|
35505
|
+
throw new Error(`Mandate '${id}' not found. Use list() to see available mandates.`);
|
|
35506
35506
|
}
|
|
35507
35507
|
const updated = { ...existing, ...updates };
|
|
35508
35508
|
this.entries.set(id, updated);
|
|
@@ -35510,7 +35510,7 @@ class InMemoryMandateStorage {
|
|
|
35510
35510
|
async vote(vote) {
|
|
35511
35511
|
const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
|
|
35512
35512
|
if (existing) {
|
|
35513
|
-
throw new Error(`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}
|
|
35513
|
+
throw new Error(`Agent '${vote.agent_name}' has already voted on mandate '${vote.mandate_id}'. Each agent can vote once per mandate to ensure fair consensus.`);
|
|
35514
35514
|
}
|
|
35515
35515
|
this.votes.set(vote.id, vote);
|
|
35516
35516
|
}
|
|
@@ -35565,13 +35565,13 @@ function createMandateStorage(config2 = {}) {
|
|
|
35565
35565
|
case "memory":
|
|
35566
35566
|
return new InMemoryMandateStorage(fullConfig);
|
|
35567
35567
|
default:
|
|
35568
|
-
throw new Error(`Unknown storage backend: ${fullConfig.backend}
|
|
35568
|
+
throw new Error(`Unknown storage backend: '${fullConfig.backend}'. Valid backends are 'semantic-memory' or 'memory'.`);
|
|
35569
35569
|
}
|
|
35570
35570
|
}
|
|
35571
35571
|
async function updateMandateStatus(mandateId, storage) {
|
|
35572
35572
|
const entry = await storage.get(mandateId);
|
|
35573
35573
|
if (!entry) {
|
|
35574
|
-
throw new Error(`Mandate ${mandateId} not found
|
|
35574
|
+
throw new Error(`Mandate '${mandateId}' not found when calculating score. Use storage.list() to verify the mandate exists.`);
|
|
35575
35575
|
}
|
|
35576
35576
|
const score = await storage.calculateScore(mandateId);
|
|
35577
35577
|
const previousStatus = entry.status;
|
|
@@ -35781,11 +35781,11 @@ var mandate_vote = tool({
|
|
|
35781
35781
|
const storage = getMandateStorage();
|
|
35782
35782
|
const mandate = await storage.get(validated.mandate_id);
|
|
35783
35783
|
if (!mandate) {
|
|
35784
|
-
throw new MandateError(`Mandate ${validated.mandate_id} not found
|
|
35784
|
+
throw new MandateError(`Mandate '${validated.mandate_id}' not found. Use mandate_list() to see available mandates, or check the ID is correct.`, "mandate_vote");
|
|
35785
35785
|
}
|
|
35786
35786
|
const hasVoted = await storage.hasVoted(validated.mandate_id, args.agent_name);
|
|
35787
35787
|
if (hasVoted) {
|
|
35788
|
-
throw new MandateError(`Agent ${args.agent_name} has already voted on mandate ${validated.mandate_id}
|
|
35788
|
+
throw new MandateError(`Agent '${args.agent_name}' has already voted on mandate '${validated.mandate_id}'. Each agent can vote once per mandate. This is expected behavior to prevent vote manipulation.`, "mandate_vote");
|
|
35789
35789
|
}
|
|
35790
35790
|
const vote = {
|
|
35791
35791
|
id: generateVoteId(),
|
|
@@ -35928,7 +35928,7 @@ var mandate_stats = tool({
|
|
|
35928
35928
|
if (args.mandate_id) {
|
|
35929
35929
|
const mandate = await storage.get(args.mandate_id);
|
|
35930
35930
|
if (!mandate) {
|
|
35931
|
-
throw new MandateError(`Mandate ${args.mandate_id} not found
|
|
35931
|
+
throw new MandateError(`Mandate '${args.mandate_id}' not found. Use mandate_list() to see available mandates, or check the ID is correct.`, "mandate_stats");
|
|
35932
35932
|
}
|
|
35933
35933
|
const score = await storage.calculateScore(args.mandate_id);
|
|
35934
35934
|
const votes = await storage.getVotes(args.mandate_id);
|
package/dist/plugin.js
CHANGED
|
@@ -29829,7 +29829,7 @@ function parseBead(output) {
|
|
|
29829
29829
|
const parsed = JSON.parse(output);
|
|
29830
29830
|
const data = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
29831
29831
|
if (!data) {
|
|
29832
|
-
throw new BeadError("No bead data in response", "parse");
|
|
29832
|
+
throw new BeadError("No bead data in response. The bd CLI may not be installed or returned unexpected output. Try: Run 'bd --version' to verify installation, or check if .beads/ directory exists in project.", "parse");
|
|
29833
29833
|
}
|
|
29834
29834
|
return BeadSchema.parse(data);
|
|
29835
29835
|
} catch (error45) {
|
|
@@ -29839,7 +29839,7 @@ function parseBead(output) {
|
|
|
29839
29839
|
if (error45 instanceof BeadError) {
|
|
29840
29840
|
throw error45;
|
|
29841
29841
|
}
|
|
29842
|
-
throw new BeadError(`Failed to parse bead JSON: ${output}`, "parse");
|
|
29842
|
+
throw new BeadError(`Failed to parse bead JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`, "parse");
|
|
29843
29843
|
}
|
|
29844
29844
|
}
|
|
29845
29845
|
function parseBeads(output) {
|
|
@@ -29850,7 +29850,7 @@ function parseBeads(output) {
|
|
|
29850
29850
|
if (error45 instanceof exports_external.ZodError) {
|
|
29851
29851
|
throw new BeadValidationError(`Invalid beads data: ${error45.message}`, error45);
|
|
29852
29852
|
}
|
|
29853
|
-
throw new BeadError(`Failed to parse beads JSON: ${output}`, "parse");
|
|
29853
|
+
throw new BeadError(`Failed to parse beads JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`, "parse");
|
|
29854
29854
|
}
|
|
29855
29855
|
}
|
|
29856
29856
|
var beads_create = tool({
|
|
@@ -29867,14 +29867,14 @@ var beads_create = tool({
|
|
|
29867
29867
|
const cmdParts = buildCreateCommand(validated);
|
|
29868
29868
|
const result = await runBdCommand(cmdParts.slice(1));
|
|
29869
29869
|
if (result.exitCode !== 0) {
|
|
29870
|
-
throw new BeadError(`Failed to create bead: ${result.stderr}
|
|
29870
|
+
throw new BeadError(`Failed to create bead because bd command exited with code ${result.exitCode}. Error: ${result.stderr}. Try: Check if beads initialized with 'bd init' in project root, or verify .beads/ directory exists.`, cmdParts.join(" "), result.exitCode, result.stderr);
|
|
29871
29871
|
}
|
|
29872
29872
|
const stdout = result.stdout.trim();
|
|
29873
29873
|
if (!stdout) {
|
|
29874
|
-
throw new BeadError("bd create returned empty output", cmdParts.join(" "), 0, "Empty stdout");
|
|
29874
|
+
throw new BeadError("bd create returned empty output because command produced no response. Try: Check if bd is properly installed with 'bd --version', or run 'bd list' to test basic functionality.", cmdParts.join(" "), 0, "Empty stdout");
|
|
29875
29875
|
}
|
|
29876
29876
|
if (stdout.startsWith("error:") || stdout.startsWith("Error:")) {
|
|
29877
|
-
throw new BeadError(`bd create failed: ${stdout}
|
|
29877
|
+
throw new BeadError(`bd create failed because command returned error in stdout: ${stdout}. Try: Check error message above, verify beads initialized with 'bd init', or check .beads/issues.jsonl for corruption.`, cmdParts.join(" "), 0, stdout);
|
|
29878
29878
|
}
|
|
29879
29879
|
const bead = parseBead(stdout);
|
|
29880
29880
|
return JSON.stringify(bead, null, 2);
|
|
@@ -29906,7 +29906,7 @@ var beads_create_epic = tool({
|
|
|
29906
29906
|
});
|
|
29907
29907
|
const epicResult = await runBdCommand(epicCmd.slice(1));
|
|
29908
29908
|
if (epicResult.exitCode !== 0) {
|
|
29909
|
-
throw new BeadError(`Failed to create epic: ${epicResult.stderr}
|
|
29909
|
+
throw new BeadError(`Failed to create epic because bd command failed: ${epicResult.stderr}. Try: Verify beads initialized with 'bd init', check if .beads/ directory is writable, or run 'bd list' to test basic functionality.`, epicCmd.join(" "), epicResult.exitCode);
|
|
29910
29910
|
}
|
|
29911
29911
|
const epic = parseBead(epicResult.stdout);
|
|
29912
29912
|
created.push(epic);
|
|
@@ -29924,7 +29924,7 @@ var beads_create_epic = tool({
|
|
|
29924
29924
|
});
|
|
29925
29925
|
const subtaskResult = await runBdCommand(subtaskCmd.slice(1));
|
|
29926
29926
|
if (subtaskResult.exitCode !== 0) {
|
|
29927
|
-
throw new BeadError(`Failed to create subtask: ${subtaskResult.stderr}
|
|
29927
|
+
throw new BeadError(`Failed to create subtask because bd command failed: ${subtaskResult.stderr}. Try: Check if parent epic exists with 'bd show ${epic.id}', verify .beads/issues.jsonl is not corrupted, or check for invalid characters in title.`, subtaskCmd.join(" "), subtaskResult.exitCode);
|
|
29928
29928
|
}
|
|
29929
29929
|
const subtaskBead = parseBead(subtaskResult.stdout);
|
|
29930
29930
|
created.push(subtaskBead);
|
|
@@ -29980,7 +29980,7 @@ ${rollbackErrors.join(`
|
|
|
29980
29980
|
|
|
29981
29981
|
No beads to rollback.`;
|
|
29982
29982
|
}
|
|
29983
|
-
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}
|
|
29983
|
+
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}. Try: If rollback failed, manually close beads with 'bd close <id> --reason "Rollback"', check .beads/issues.jsonl for partial state, or re-run beads_create_epic with corrected parameters.`, "beads_create_epic", 1);
|
|
29984
29984
|
}
|
|
29985
29985
|
}
|
|
29986
29986
|
});
|
|
@@ -30008,7 +30008,7 @@ var beads_query = tool({
|
|
|
30008
30008
|
}
|
|
30009
30009
|
const result = await runBdCommand(cmd.slice(1));
|
|
30010
30010
|
if (result.exitCode !== 0) {
|
|
30011
|
-
throw new BeadError(`Failed to query beads: ${result.stderr}
|
|
30011
|
+
throw new BeadError(`Failed to query beads because bd command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory exists, or run 'bd --version' to check CLI version.`, cmd.join(" "), result.exitCode);
|
|
30012
30012
|
}
|
|
30013
30013
|
const beads = parseBeads(result.stdout);
|
|
30014
30014
|
const limited = beads.slice(0, validated.limit);
|
|
@@ -30038,7 +30038,7 @@ var beads_update = tool({
|
|
|
30038
30038
|
cmd.push("--json");
|
|
30039
30039
|
const result = await runBdCommand(cmd.slice(1));
|
|
30040
30040
|
if (result.exitCode !== 0) {
|
|
30041
|
-
throw new BeadError(`Failed to update bead: ${result.stderr}
|
|
30041
|
+
throw new BeadError(`Failed to update bead because bd command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${validated.id}', check for invalid status values, or inspect .beads/issues.jsonl for corruption.`, cmd.join(" "), result.exitCode);
|
|
30042
30042
|
}
|
|
30043
30043
|
const bead = parseBead(result.stdout);
|
|
30044
30044
|
return JSON.stringify(bead, null, 2);
|
|
@@ -30062,7 +30062,7 @@ var beads_close = tool({
|
|
|
30062
30062
|
];
|
|
30063
30063
|
const result = await runBdCommand(cmd.slice(1));
|
|
30064
30064
|
if (result.exitCode !== 0) {
|
|
30065
|
-
throw new BeadError(`Failed to close bead: ${result.stderr}
|
|
30065
|
+
throw new BeadError(`Failed to close bead because bd command failed: ${result.stderr}. Try: Verify bead exists and is not already closed with 'beads_query(status="closed")' or 'bd show ${validated.id}', check if bead ID is correct.`, cmd.join(" "), result.exitCode);
|
|
30066
30066
|
}
|
|
30067
30067
|
const bead = parseBead(result.stdout);
|
|
30068
30068
|
return `Closed ${bead.id}: ${validated.reason}`;
|
|
@@ -30082,7 +30082,7 @@ var beads_start = tool({
|
|
|
30082
30082
|
"--json"
|
|
30083
30083
|
]);
|
|
30084
30084
|
if (result.exitCode !== 0) {
|
|
30085
|
-
throw new BeadError(`Failed to start bead: ${result.stderr}
|
|
30085
|
+
throw new BeadError(`Failed to start bead because bd update command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${args.id}', check if already in_progress with 'beads_query(status="in_progress")', or use beads_update directly.`, `bd update ${args.id} --status in_progress --json`, result.exitCode);
|
|
30086
30086
|
}
|
|
30087
30087
|
const bead = parseBead(result.stdout);
|
|
30088
30088
|
return `Started: ${bead.id}`;
|
|
@@ -30094,7 +30094,7 @@ var beads_ready = tool({
|
|
|
30094
30094
|
async execute(args, ctx) {
|
|
30095
30095
|
const result = await runBdCommand(["ready", "--json"]);
|
|
30096
30096
|
if (result.exitCode !== 0) {
|
|
30097
|
-
throw new BeadError(`Failed to get ready beads: ${result.stderr}
|
|
30097
|
+
throw new BeadError(`Failed to get ready beads because bd ready command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory is readable, or run 'bd list --json' to test basic query.`, "bd ready --json", result.exitCode);
|
|
30098
30098
|
}
|
|
30099
30099
|
const beads = parseBeads(result.stdout);
|
|
30100
30100
|
if (beads.length === 0) {
|
|
@@ -30127,7 +30127,7 @@ var beads_sync = tool({
|
|
|
30127
30127
|
};
|
|
30128
30128
|
const flushResult = await withTimeout(runBdCommand(["sync", "--flush-only"]), TIMEOUT_MS, "bd sync --flush-only");
|
|
30129
30129
|
if (flushResult.exitCode !== 0) {
|
|
30130
|
-
throw new BeadError(`Failed to flush beads: ${flushResult.stderr}
|
|
30130
|
+
throw new BeadError(`Failed to flush beads because bd sync failed: ${flushResult.stderr}. Try: Check if .beads/ directory is writable, verify no corrupted JSONL files, or run 'bd list' to test basic beads functionality.`, "bd sync --flush-only", flushResult.exitCode);
|
|
30131
30131
|
}
|
|
30132
30132
|
const beadsStatusResult = await runGitCommand([
|
|
30133
30133
|
"status",
|
|
@@ -30138,11 +30138,11 @@ var beads_sync = tool({
|
|
|
30138
30138
|
if (hasChanges) {
|
|
30139
30139
|
const addResult = await runGitCommand(["add", ".beads/"]);
|
|
30140
30140
|
if (addResult.exitCode !== 0) {
|
|
30141
|
-
throw new BeadError(`Failed to stage beads: ${addResult.stderr}
|
|
30141
|
+
throw new BeadError(`Failed to stage beads because git add failed: ${addResult.stderr}. Try: Check if .beads/ directory exists, verify git is initialized with 'git status', or check for .gitignore patterns blocking .beads/.`, "git add .beads/", addResult.exitCode);
|
|
30142
30142
|
}
|
|
30143
30143
|
const commitResult = await withTimeout(runGitCommand(["commit", "-m", "chore: sync beads"]), TIMEOUT_MS, "git commit");
|
|
30144
30144
|
if (commitResult.exitCode !== 0 && !commitResult.stdout.includes("nothing to commit")) {
|
|
30145
|
-
throw new BeadError(`Failed to commit beads: ${commitResult.stderr}
|
|
30145
|
+
throw new BeadError(`Failed to commit beads because git commit failed: ${commitResult.stderr}. Try: Check git config (user.name, user.email) with 'git config --list', verify working tree is clean, or check for pre-commit hooks blocking commit.`, "git commit", commitResult.exitCode);
|
|
30146
30146
|
}
|
|
30147
30147
|
}
|
|
30148
30148
|
if (autoPull) {
|
|
@@ -30181,7 +30181,7 @@ var beads_sync = tool({
|
|
|
30181
30181
|
}
|
|
30182
30182
|
}
|
|
30183
30183
|
if (pullResult.exitCode !== 0) {
|
|
30184
|
-
throw new BeadError(`Failed to pull: ${pullResult.stderr}
|
|
30184
|
+
throw new BeadError(`Failed to pull because git pull --rebase failed: ${pullResult.stderr}. Try: Resolve merge conflicts manually with 'git status', check if remote is accessible with 'git remote -v', or use skip_verification to bypass automatic pull.`, "git pull --rebase", pullResult.exitCode);
|
|
30185
30185
|
}
|
|
30186
30186
|
const importResult = await withTimeout(runBdCommand(["sync", "--import-only"]), TIMEOUT_MS, "bd sync --import-only");
|
|
30187
30187
|
if (importResult.exitCode !== 0) {
|
|
@@ -30190,7 +30190,7 @@ var beads_sync = tool({
|
|
|
30190
30190
|
}
|
|
30191
30191
|
const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
|
|
30192
30192
|
if (pushResult.exitCode !== 0) {
|
|
30193
|
-
throw new BeadError(`Failed to push: ${pushResult.stderr}
|
|
30193
|
+
throw new BeadError(`Failed to push because git push failed: ${pushResult.stderr}. Try: Check if remote branch is up to date with 'git pull --rebase', verify push permissions, check remote URL with 'git remote -v', or force push with 'git push --force-with-lease' if safe.`, "git push", pushResult.exitCode);
|
|
30194
30194
|
}
|
|
30195
30195
|
const statusResult = await runGitCommand(["status", "--porcelain"]);
|
|
30196
30196
|
const status = statusResult.stdout.trim();
|
|
@@ -30210,7 +30210,7 @@ var beads_link_thread = tool({
|
|
|
30210
30210
|
async execute(args, ctx) {
|
|
30211
30211
|
const queryResult = await runBdCommand(["show", args.bead_id, "--json"]);
|
|
30212
30212
|
if (queryResult.exitCode !== 0) {
|
|
30213
|
-
throw new BeadError(`Failed to get bead: ${queryResult.stderr}
|
|
30213
|
+
throw new BeadError(`Failed to get bead because bd show command failed: ${queryResult.stderr}. Try: Verify bead ID is correct with 'beads_query()', check if bead exists with 'bd list --json', or check .beads/issues.jsonl for valid entries.`, `bd show ${args.bead_id} --json`, queryResult.exitCode);
|
|
30214
30214
|
}
|
|
30215
30215
|
const bead = parseBead(queryResult.stdout);
|
|
30216
30216
|
const existingDesc = bead.description || "";
|
|
@@ -30229,7 +30229,7 @@ ${threadMarker}` : threadMarker;
|
|
|
30229
30229
|
"--json"
|
|
30230
30230
|
]);
|
|
30231
30231
|
if (updateResult.exitCode !== 0) {
|
|
30232
|
-
throw new BeadError(`Failed to update bead: ${updateResult.stderr}
|
|
30232
|
+
throw new BeadError(`Failed to update bead because bd update command failed: ${updateResult.stderr}. Try: Verify bead exists with 'bd show ${args.bead_id}', check for invalid characters in description, or inspect .beads/issues.jsonl for corruption.`, `bd update ${args.bead_id} -d ...`, updateResult.exitCode);
|
|
30233
30233
|
}
|
|
30234
30234
|
return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
|
|
30235
30235
|
}
|
|
@@ -33846,7 +33846,7 @@ async function runVerificationGate(filesTouched, skipUbs = false) {
|
|
|
33846
33846
|
};
|
|
33847
33847
|
if (!ubsStep.passed) {
|
|
33848
33848
|
ubsStep.error = `Found ${ubsResult.summary.critical} critical bugs`;
|
|
33849
|
-
blockers.push(`UBS
|
|
33849
|
+
blockers.push(`UBS found ${ubsResult.summary.critical} critical bug(s). Try: Run 'ubs scan ${filesTouched.join(" ")}' to see details, fix critical bugs in reported files, or use skip_ubs_scan=true to bypass (not recommended).`);
|
|
33850
33850
|
}
|
|
33851
33851
|
steps.push(ubsStep);
|
|
33852
33852
|
} else {
|
|
@@ -33863,12 +33863,12 @@ async function runVerificationGate(filesTouched, skipUbs = false) {
|
|
|
33863
33863
|
const typecheckStep = await runTypecheckVerification();
|
|
33864
33864
|
steps.push(typecheckStep);
|
|
33865
33865
|
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
33866
|
-
blockers.push(`Typecheck: ${typecheckStep.error?.slice(0, 100) || "
|
|
33866
|
+
blockers.push(`Typecheck failed: ${typecheckStep.error?.slice(0, 100) || "type errors found"}. Try: Run 'tsc --noEmit' to see full errors, check tsconfig.json configuration, or fix reported type errors in modified files.`);
|
|
33867
33867
|
}
|
|
33868
33868
|
const testStep = await runTestVerification(filesTouched);
|
|
33869
33869
|
steps.push(testStep);
|
|
33870
33870
|
if (!testStep.passed && !testStep.skipped) {
|
|
33871
|
-
blockers.push(`Tests: ${testStep.error?.slice(0, 100) || "
|
|
33871
|
+
blockers.push(`Tests failed: ${testStep.error?.slice(0, 100) || "test failures"}. Try: Run 'bun test ${testStep.command.split(" ").slice(2).join(" ")}' to see full output, check test assertions, or fix failing tests in modified files.`);
|
|
33872
33872
|
}
|
|
33873
33873
|
const passedCount = steps.filter((s) => s.passed).length;
|
|
33874
33874
|
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
@@ -33923,8 +33923,8 @@ async function runUbsScan(files) {
|
|
|
33923
33923
|
}
|
|
33924
33924
|
};
|
|
33925
33925
|
} catch (error45) {
|
|
33926
|
-
console.error(`[swarm] CRITICAL: UBS scan failed to parse JSON output:`, error45);
|
|
33927
|
-
console.error(`[swarm] Raw output
|
|
33926
|
+
console.error(`[swarm] CRITICAL: UBS scan failed to parse JSON output because output is malformed:`, error45);
|
|
33927
|
+
console.error(`[swarm] Raw output: ${output}. Try: Run 'ubs doctor' to check installation, verify UBS version with 'ubs --version' (need v1.0.0+), or check if UBS supports --json flag.`);
|
|
33928
33928
|
return {
|
|
33929
33929
|
exitCode: result.exitCode,
|
|
33930
33930
|
bugs: [],
|
|
@@ -34014,7 +34014,7 @@ var swarm_complete = tool({
|
|
|
34014
34014
|
error: s.error?.slice(0, 200)
|
|
34015
34015
|
}))
|
|
34016
34016
|
},
|
|
34017
|
-
hint: "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
34017
|
+
hint: verificationResult.blockers.length > 0 ? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.` : "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
34018
34018
|
gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
|
|
34019
34019
|
}, null, 2);
|
|
34020
34020
|
}
|
|
@@ -34025,12 +34025,12 @@ var swarm_complete = tool({
|
|
|
34025
34025
|
if (ubsResult && ubsResult.summary.critical > 0) {
|
|
34026
34026
|
return JSON.stringify({
|
|
34027
34027
|
success: false,
|
|
34028
|
-
error:
|
|
34028
|
+
error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
|
|
34029
34029
|
ubs_scan: {
|
|
34030
34030
|
critical_count: ubsResult.summary.critical,
|
|
34031
34031
|
bugs: ubsResult.bugs.filter((b) => b.severity === "critical")
|
|
34032
34032
|
},
|
|
34033
|
-
hint:
|
|
34033
|
+
hint: `Fix these critical bugs: ${ubsResult.bugs.filter((b) => b.severity === "critical").map((b) => `${b.file}:${b.line} - ${b.message}`).slice(0, 3).join("; ")}. Try: Run 'ubs scan ${args.files_touched?.join(" ") || "."} --json' for full report, fix reported issues, or use skip_ubs_scan=true to bypass (not recommended).`
|
|
34034
34034
|
}, null, 2);
|
|
34035
34035
|
}
|
|
34036
34036
|
}
|
|
@@ -34056,7 +34056,7 @@ var swarm_complete = tool({
|
|
|
34056
34056
|
}
|
|
34057
34057
|
const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
|
|
34058
34058
|
if (closeResult.exitCode !== 0) {
|
|
34059
|
-
throw new SwarmError(`Failed to close bead: ${closeResult.stderr.toString()}
|
|
34059
|
+
throw new SwarmError(`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`, "complete");
|
|
34060
34060
|
}
|
|
34061
34061
|
try {
|
|
34062
34062
|
await releaseSwarmFiles({
|
|
@@ -35234,7 +35234,7 @@ class SemanticMemoryMandateStorage {
|
|
|
35234
35234
|
async update(id, updates) {
|
|
35235
35235
|
const existing = await this.get(id);
|
|
35236
35236
|
if (!existing) {
|
|
35237
|
-
throw new Error(`Mandate ${id} not found
|
|
35237
|
+
throw new Error(`Mandate '${id}' not found. Use list() to see available mandates.`);
|
|
35238
35238
|
}
|
|
35239
35239
|
const updated = { ...existing, ...updates };
|
|
35240
35240
|
await this.store(updated);
|
|
@@ -35242,7 +35242,7 @@ class SemanticMemoryMandateStorage {
|
|
|
35242
35242
|
async vote(vote) {
|
|
35243
35243
|
const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
|
|
35244
35244
|
if (existing) {
|
|
35245
|
-
throw new Error(`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}
|
|
35245
|
+
throw new Error(`Agent '${vote.agent_name}' has already voted on mandate '${vote.mandate_id}'. Each agent can vote once per mandate to ensure fair consensus.`);
|
|
35246
35246
|
}
|
|
35247
35247
|
await this.storeInternal(this.config.collections.votes, vote, {
|
|
35248
35248
|
id: vote.id,
|
|
@@ -35333,7 +35333,7 @@ class InMemoryMandateStorage {
|
|
|
35333
35333
|
async update(id, updates) {
|
|
35334
35334
|
const existing = await this.get(id);
|
|
35335
35335
|
if (!existing) {
|
|
35336
|
-
throw new Error(`Mandate ${id} not found
|
|
35336
|
+
throw new Error(`Mandate '${id}' not found. Use list() to see available mandates.`);
|
|
35337
35337
|
}
|
|
35338
35338
|
const updated = { ...existing, ...updates };
|
|
35339
35339
|
this.entries.set(id, updated);
|
|
@@ -35341,7 +35341,7 @@ class InMemoryMandateStorage {
|
|
|
35341
35341
|
async vote(vote) {
|
|
35342
35342
|
const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
|
|
35343
35343
|
if (existing) {
|
|
35344
|
-
throw new Error(`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}
|
|
35344
|
+
throw new Error(`Agent '${vote.agent_name}' has already voted on mandate '${vote.mandate_id}'. Each agent can vote once per mandate to ensure fair consensus.`);
|
|
35345
35345
|
}
|
|
35346
35346
|
this.votes.set(vote.id, vote);
|
|
35347
35347
|
}
|
|
@@ -35396,13 +35396,13 @@ function createMandateStorage(config2 = {}) {
|
|
|
35396
35396
|
case "memory":
|
|
35397
35397
|
return new InMemoryMandateStorage(fullConfig);
|
|
35398
35398
|
default:
|
|
35399
|
-
throw new Error(`Unknown storage backend: ${fullConfig.backend}
|
|
35399
|
+
throw new Error(`Unknown storage backend: '${fullConfig.backend}'. Valid backends are 'semantic-memory' or 'memory'.`);
|
|
35400
35400
|
}
|
|
35401
35401
|
}
|
|
35402
35402
|
async function updateMandateStatus(mandateId, storage) {
|
|
35403
35403
|
const entry = await storage.get(mandateId);
|
|
35404
35404
|
if (!entry) {
|
|
35405
|
-
throw new Error(`Mandate ${mandateId} not found
|
|
35405
|
+
throw new Error(`Mandate '${mandateId}' not found when calculating score. Use storage.list() to verify the mandate exists.`);
|
|
35406
35406
|
}
|
|
35407
35407
|
const score = await storage.calculateScore(mandateId);
|
|
35408
35408
|
const previousStatus = entry.status;
|
|
@@ -35566,11 +35566,11 @@ var mandate_vote = tool({
|
|
|
35566
35566
|
const storage = getMandateStorage();
|
|
35567
35567
|
const mandate = await storage.get(validated.mandate_id);
|
|
35568
35568
|
if (!mandate) {
|
|
35569
|
-
throw new MandateError(`Mandate ${validated.mandate_id} not found
|
|
35569
|
+
throw new MandateError(`Mandate '${validated.mandate_id}' not found. Use mandate_list() to see available mandates, or check the ID is correct.`, "mandate_vote");
|
|
35570
35570
|
}
|
|
35571
35571
|
const hasVoted = await storage.hasVoted(validated.mandate_id, args.agent_name);
|
|
35572
35572
|
if (hasVoted) {
|
|
35573
|
-
throw new MandateError(`Agent ${args.agent_name} has already voted on mandate ${validated.mandate_id}
|
|
35573
|
+
throw new MandateError(`Agent '${args.agent_name}' has already voted on mandate '${validated.mandate_id}'. Each agent can vote once per mandate. This is expected behavior to prevent vote manipulation.`, "mandate_vote");
|
|
35574
35574
|
}
|
|
35575
35575
|
const vote = {
|
|
35576
35576
|
id: generateVoteId(),
|
|
@@ -35713,7 +35713,7 @@ var mandate_stats = tool({
|
|
|
35713
35713
|
if (args.mandate_id) {
|
|
35714
35714
|
const mandate = await storage.get(args.mandate_id);
|
|
35715
35715
|
if (!mandate) {
|
|
35716
|
-
throw new MandateError(`Mandate ${args.mandate_id} not found
|
|
35716
|
+
throw new MandateError(`Mandate '${args.mandate_id}' not found. Use mandate_list() to see available mandates, or check the ID is correct.`, "mandate_stats");
|
|
35717
35717
|
}
|
|
35718
35718
|
const score = await storage.calculateScore(args.mandate_id);
|
|
35719
35719
|
const votes = await storage.getVotes(args.mandate_id);
|
package/package.json
CHANGED
package/src/beads.ts
CHANGED
|
@@ -178,7 +178,10 @@ function parseBead(output: string): Bead {
|
|
|
178
178
|
// CLI commands like `bd close`, `bd update` return arrays even for single items
|
|
179
179
|
const data = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
180
180
|
if (!data) {
|
|
181
|
-
throw new BeadError(
|
|
181
|
+
throw new BeadError(
|
|
182
|
+
"No bead data in response. The bd CLI may not be installed or returned unexpected output. Try: Run 'bd --version' to verify installation, or check if .beads/ directory exists in project.",
|
|
183
|
+
"parse",
|
|
184
|
+
);
|
|
182
185
|
}
|
|
183
186
|
return BeadSchema.parse(data);
|
|
184
187
|
} catch (error) {
|
|
@@ -191,7 +194,10 @@ function parseBead(output: string): Bead {
|
|
|
191
194
|
if (error instanceof BeadError) {
|
|
192
195
|
throw error;
|
|
193
196
|
}
|
|
194
|
-
throw new BeadError(
|
|
197
|
+
throw new BeadError(
|
|
198
|
+
`Failed to parse bead JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`,
|
|
199
|
+
"parse",
|
|
200
|
+
);
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
|
|
@@ -209,7 +215,10 @@ function parseBeads(output: string): Bead[] {
|
|
|
209
215
|
error,
|
|
210
216
|
);
|
|
211
217
|
}
|
|
212
|
-
throw new BeadError(
|
|
218
|
+
throw new BeadError(
|
|
219
|
+
`Failed to parse beads JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`,
|
|
220
|
+
"parse",
|
|
221
|
+
);
|
|
213
222
|
}
|
|
214
223
|
}
|
|
215
224
|
|
|
@@ -249,7 +258,7 @@ export const beads_create = tool({
|
|
|
249
258
|
|
|
250
259
|
if (result.exitCode !== 0) {
|
|
251
260
|
throw new BeadError(
|
|
252
|
-
`Failed to create bead: ${result.stderr}
|
|
261
|
+
`Failed to create bead because bd command exited with code ${result.exitCode}. Error: ${result.stderr}. Try: Check if beads initialized with 'bd init' in project root, or verify .beads/ directory exists.`,
|
|
253
262
|
cmdParts.join(" "),
|
|
254
263
|
result.exitCode,
|
|
255
264
|
result.stderr,
|
|
@@ -260,7 +269,7 @@ export const beads_create = tool({
|
|
|
260
269
|
const stdout = result.stdout.trim();
|
|
261
270
|
if (!stdout) {
|
|
262
271
|
throw new BeadError(
|
|
263
|
-
"bd create returned empty output",
|
|
272
|
+
"bd create returned empty output because command produced no response. Try: Check if bd is properly installed with 'bd --version', or run 'bd list' to test basic functionality.",
|
|
264
273
|
cmdParts.join(" "),
|
|
265
274
|
0,
|
|
266
275
|
"Empty stdout",
|
|
@@ -270,7 +279,7 @@ export const beads_create = tool({
|
|
|
270
279
|
// Check for error messages in stdout (bd sometimes outputs errors to stdout)
|
|
271
280
|
if (stdout.startsWith("error:") || stdout.startsWith("Error:")) {
|
|
272
281
|
throw new BeadError(
|
|
273
|
-
`bd create failed: ${stdout}
|
|
282
|
+
`bd create failed because command returned error in stdout: ${stdout}. Try: Check error message above, verify beads initialized with 'bd init', or check .beads/issues.jsonl for corruption.`,
|
|
274
283
|
cmdParts.join(" "),
|
|
275
284
|
0,
|
|
276
285
|
stdout,
|
|
@@ -331,7 +340,7 @@ export const beads_create_epic = tool({
|
|
|
331
340
|
|
|
332
341
|
if (epicResult.exitCode !== 0) {
|
|
333
342
|
throw new BeadError(
|
|
334
|
-
`Failed to create epic: ${epicResult.stderr}
|
|
343
|
+
`Failed to create epic because bd command failed: ${epicResult.stderr}. Try: Verify beads initialized with 'bd init', check if .beads/ directory is writable, or run 'bd list' to test basic functionality.`,
|
|
335
344
|
epicCmd.join(" "),
|
|
336
345
|
epicResult.exitCode,
|
|
337
346
|
);
|
|
@@ -361,7 +370,7 @@ export const beads_create_epic = tool({
|
|
|
361
370
|
|
|
362
371
|
if (subtaskResult.exitCode !== 0) {
|
|
363
372
|
throw new BeadError(
|
|
364
|
-
`Failed to create subtask: ${subtaskResult.stderr}
|
|
373
|
+
`Failed to create subtask because bd command failed: ${subtaskResult.stderr}. Try: Check if parent epic exists with 'bd show ${epic.id}', verify .beads/issues.jsonl is not corrupted, or check for invalid characters in title.`,
|
|
365
374
|
subtaskCmd.join(" "),
|
|
366
375
|
subtaskResult.exitCode,
|
|
367
376
|
);
|
|
@@ -430,7 +439,7 @@ export const beads_create_epic = tool({
|
|
|
430
439
|
}
|
|
431
440
|
|
|
432
441
|
throw new BeadError(
|
|
433
|
-
`Epic creation failed: ${errorMsg}${rollbackInfo}
|
|
442
|
+
`Epic creation failed: ${errorMsg}${rollbackInfo}. Try: If rollback failed, manually close beads with 'bd close <id> --reason "Rollback"', check .beads/issues.jsonl for partial state, or re-run beads_create_epic with corrected parameters.`,
|
|
434
443
|
"beads_create_epic",
|
|
435
444
|
1,
|
|
436
445
|
);
|
|
@@ -482,7 +491,7 @@ export const beads_query = tool({
|
|
|
482
491
|
|
|
483
492
|
if (result.exitCode !== 0) {
|
|
484
493
|
throw new BeadError(
|
|
485
|
-
`Failed to query beads: ${result.stderr}
|
|
494
|
+
`Failed to query beads because bd command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory exists, or run 'bd --version' to check CLI version.`,
|
|
486
495
|
cmd.join(" "),
|
|
487
496
|
result.exitCode,
|
|
488
497
|
);
|
|
@@ -534,7 +543,7 @@ export const beads_update = tool({
|
|
|
534
543
|
|
|
535
544
|
if (result.exitCode !== 0) {
|
|
536
545
|
throw new BeadError(
|
|
537
|
-
`Failed to update bead: ${result.stderr}
|
|
546
|
+
`Failed to update bead because bd command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${validated.id}', check for invalid status values, or inspect .beads/issues.jsonl for corruption.`,
|
|
538
547
|
cmd.join(" "),
|
|
539
548
|
result.exitCode,
|
|
540
549
|
);
|
|
@@ -570,7 +579,7 @@ export const beads_close = tool({
|
|
|
570
579
|
|
|
571
580
|
if (result.exitCode !== 0) {
|
|
572
581
|
throw new BeadError(
|
|
573
|
-
`Failed to close bead: ${result.stderr}
|
|
582
|
+
`Failed to close bead because bd command failed: ${result.stderr}. Try: Verify bead exists and is not already closed with 'beads_query(status="closed")' or 'bd show ${validated.id}', check if bead ID is correct.`,
|
|
574
583
|
cmd.join(" "),
|
|
575
584
|
result.exitCode,
|
|
576
585
|
);
|
|
@@ -601,7 +610,7 @@ export const beads_start = tool({
|
|
|
601
610
|
|
|
602
611
|
if (result.exitCode !== 0) {
|
|
603
612
|
throw new BeadError(
|
|
604
|
-
`Failed to start bead: ${result.stderr}
|
|
613
|
+
`Failed to start bead because bd update command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${args.id}', check if already in_progress with 'beads_query(status="in_progress")', or use beads_update directly.`,
|
|
605
614
|
`bd update ${args.id} --status in_progress --json`,
|
|
606
615
|
result.exitCode,
|
|
607
616
|
);
|
|
@@ -623,7 +632,7 @@ export const beads_ready = tool({
|
|
|
623
632
|
|
|
624
633
|
if (result.exitCode !== 0) {
|
|
625
634
|
throw new BeadError(
|
|
626
|
-
`Failed to get ready beads: ${result.stderr}
|
|
635
|
+
`Failed to get ready beads because bd ready command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory is readable, or run 'bd list --json' to test basic query.`,
|
|
627
636
|
"bd ready --json",
|
|
628
637
|
result.exitCode,
|
|
629
638
|
);
|
|
@@ -696,7 +705,7 @@ export const beads_sync = tool({
|
|
|
696
705
|
);
|
|
697
706
|
if (flushResult.exitCode !== 0) {
|
|
698
707
|
throw new BeadError(
|
|
699
|
-
`Failed to flush beads: ${flushResult.stderr}
|
|
708
|
+
`Failed to flush beads because bd sync failed: ${flushResult.stderr}. Try: Check if .beads/ directory is writable, verify no corrupted JSONL files, or run 'bd list' to test basic beads functionality.`,
|
|
700
709
|
"bd sync --flush-only",
|
|
701
710
|
flushResult.exitCode,
|
|
702
711
|
);
|
|
@@ -715,7 +724,7 @@ export const beads_sync = tool({
|
|
|
715
724
|
const addResult = await runGitCommand(["add", ".beads/"]);
|
|
716
725
|
if (addResult.exitCode !== 0) {
|
|
717
726
|
throw new BeadError(
|
|
718
|
-
`Failed to stage beads: ${addResult.stderr}
|
|
727
|
+
`Failed to stage beads because git add failed: ${addResult.stderr}. Try: Check if .beads/ directory exists, verify git is initialized with 'git status', or check for .gitignore patterns blocking .beads/.`,
|
|
719
728
|
"git add .beads/",
|
|
720
729
|
addResult.exitCode,
|
|
721
730
|
);
|
|
@@ -732,7 +741,7 @@ export const beads_sync = tool({
|
|
|
732
741
|
!commitResult.stdout.includes("nothing to commit")
|
|
733
742
|
) {
|
|
734
743
|
throw new BeadError(
|
|
735
|
-
`Failed to commit beads: ${commitResult.stderr}
|
|
744
|
+
`Failed to commit beads because git commit failed: ${commitResult.stderr}. Try: Check git config (user.name, user.email) with 'git config --list', verify working tree is clean, or check for pre-commit hooks blocking commit.`,
|
|
736
745
|
"git commit",
|
|
737
746
|
commitResult.exitCode,
|
|
738
747
|
);
|
|
@@ -798,7 +807,7 @@ export const beads_sync = tool({
|
|
|
798
807
|
|
|
799
808
|
if (pullResult.exitCode !== 0) {
|
|
800
809
|
throw new BeadError(
|
|
801
|
-
`Failed to pull: ${pullResult.stderr}
|
|
810
|
+
`Failed to pull because git pull --rebase failed: ${pullResult.stderr}. Try: Resolve merge conflicts manually with 'git status', check if remote is accessible with 'git remote -v', or use skip_verification to bypass automatic pull.`,
|
|
802
811
|
"git pull --rebase",
|
|
803
812
|
pullResult.exitCode,
|
|
804
813
|
);
|
|
@@ -824,7 +833,7 @@ export const beads_sync = tool({
|
|
|
824
833
|
);
|
|
825
834
|
if (pushResult.exitCode !== 0) {
|
|
826
835
|
throw new BeadError(
|
|
827
|
-
`Failed to push: ${pushResult.stderr}
|
|
836
|
+
`Failed to push because git push failed: ${pushResult.stderr}. Try: Check if remote branch is up to date with 'git pull --rebase', verify push permissions, check remote URL with 'git remote -v', or force push with 'git push --force-with-lease' if safe.`,
|
|
828
837
|
"git push",
|
|
829
838
|
pushResult.exitCode,
|
|
830
839
|
);
|
|
@@ -858,7 +867,7 @@ export const beads_link_thread = tool({
|
|
|
858
867
|
|
|
859
868
|
if (queryResult.exitCode !== 0) {
|
|
860
869
|
throw new BeadError(
|
|
861
|
-
`Failed to get bead: ${queryResult.stderr}
|
|
870
|
+
`Failed to get bead because bd show command failed: ${queryResult.stderr}. Try: Verify bead ID is correct with 'beads_query()', check if bead exists with 'bd list --json', or check .beads/issues.jsonl for valid entries.`,
|
|
862
871
|
`bd show ${args.bead_id} --json`,
|
|
863
872
|
queryResult.exitCode,
|
|
864
873
|
);
|
|
@@ -887,7 +896,7 @@ export const beads_link_thread = tool({
|
|
|
887
896
|
|
|
888
897
|
if (updateResult.exitCode !== 0) {
|
|
889
898
|
throw new BeadError(
|
|
890
|
-
`Failed to update bead: ${updateResult.stderr}
|
|
899
|
+
`Failed to update bead because bd update command failed: ${updateResult.stderr}. Try: Verify bead exists with 'bd show ${args.bead_id}', check for invalid characters in description, or inspect .beads/issues.jsonl for corruption.`,
|
|
891
900
|
`bd update ${args.bead_id} -d ...`,
|
|
892
901
|
updateResult.exitCode,
|
|
893
902
|
);
|
package/src/mandate-storage.ts
CHANGED
|
@@ -383,7 +383,9 @@ export class SemanticMemoryMandateStorage implements MandateStorage {
|
|
|
383
383
|
async update(id: string, updates: Partial<MandateEntry>): Promise<void> {
|
|
384
384
|
const existing = await this.get(id);
|
|
385
385
|
if (!existing) {
|
|
386
|
-
throw new Error(
|
|
386
|
+
throw new Error(
|
|
387
|
+
`Mandate '${id}' not found. Use list() to see available mandates.`,
|
|
388
|
+
);
|
|
387
389
|
}
|
|
388
390
|
|
|
389
391
|
const updated = { ...existing, ...updates };
|
|
@@ -399,7 +401,7 @@ export class SemanticMemoryMandateStorage implements MandateStorage {
|
|
|
399
401
|
const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
|
|
400
402
|
if (existing) {
|
|
401
403
|
throw new Error(
|
|
402
|
-
`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}
|
|
404
|
+
`Agent '${vote.agent_name}' has already voted on mandate '${vote.mandate_id}'. Each agent can vote once per mandate to ensure fair consensus.`,
|
|
403
405
|
);
|
|
404
406
|
}
|
|
405
407
|
|
|
@@ -540,7 +542,9 @@ export class InMemoryMandateStorage implements MandateStorage {
|
|
|
540
542
|
async update(id: string, updates: Partial<MandateEntry>): Promise<void> {
|
|
541
543
|
const existing = await this.get(id);
|
|
542
544
|
if (!existing) {
|
|
543
|
-
throw new Error(
|
|
545
|
+
throw new Error(
|
|
546
|
+
`Mandate '${id}' not found. Use list() to see available mandates.`,
|
|
547
|
+
);
|
|
544
548
|
}
|
|
545
549
|
|
|
546
550
|
const updated = { ...existing, ...updates };
|
|
@@ -553,7 +557,7 @@ export class InMemoryMandateStorage implements MandateStorage {
|
|
|
553
557
|
const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
|
|
554
558
|
if (existing) {
|
|
555
559
|
throw new Error(
|
|
556
|
-
`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}
|
|
560
|
+
`Agent '${vote.agent_name}' has already voted on mandate '${vote.mandate_id}'. Each agent can vote once per mandate to ensure fair consensus.`,
|
|
557
561
|
);
|
|
558
562
|
}
|
|
559
563
|
|
|
@@ -662,7 +666,9 @@ export function createMandateStorage(
|
|
|
662
666
|
case "memory":
|
|
663
667
|
return new InMemoryMandateStorage(fullConfig);
|
|
664
668
|
default:
|
|
665
|
-
throw new Error(
|
|
669
|
+
throw new Error(
|
|
670
|
+
`Unknown storage backend: '${fullConfig.backend}'. Valid backends are 'semantic-memory' or 'memory'.`,
|
|
671
|
+
);
|
|
666
672
|
}
|
|
667
673
|
}
|
|
668
674
|
|
|
@@ -689,7 +695,9 @@ export async function updateMandateStatus(
|
|
|
689
695
|
): Promise<ScoreCalculationResult> {
|
|
690
696
|
const entry = await storage.get(mandateId);
|
|
691
697
|
if (!entry) {
|
|
692
|
-
throw new Error(
|
|
698
|
+
throw new Error(
|
|
699
|
+
`Mandate '${mandateId}' not found when calculating score. Use storage.list() to verify the mandate exists.`,
|
|
700
|
+
);
|
|
693
701
|
}
|
|
694
702
|
|
|
695
703
|
const score = await storage.calculateScore(mandateId);
|
package/src/mandates.ts
CHANGED
|
@@ -177,7 +177,7 @@ export const mandate_vote = tool({
|
|
|
177
177
|
const mandate = await storage.get(validated.mandate_id);
|
|
178
178
|
if (!mandate) {
|
|
179
179
|
throw new MandateError(
|
|
180
|
-
`Mandate ${validated.mandate_id} not found
|
|
180
|
+
`Mandate '${validated.mandate_id}' not found. Use mandate_list() to see available mandates, or check the ID is correct.`,
|
|
181
181
|
"mandate_vote",
|
|
182
182
|
);
|
|
183
183
|
}
|
|
@@ -189,7 +189,7 @@ export const mandate_vote = tool({
|
|
|
189
189
|
);
|
|
190
190
|
if (hasVoted) {
|
|
191
191
|
throw new MandateError(
|
|
192
|
-
`Agent ${args.agent_name} has already voted on mandate ${validated.mandate_id}
|
|
192
|
+
`Agent '${args.agent_name}' has already voted on mandate '${validated.mandate_id}'. Each agent can vote once per mandate. This is expected behavior to prevent vote manipulation.`,
|
|
193
193
|
"mandate_vote",
|
|
194
194
|
);
|
|
195
195
|
}
|
|
@@ -447,7 +447,7 @@ export const mandate_stats = tool({
|
|
|
447
447
|
const mandate = await storage.get(args.mandate_id);
|
|
448
448
|
if (!mandate) {
|
|
449
449
|
throw new MandateError(
|
|
450
|
-
`Mandate ${args.mandate_id} not found
|
|
450
|
+
`Mandate '${args.mandate_id}' not found. Use mandate_list() to see available mandates, or check the ID is correct.`,
|
|
451
451
|
"mandate_stats",
|
|
452
452
|
);
|
|
453
453
|
}
|
package/src/swarm.ts
CHANGED
|
@@ -2039,7 +2039,9 @@ async function runVerificationGate(
|
|
|
2039
2039
|
|
|
2040
2040
|
if (!ubsStep.passed) {
|
|
2041
2041
|
ubsStep.error = `Found ${ubsResult.summary.critical} critical bugs`;
|
|
2042
|
-
blockers.push(
|
|
2042
|
+
blockers.push(
|
|
2043
|
+
`UBS found ${ubsResult.summary.critical} critical bug(s). Try: Run 'ubs scan ${filesTouched.join(" ")}' to see details, fix critical bugs in reported files, or use skip_ubs_scan=true to bypass (not recommended).`,
|
|
2044
|
+
);
|
|
2043
2045
|
}
|
|
2044
2046
|
|
|
2045
2047
|
steps.push(ubsStep);
|
|
@@ -2060,7 +2062,7 @@ async function runVerificationGate(
|
|
|
2060
2062
|
steps.push(typecheckStep);
|
|
2061
2063
|
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
2062
2064
|
blockers.push(
|
|
2063
|
-
`Typecheck: ${typecheckStep.error?.slice(0, 100) || "
|
|
2065
|
+
`Typecheck failed: ${typecheckStep.error?.slice(0, 100) || "type errors found"}. Try: Run 'tsc --noEmit' to see full errors, check tsconfig.json configuration, or fix reported type errors in modified files.`,
|
|
2064
2066
|
);
|
|
2065
2067
|
}
|
|
2066
2068
|
|
|
@@ -2068,7 +2070,9 @@ async function runVerificationGate(
|
|
|
2068
2070
|
const testStep = await runTestVerification(filesTouched);
|
|
2069
2071
|
steps.push(testStep);
|
|
2070
2072
|
if (!testStep.passed && !testStep.skipped) {
|
|
2071
|
-
blockers.push(
|
|
2073
|
+
blockers.push(
|
|
2074
|
+
`Tests failed: ${testStep.error?.slice(0, 100) || "test failures"}. Try: Run 'bun test ${testStep.command.split(" ").slice(2).join(" ")}' to see full output, check test assertions, or fix failing tests in modified files.`,
|
|
2075
|
+
);
|
|
2072
2076
|
}
|
|
2073
2077
|
|
|
2074
2078
|
// Build summary
|
|
@@ -2150,10 +2154,12 @@ async function runUbsScan(files: string[]): Promise<UbsScanResult | null> {
|
|
|
2150
2154
|
} catch (error) {
|
|
2151
2155
|
// UBS output wasn't JSON - this is an error condition
|
|
2152
2156
|
console.error(
|
|
2153
|
-
`[swarm] CRITICAL: UBS scan failed to parse JSON output:`,
|
|
2157
|
+
`[swarm] CRITICAL: UBS scan failed to parse JSON output because output is malformed:`,
|
|
2154
2158
|
error,
|
|
2155
2159
|
);
|
|
2156
|
-
console.error(
|
|
2160
|
+
console.error(
|
|
2161
|
+
`[swarm] Raw output: ${output}. Try: Run 'ubs doctor' to check installation, verify UBS version with 'ubs --version' (need v1.0.0+), or check if UBS supports --json flag.`,
|
|
2162
|
+
);
|
|
2157
2163
|
return {
|
|
2158
2164
|
exitCode: result.exitCode,
|
|
2159
2165
|
bugs: [],
|
|
@@ -2320,7 +2326,10 @@ export const swarm_complete = tool({
|
|
|
2320
2326
|
error: s.error?.slice(0, 200),
|
|
2321
2327
|
})),
|
|
2322
2328
|
},
|
|
2323
|
-
hint:
|
|
2329
|
+
hint:
|
|
2330
|
+
verificationResult.blockers.length > 0
|
|
2331
|
+
? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.`
|
|
2332
|
+
: "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
2324
2333
|
gate_function:
|
|
2325
2334
|
"IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)",
|
|
2326
2335
|
},
|
|
@@ -2345,12 +2354,18 @@ export const swarm_complete = tool({
|
|
|
2345
2354
|
return JSON.stringify(
|
|
2346
2355
|
{
|
|
2347
2356
|
success: false,
|
|
2348
|
-
error:
|
|
2357
|
+
error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
|
|
2349
2358
|
ubs_scan: {
|
|
2350
2359
|
critical_count: ubsResult.summary.critical,
|
|
2351
2360
|
bugs: ubsResult.bugs.filter((b) => b.severity === "critical"),
|
|
2352
2361
|
},
|
|
2353
|
-
hint:
|
|
2362
|
+
hint: `Fix these critical bugs: ${ubsResult.bugs
|
|
2363
|
+
.filter((b) => b.severity === "critical")
|
|
2364
|
+
.map((b) => `${b.file}:${b.line} - ${b.message}`)
|
|
2365
|
+
.slice(0, 3)
|
|
2366
|
+
.join(
|
|
2367
|
+
"; ",
|
|
2368
|
+
)}. Try: Run 'ubs scan ${args.files_touched?.join(" ") || "."} --json' for full report, fix reported issues, or use skip_ubs_scan=true to bypass (not recommended).`,
|
|
2354
2369
|
},
|
|
2355
2370
|
null,
|
|
2356
2371
|
2,
|
|
@@ -2398,7 +2413,7 @@ export const swarm_complete = tool({
|
|
|
2398
2413
|
|
|
2399
2414
|
if (closeResult.exitCode !== 0) {
|
|
2400
2415
|
throw new SwarmError(
|
|
2401
|
-
`Failed to close bead: ${closeResult.stderr.toString()}
|
|
2416
|
+
`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`,
|
|
2402
2417
|
"complete",
|
|
2403
2418
|
);
|
|
2404
2419
|
}
|