opencode-beads 0.1.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/LICENSE +9 -0
- package/README.md +53 -0
- package/package.json +37 -0
- package/src/plugin.ts +145 -0
- package/src/vendor.ts +155 -0
- package/vendor/agents/task-agent.md +60 -0
- package/vendor/commands/blocked.md +15 -0
- package/vendor/commands/close.md +18 -0
- package/vendor/commands/comments.md +28 -0
- package/vendor/commands/compact.md +31 -0
- package/vendor/commands/create.md +19 -0
- package/vendor/commands/daemon.md +58 -0
- package/vendor/commands/daemons.md +242 -0
- package/vendor/commands/delete.md +32 -0
- package/vendor/commands/dep.md +101 -0
- package/vendor/commands/epic.md +26 -0
- package/vendor/commands/export.md +24 -0
- package/vendor/commands/import.md +36 -0
- package/vendor/commands/init.md +18 -0
- package/vendor/commands/label.md +33 -0
- package/vendor/commands/list.md +64 -0
- package/vendor/commands/prime.md +7 -0
- package/vendor/commands/quickstart.md +17 -0
- package/vendor/commands/ready.md +15 -0
- package/vendor/commands/rename-prefix.md +24 -0
- package/vendor/commands/reopen.md +22 -0
- package/vendor/commands/restore.md +28 -0
- package/vendor/commands/search.md +103 -0
- package/vendor/commands/show.md +17 -0
- package/vendor/commands/stats.md +17 -0
- package/vendor/commands/sync.md +54 -0
- package/vendor/commands/template.md +337 -0
- package/vendor/commands/update.md +22 -0
- package/vendor/commands/version.md +26 -0
- package/vendor/commands/workflow.md +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Josh Thomas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# opencode-beads
|
|
2
|
+
|
|
3
|
+
[Beads](https://github.com/steveyegge/beads) issue tracker integration for [OpenCode](https://opencode.ai).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install the beads CLI:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
See the [beads installation guide](https://github.com/steveyegge/beads/blob/main/docs/INSTALLING.md) for alternative methods (Homebrew, Windows, AUR, etc.).
|
|
14
|
+
|
|
15
|
+
Add to your `opencode.json`:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"plugin": ["opencode-beads"]
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- **Context injection** - Automatically runs `bd prime` on session start and after compaction, keeping your agent aware of current issues
|
|
26
|
+
- **Commands** - All beads operations available as `/bd-*` commands
|
|
27
|
+
- **Task agent** - Autonomous issue completion via `beads-task-agent` subagent
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
This plugin brings beads into OpenCode. For learning how to use beads itself - workflows, commands, best practices - see the [beads documentation](https://github.com/steveyegge/beads).
|
|
32
|
+
|
|
33
|
+
The plugin automatically injects beads context on session start and after compaction, so your agent stays oriented.
|
|
34
|
+
|
|
35
|
+
## Commands
|
|
36
|
+
|
|
37
|
+
Commands are available as `/bd-*` and mirror the `bd` CLI. See the [beads documentation](https://github.com/steveyegge/beads) for the full command reference.
|
|
38
|
+
|
|
39
|
+
## Agent
|
|
40
|
+
|
|
41
|
+
### beads-task-agent
|
|
42
|
+
|
|
43
|
+
A subagent for autonomous issue completion. Designed to work through issues independently, updating status and handling dependencies.
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
opencode-beads is licensed under the MIT license. See the [`LICENSE`](LICENSE) file for more information.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
opencode-beads is not built by, or affiliated with, the OpenCode team.
|
|
52
|
+
|
|
53
|
+
OpenCode is ©2025 Anomaly.
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-beads",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A plugin for OpenCode that provides integration with the beads issue tracker.",
|
|
6
|
+
"author": "Josh Thomas <josh@joshthomas.dev>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/joshuadavidthomas/opencode-beads"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"opencode",
|
|
14
|
+
"plugin",
|
|
15
|
+
"beads",
|
|
16
|
+
"agent",
|
|
17
|
+
"ai"
|
|
18
|
+
],
|
|
19
|
+
"main": "src/plugin.ts",
|
|
20
|
+
"files": ["src", "vendor", "README.md"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@opencode-ai/plugin": "^1.0.143",
|
|
26
|
+
"@opencode-ai/sdk": "^1.0.143",
|
|
27
|
+
"zod": "^4.1.13"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/bun": "latest",
|
|
31
|
+
"@types/node": "^22.0.0",
|
|
32
|
+
"typescript": "~5.9.3"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"bun": ">=1.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/plugin.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Beads Plugin
|
|
3
|
+
*
|
|
4
|
+
* Integrates the beads issue tracker with OpenCode.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Context injection via `bd prime` on session start and after compaction
|
|
8
|
+
* - Commands parsed from beads command definitions
|
|
9
|
+
* - Task agent for autonomous issue completion
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Plugin, PluginInput } from "@opencode-ai/plugin";
|
|
13
|
+
import { CLI_GUIDANCE, loadAgent, loadCommands } from "./vendor";
|
|
14
|
+
|
|
15
|
+
type OpencodeClient = PluginInput["client"];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the current model/agent context for a session by querying messages.
|
|
19
|
+
*
|
|
20
|
+
* Mirrors OpenCode's internal lastModel() logic to find the most recent
|
|
21
|
+
* user message. Used during event handling when we don't have direct access
|
|
22
|
+
* to the current user message's context.
|
|
23
|
+
*/
|
|
24
|
+
async function getSessionContext(
|
|
25
|
+
client: OpencodeClient,
|
|
26
|
+
sessionID: string
|
|
27
|
+
): Promise<
|
|
28
|
+
{ model?: { providerID: string; modelID: string }; agent?: string } | undefined
|
|
29
|
+
> {
|
|
30
|
+
try {
|
|
31
|
+
const response = await client.session.messages({
|
|
32
|
+
path: { id: sessionID },
|
|
33
|
+
query: { limit: 50 },
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (response.data) {
|
|
37
|
+
for (const msg of response.data) {
|
|
38
|
+
if (msg.info.role === "user" && "model" in msg.info && msg.info.model) {
|
|
39
|
+
return { model: msg.info.model, agent: msg.info.agent };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
// On error, return undefined (let opencode use its default)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Inject beads context into a session.
|
|
52
|
+
*
|
|
53
|
+
* Runs `bd prime` and injects the output along with CLI guidance.
|
|
54
|
+
* Silently skips if bd is not installed or not initialized.
|
|
55
|
+
*/
|
|
56
|
+
async function injectBeadsContext(
|
|
57
|
+
client: OpencodeClient,
|
|
58
|
+
$: PluginInput["$"],
|
|
59
|
+
sessionID: string,
|
|
60
|
+
context?: { model?: { providerID: string; modelID: string }; agent?: string }
|
|
61
|
+
): Promise<void> {
|
|
62
|
+
try {
|
|
63
|
+
const primeOutput = await $`bd prime`.text();
|
|
64
|
+
|
|
65
|
+
if (!primeOutput || primeOutput.trim() === "") {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const beadsContext = `<beads-context>
|
|
70
|
+
${primeOutput.trim()}
|
|
71
|
+
</beads-context>
|
|
72
|
+
|
|
73
|
+
${CLI_GUIDANCE}`;
|
|
74
|
+
|
|
75
|
+
// Inject content via noReply + synthetic
|
|
76
|
+
// Must pass model and agent to prevent mode/model switching
|
|
77
|
+
await client.session.prompt({
|
|
78
|
+
path: { id: sessionID },
|
|
79
|
+
body: {
|
|
80
|
+
noReply: true,
|
|
81
|
+
model: context?.model,
|
|
82
|
+
agent: context?.agent,
|
|
83
|
+
parts: [{ type: "text", text: beadsContext, synthetic: true }],
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
} catch {
|
|
87
|
+
// Silent skip if bd prime fails (not installed or not initialized)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
export const BeadsPlugin: Plugin = async ({ client, $ }) => {
|
|
93
|
+
const [commands, agents] = await Promise.all([loadCommands(), loadAgent()]);
|
|
94
|
+
|
|
95
|
+
const injectedSessions = new Set<string>();
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
"chat.message": async (_input, output) => {
|
|
99
|
+
const sessionID = output.message.sessionID;
|
|
100
|
+
|
|
101
|
+
// Skip if already injected this session
|
|
102
|
+
if (injectedSessions.has(sessionID)) return;
|
|
103
|
+
|
|
104
|
+
// Check if session already has messages (handles plugin reload/reconnection)
|
|
105
|
+
try {
|
|
106
|
+
const existing = await client.session.messages({
|
|
107
|
+
path: { id: sessionID },
|
|
108
|
+
query: { limit: 1 },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (existing.data && existing.data.length > 0) {
|
|
112
|
+
injectedSessions.add(sessionID);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
} catch {
|
|
116
|
+
// On error, proceed with injection
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
injectedSessions.add(sessionID);
|
|
120
|
+
|
|
121
|
+
// Use output.message which has the resolved model/agent values
|
|
122
|
+
// This ensures our injected noReply message has identical model/agent
|
|
123
|
+
// to the real user message, preventing mode/model switching
|
|
124
|
+
await injectBeadsContext(client, $, sessionID, {
|
|
125
|
+
model: output.message.model,
|
|
126
|
+
agent: output.message.agent,
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
event: async ({ event }) => {
|
|
131
|
+
if (event.type === "session.compacted") {
|
|
132
|
+
const sessionID = event.properties.sessionID;
|
|
133
|
+
const context = await getSessionContext(client, sessionID);
|
|
134
|
+
await injectBeadsContext(client, $, sessionID, context);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
config: async (config) => {
|
|
139
|
+
config.command = { ...config.command, ...commands };
|
|
140
|
+
config.agent = { ...config.agent, ...agents };
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default BeadsPlugin;
|
package/src/vendor.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendor file loaders for beads plugin.
|
|
3
|
+
*
|
|
4
|
+
* The vendor directory contains beads command definitions and agent prompts
|
|
5
|
+
* synced from the upstream beads repository via scripts/sync-beads.sh.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as fs from "node:fs/promises";
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import type { Config } from "@opencode-ai/sdk";
|
|
12
|
+
|
|
13
|
+
function getVendorDir(): string {
|
|
14
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
return path.join(__dirname, "..", "vendor");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ParsedMarkdown {
|
|
19
|
+
frontmatter: Record<string, string | undefined>;
|
|
20
|
+
body: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseMarkdownWithFrontmatter(content: string): ParsedMarkdown | null {
|
|
24
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
|
|
25
|
+
const match = content.match(frontmatterRegex);
|
|
26
|
+
|
|
27
|
+
if (!match) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const frontmatterStr = match[1];
|
|
32
|
+
const body = match[2];
|
|
33
|
+
|
|
34
|
+
if (frontmatterStr === undefined || body === undefined) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const frontmatter: Record<string, string | undefined> = {};
|
|
39
|
+
|
|
40
|
+
for (const line of frontmatterStr.split("\n")) {
|
|
41
|
+
const trimmed = line.trim();
|
|
42
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
43
|
+
|
|
44
|
+
const colonIndex = trimmed.indexOf(":");
|
|
45
|
+
if (colonIndex === -1) continue;
|
|
46
|
+
|
|
47
|
+
const key = trimmed.slice(0, colonIndex).trim();
|
|
48
|
+
let value = trimmed.slice(colonIndex + 1).trim();
|
|
49
|
+
|
|
50
|
+
// Handle quoted strings
|
|
51
|
+
if (
|
|
52
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
53
|
+
(value.startsWith("'") && value.endsWith("'"))
|
|
54
|
+
) {
|
|
55
|
+
value = value.slice(1, -1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Handle empty array syntax like []
|
|
59
|
+
if (value === "[]") {
|
|
60
|
+
value = "";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
frontmatter[key] = value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { frontmatter, body: body.trim() };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function readVendorFile(relativePath: string): Promise<string | null> {
|
|
70
|
+
try {
|
|
71
|
+
const fullPath = path.join(getVendorDir(), relativePath);
|
|
72
|
+
return await fs.readFile(fullPath, "utf-8");
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function listVendorFiles(relativePath: string): Promise<string[]> {
|
|
79
|
+
try {
|
|
80
|
+
const fullPath = path.join(getVendorDir(), relativePath);
|
|
81
|
+
return await fs.readdir(fullPath);
|
|
82
|
+
} catch {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const CLI_GUIDANCE = `<beads-cli-guidance>
|
|
88
|
+
Beads MCP tools are not available. Use the \`bd\` CLI via bash instead:
|
|
89
|
+
|
|
90
|
+
- \`init\` → \`bd init [prefix]\`
|
|
91
|
+
- \`ready\` → \`bd ready --json\`
|
|
92
|
+
- \`show\` → \`bd show <id> --json\`
|
|
93
|
+
- \`create\` → \`bd create "title" -t bug|feature|task -p 0-4 --json\`
|
|
94
|
+
- \`update\` → \`bd update <id> --status in_progress --json\`
|
|
95
|
+
- \`close\` → \`bd close <id> --reason "message" --json\`
|
|
96
|
+
- \`reopen\` → \`bd reopen <id> --json\`
|
|
97
|
+
- \`dep\` → \`bd dep add <from> <to> --type blocks|discovered-from --json\`
|
|
98
|
+
- \`list\` → \`bd list --status open --json\`
|
|
99
|
+
- \`blocked\` → \`bd blocked --json\`
|
|
100
|
+
- \`stats\` → \`bd stats --json\`
|
|
101
|
+
- \`sync\` → \`bd sync\`
|
|
102
|
+
|
|
103
|
+
MCP tools map directly to bd CLI commands. If a tool is not listed above, try \`bd <tool> --help\`.
|
|
104
|
+
|
|
105
|
+
Always use \`--json\` flag for structured output.
|
|
106
|
+
</beads-cli-guidance>`;
|
|
107
|
+
|
|
108
|
+
export async function loadAgent(): Promise<Config["agent"]> {
|
|
109
|
+
const content = await readVendorFile("agents/task-agent.md");
|
|
110
|
+
if (!content) return {};
|
|
111
|
+
|
|
112
|
+
const parsed = parseMarkdownWithFrontmatter(content);
|
|
113
|
+
if (!parsed) return {};
|
|
114
|
+
|
|
115
|
+
const description =
|
|
116
|
+
parsed.frontmatter.description ?? "Beads task completion agent";
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
"beads-task-agent": {
|
|
120
|
+
description,
|
|
121
|
+
prompt: CLI_GUIDANCE + "\n" + parsed.body,
|
|
122
|
+
mode: "subagent",
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export async function loadCommands(): Promise<Config["command"]> {
|
|
128
|
+
const files = await listVendorFiles("commands");
|
|
129
|
+
const commands: Config["command"] = {};
|
|
130
|
+
|
|
131
|
+
for (const file of files) {
|
|
132
|
+
if (!file.endsWith(".md")) continue;
|
|
133
|
+
|
|
134
|
+
const content = await readVendorFile(`commands/${file}`);
|
|
135
|
+
if (!content) continue;
|
|
136
|
+
|
|
137
|
+
const parsed = parseMarkdownWithFrontmatter(content);
|
|
138
|
+
if (!parsed) continue;
|
|
139
|
+
|
|
140
|
+
const name = `bd-${file.replace(".md", "")}`;
|
|
141
|
+
|
|
142
|
+
const argHint = parsed.frontmatter["argument-hint"];
|
|
143
|
+
const baseDescription = parsed.frontmatter.description ?? name;
|
|
144
|
+
const description = argHint
|
|
145
|
+
? `${baseDescription} (${argHint})`
|
|
146
|
+
: baseDescription;
|
|
147
|
+
|
|
148
|
+
commands[name] = {
|
|
149
|
+
description,
|
|
150
|
+
template: parsed.body,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return commands;
|
|
155
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Autonomous agent that finds and completes ready tasks
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are a task-completion agent for beads. Your goal is to find ready work and complete it autonomously.
|
|
6
|
+
|
|
7
|
+
# Agent Workflow
|
|
8
|
+
|
|
9
|
+
1. **Find Ready Work**
|
|
10
|
+
- Use the `ready` MCP tool to get unblocked tasks
|
|
11
|
+
- Prefer higher priority tasks (P0 > P1 > P2 > P3 > P4)
|
|
12
|
+
- If no ready tasks, report completion
|
|
13
|
+
|
|
14
|
+
2. **Claim the Task**
|
|
15
|
+
- Use the `show` tool to get full task details
|
|
16
|
+
- Use the `update` tool to set status to `in_progress`
|
|
17
|
+
- Report what you're working on
|
|
18
|
+
|
|
19
|
+
3. **Execute the Task**
|
|
20
|
+
- Read the task description carefully
|
|
21
|
+
- Use available tools to complete the work
|
|
22
|
+
- Follow best practices from project documentation
|
|
23
|
+
- Run tests if applicable
|
|
24
|
+
|
|
25
|
+
4. **Track Discoveries**
|
|
26
|
+
- If you find bugs, TODOs, or related work:
|
|
27
|
+
- Use `create` tool to file new issues
|
|
28
|
+
- Use `dep` tool with `discovered-from` to link them
|
|
29
|
+
- This maintains context for future work
|
|
30
|
+
|
|
31
|
+
5. **Complete the Task**
|
|
32
|
+
- Verify the work is done correctly
|
|
33
|
+
- Use `close` tool with a clear completion message
|
|
34
|
+
- Report what was accomplished
|
|
35
|
+
|
|
36
|
+
6. **Continue**
|
|
37
|
+
- Check for newly unblocked work with `ready`
|
|
38
|
+
- Repeat the cycle
|
|
39
|
+
|
|
40
|
+
# Important Guidelines
|
|
41
|
+
|
|
42
|
+
- Always update issue status (`in_progress` when starting, close when done)
|
|
43
|
+
- Link discovered work with `discovered-from` dependencies
|
|
44
|
+
- Don't close issues unless work is actually complete
|
|
45
|
+
- If blocked, use `update` to set status to `blocked` and explain why
|
|
46
|
+
- Communicate clearly about progress and blockers
|
|
47
|
+
|
|
48
|
+
# Available Tools
|
|
49
|
+
|
|
50
|
+
Via beads MCP server:
|
|
51
|
+
- `ready` - Find unblocked tasks
|
|
52
|
+
- `show` - Get task details
|
|
53
|
+
- `update` - Update task status/fields
|
|
54
|
+
- `create` - Create new issues
|
|
55
|
+
- `dep` - Manage dependencies
|
|
56
|
+
- `close` - Complete tasks
|
|
57
|
+
- `blocked` - Check blocked issues
|
|
58
|
+
- `stats` - View project stats
|
|
59
|
+
|
|
60
|
+
You are autonomous but should communicate your progress clearly. Start by finding ready work!
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show blocked issues
|
|
3
|
+
argument-hint: []
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Show all issues that are blocked by dependencies.
|
|
7
|
+
|
|
8
|
+
Use `bd blocked` to see which issues have blockers preventing them from being worked on. This is the inverse of `bd ready` - it shows what's NOT ready.
|
|
9
|
+
|
|
10
|
+
Blocked issues have one or more dependencies with type "blocks" that are still open. Once all blocking dependencies are closed, the issue becomes ready and will appear in `bd ready`.
|
|
11
|
+
|
|
12
|
+
Useful for:
|
|
13
|
+
- Understanding why work is stuck
|
|
14
|
+
- Identifying critical path items
|
|
15
|
+
- Planning dependency resolution
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Close a completed issue
|
|
3
|
+
argument-hint: [issue-id] [reason]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Close a beads issue that's been completed.
|
|
7
|
+
|
|
8
|
+
If arguments are provided:
|
|
9
|
+
- $1: Issue ID
|
|
10
|
+
- $2+: Completion reason (optional)
|
|
11
|
+
|
|
12
|
+
If the issue ID is missing, ask for it. Optionally ask for a reason describing what was done.
|
|
13
|
+
|
|
14
|
+
Use the beads MCP `close` tool to close the issue. Show confirmation with the issue details.
|
|
15
|
+
|
|
16
|
+
After closing, suggest checking for:
|
|
17
|
+
- Dependent issues that might now be unblocked (use `ready` tool)
|
|
18
|
+
- New work discovered during this task (use `create` tool with `discovered-from` link)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: View or manage comments on an issue
|
|
3
|
+
argument-hint: [issue-id]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
View or add comments to a beads issue.
|
|
7
|
+
|
|
8
|
+
## View Comments
|
|
9
|
+
|
|
10
|
+
To view all comments on an issue:
|
|
11
|
+
- $1: Issue ID (e.g., bd-123)
|
|
12
|
+
|
|
13
|
+
Use the beads CLI `bd comments <issue-id>` to list all comments. Show them to the user with timestamps and authors.
|
|
14
|
+
|
|
15
|
+
## Add Comment
|
|
16
|
+
|
|
17
|
+
To add a comment:
|
|
18
|
+
- $1: "add"
|
|
19
|
+
- $2: Issue ID
|
|
20
|
+
- $3: Comment text (or use -f flag for file input)
|
|
21
|
+
|
|
22
|
+
Use `bd comments add <issue-id> "comment text"` to add a comment. Confirm the comment was added successfully.
|
|
23
|
+
|
|
24
|
+
Comments are useful for:
|
|
25
|
+
- Progress updates during work
|
|
26
|
+
- Design notes or technical decisions
|
|
27
|
+
- Links to related resources
|
|
28
|
+
- Questions or blockers
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Compact old closed issues using semantic summarization
|
|
3
|
+
argument-hint: [--all] [--id issue-id] [--dry-run]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Reduce database size by summarizing closed issues no longer actively referenced.
|
|
7
|
+
|
|
8
|
+
## Compaction Tiers
|
|
9
|
+
|
|
10
|
+
- **Tier 1**: Semantic compression (30+ days closed, ~70% size reduction)
|
|
11
|
+
- **Tier 2**: Ultra compression (90+ days closed, ~95% size reduction)
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
- **Preview candidates**: `bd compact --dry-run`
|
|
16
|
+
- **Compact all eligible**: `bd compact --all`
|
|
17
|
+
- **Compact specific issue**: `bd compact --id bd-42`
|
|
18
|
+
- **Force compact**: `bd compact --id bd-42 --force` (bypass age checks)
|
|
19
|
+
- **View statistics**: `bd compact --stats`
|
|
20
|
+
|
|
21
|
+
## Options
|
|
22
|
+
|
|
23
|
+
- **--tier**: Choose compaction tier (1 or 2, default: 1)
|
|
24
|
+
- **--workers**: Parallel workers (default: 5)
|
|
25
|
+
- **--batch-size**: Issues per batch (default: 10)
|
|
26
|
+
|
|
27
|
+
## Important
|
|
28
|
+
|
|
29
|
+
This is **permanent graceful decay** - original content is discarded. Use `bd restore <id>` to view full history from git if needed.
|
|
30
|
+
|
|
31
|
+
Useful for long-running projects to keep database size manageable.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new issue interactively
|
|
3
|
+
argument-hint: [title] [type] [priority]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Create a new beads issue. If arguments are provided:
|
|
7
|
+
- $1: Issue title
|
|
8
|
+
- $2: Issue type (bug, feature, task, epic, chore)
|
|
9
|
+
- $3: Priority (0-4, where 0=critical, 4=backlog)
|
|
10
|
+
|
|
11
|
+
If arguments are missing, ask the user for:
|
|
12
|
+
1. Issue title (required)
|
|
13
|
+
2. Issue type (default: task)
|
|
14
|
+
3. Priority (default: 2)
|
|
15
|
+
4. Description (optional)
|
|
16
|
+
|
|
17
|
+
Use the beads MCP `create` tool to create the issue. Show the created issue ID and details to the user.
|
|
18
|
+
|
|
19
|
+
Optionally ask if this issue should be linked to another issue (discovered-from, blocks, parent-child, related).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manage background sync daemon
|
|
3
|
+
argument-hint: [--start] [--stop] [--status] [--health]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Manage the per-project background daemon that handles database connections and syncs with git.
|
|
7
|
+
|
|
8
|
+
## Per-Project Daemon (LSP Model)
|
|
9
|
+
|
|
10
|
+
Each project runs its own daemon at `.beads/bd.sock` for complete database isolation.
|
|
11
|
+
|
|
12
|
+
> On Windows this file stores the daemon's loopback TCP endpoint metadata—leave it in place so bd can reconnect.
|
|
13
|
+
|
|
14
|
+
**Why per-project daemons?**
|
|
15
|
+
- Complete database isolation between projects
|
|
16
|
+
- No cross-project pollution or git worktree conflicts
|
|
17
|
+
- Simpler mental model: one project = one database = one daemon
|
|
18
|
+
- Follows LSP (Language Server Protocol) architecture
|
|
19
|
+
|
|
20
|
+
**Note:** Global daemon support was removed in v0.16.0. The `--global` flag is no longer functional.
|
|
21
|
+
|
|
22
|
+
## When to Use Daemon Mode
|
|
23
|
+
|
|
24
|
+
**✅ You SHOULD use daemon mode if:**
|
|
25
|
+
- Working in a team with git remote sync
|
|
26
|
+
- Want automatic commit/push of issue changes
|
|
27
|
+
- Need background auto-sync (5-second debounce)
|
|
28
|
+
- Making frequent bd commands (performance benefit from connection pooling)
|
|
29
|
+
|
|
30
|
+
**❌ You DON'T need daemon mode if:**
|
|
31
|
+
- Solo developer with local-only tracking
|
|
32
|
+
- Working in git worktrees (use --no-daemon to avoid conflicts)
|
|
33
|
+
- Running one-off commands or scripts
|
|
34
|
+
- Debugging database issues (direct mode is simpler)
|
|
35
|
+
|
|
36
|
+
**Local-only users:** Direct mode (default without daemon) is perfectly fine. The daemon mainly helps with git sync automation. You can still use `bd sync` manually when needed.
|
|
37
|
+
|
|
38
|
+
**Performance note:** For most operations, the daemon provides minimal performance benefit. The main value is automatic JSONL export (5s debounce) and optional git sync (--auto-commit, --auto-push).
|
|
39
|
+
|
|
40
|
+
## Common Operations
|
|
41
|
+
|
|
42
|
+
- **Start**: `bd daemon --start` (or auto-starts on first `bd` command)
|
|
43
|
+
- **Stop**: `bd daemon --stop`
|
|
44
|
+
- **Status**: `bd daemon --status`
|
|
45
|
+
- **Health**: `bd daemon --health` - shows uptime, cache stats, performance metrics
|
|
46
|
+
- **Metrics**: `bd daemon --metrics` - detailed operational telemetry
|
|
47
|
+
|
|
48
|
+
## Sync Options
|
|
49
|
+
|
|
50
|
+
- **--auto-commit**: Automatically commit JSONL changes
|
|
51
|
+
- **--auto-push**: Automatically push commits to remote
|
|
52
|
+
- **--interval**: Sync check interval (default: 5m)
|
|
53
|
+
|
|
54
|
+
The daemon provides:
|
|
55
|
+
- Connection pooling and caching
|
|
56
|
+
- Better performance for frequent operations
|
|
57
|
+
- Automatic JSONL sync (5-second debounce)
|
|
58
|
+
- Optional git sync
|