prodboard 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # prodboard
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 1aa4d25: Add `prodboard install` and `prodboard uninstall` commands to manage a user-level systemd service for the daemon
8
+
3
9
  ## 0.1.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -1,285 +1,293 @@
1
1
  # prodboard
2
2
 
3
- A self-hosted, CLI-first issue tracker and cron scheduler for AI coding agents.
3
+ Give Claude Code a persistent task board and a cron scheduler so it can manage work across sessions.
4
4
 
5
- ## Overview
5
+ **The problem:** Claude Code loses context between sessions. It can't remember what tasks exist, what's in progress, or what to work on next. There's no way to schedule it to run recurring jobs like daily triage or nightly CI.
6
6
 
7
- prodboard provides three interfaces for managing issues and scheduled AI tasks:
7
+ **The solution:** prodboard is a local issue tracker backed by SQLite that Claude Code can read and write through MCP tools. It also includes a cron daemon that spawns Claude Code on a schedule to work through tasks autonomously.
8
8
 
9
- - **CLI** — Human-friendly commands for issue tracking and schedule management
10
- - **MCP Server** — Model Context Protocol server for AI agent integration
11
- - **Scheduler Daemon** — Cron-based task scheduler that invokes Claude on a schedule
9
+ ```
10
+ You (CLI) ──┐
11
+ ├──▶ SQLite DB ◀── MCP Server ◀── Claude Code
12
+ Cron Daemon ──┘
13
+ ```
12
14
 
13
- All state lives in a single SQLite database at `~/.prodboard/db.sqlite`.
15
+ ## What You Get
14
16
 
15
- ## Quick Start
17
+ - **An issue board Claude Code can use** — Claude reads, creates, updates, and completes issues via MCP tools during any session
18
+ - **Scheduled Claude Code runs** — Define cron jobs that spawn Claude Code to triage issues, run maintenance, or work through the backlog
19
+ - **A CLI you can use too** — Same board, human-friendly commands. Add issues, check status, review what Claude did
20
+ - **Everything local** — Single SQLite file at `~/.prodboard/db.sqlite`. No servers, no accounts, no cloud
16
21
 
17
- ### Install
22
+ ## Quick Start
18
23
 
19
24
  ```bash
25
+ # Install
20
26
  bun install -g prodboard
27
+
28
+ # Initialize
29
+ prodboard init
30
+
31
+ # Connect Claude Code to the board
32
+ claude mcp add prodboard -- bunx prodboard mcp
21
33
  ```
22
34
 
23
- ### Initialize
35
+ That's it. Open Claude Code and start talking to it:
36
+
37
+ ## Things You Can Say to Claude Code
38
+
39
+ Once connected, you can manage your board entirely through conversation:
40
+
41
+ ### Setting Up Cron Jobs
24
42
 
25
- ```bash
26
- prodboard init
27
43
  ```
44
+ "Every hour, tail the nginx access and error logs. If you see
45
+ anything unusual — spikes in 5xx errors, suspicious request
46
+ patterns, or unexpected traffic — create a new issue to investigate"
28
47
 
29
- This creates `~/.prodboard/` with the database, config, and generated files.
48
+ "Every 2 hours, pick up the next todo issue and try to fix it.
49
+ Open a PR with your changes, comment the PR link on the issue,
50
+ and move the issue to review"
30
51
 
31
- ### Connect to Claude
52
+ "Every 2 hours, pick up the next issue in review. Check out the
53
+ PR, verify the code is correct and tests pass. If everything
54
+ looks good, merge it. If not, add a review comment on the PR
55
+ explaining what needs to change and move the issue back to todo"
32
56
 
33
- ```bash
34
- claude mcp add prodboard -- bunx prodboard mcp
57
+ "Create a cron job that runs every 6 hours to check for
58
+ and fix any TypeScript type errors in the project"
59
+
60
+ "Set up a daily schedule at 9 AM on weekdays to review
61
+ the board and work on the highest priority task"
62
+
63
+ "Add a cron job that runs every night at midnight to
64
+ run the test suite and create issues for any failures"
65
+
66
+ "Schedule a weekly cleanup every Friday at 5 PM to
67
+ archive all done issues and summarize what was accomplished"
68
+
69
+ "Create a schedule that runs every 30 minutes to monitor
70
+ the API health endpoint and create an issue if it's down"
35
71
  ```
36
72
 
37
- Or copy the generated MCP config:
73
+ ### Managing Tasks
38
74
 
39
- ```bash
40
- cat ~/.prodboard/mcp.json
41
75
  ```
76
+ "Add a task to fix the authentication timeout bug in the API"
42
77
 
43
- ### Add the CLAUDE.md (optional)
78
+ "What's on the board right now?"
44
79
 
45
- ```bash
46
- prodboard init --claude-md
80
+ "Pick up the next task and start working on it"
81
+
82
+ "Mark the login bug as done, I fixed it manually"
83
+
84
+ "Create an issue to refactor the database layer, mark it as todo"
85
+
86
+ "Show me all in-progress issues"
87
+
88
+ "Add a comment to the auth bug — we need to check the session TTL"
47
89
  ```
48
90
 
49
- ## CLI Reference
91
+ ### Reviewing Activity
50
92
 
51
- ### Issue Management
93
+ ```
94
+ "Show me what the last cron run did"
52
95
 
53
- ```bash
54
- # Create an issue
55
- prodboard add "Fix login bug" -d "SameSite cookie issue on Safari" -s todo
56
-
57
- # List issues
58
- prodboard ls # All non-archived issues
59
- prodboard ls --status todo # Filter by status
60
- prodboard ls --search "login" # Search title/description
61
- prodboard ls --json # JSON output
62
- prodboard ls --all # Include archived
63
-
64
- # Show issue details
65
- prodboard show <id> # Full ID or unique prefix
66
- prodboard show a3f9 # Prefix match
67
-
68
- # Edit an issue
69
- prodboard edit <id> --title "New title"
70
- prodboard edit <id> --status review
71
- prodboard edit <id> -d "Updated description"
72
-
73
- # Move issue status
74
- prodboard mv <id> done
75
-
76
- # Delete an issue
77
- prodboard rm <id> --force
78
-
79
- # Comments
80
- prodboard comment <id> "Looking into this"
81
- prodboard comment <id> "Fixed it" --author claude
82
- prodboard comments <id>
83
- prodboard comments <id> --json
96
+ "What tasks did you complete this week?"
97
+
98
+ "Show the schedule stats for the daily triage job"
84
99
  ```
85
100
 
86
- ### Schedule Management
101
+ Claude Code handles all the MCP tool calls behind the scenes — you just talk to it naturally.
102
+
103
+ ## Adding Tasks from the CLI
104
+
105
+ You can also manage the board directly:
87
106
 
88
107
  ```bash
89
- # Create a schedule
90
- prodboard schedule add \
91
- --name "daily-triage" \
92
- --cron "0 9 * * 1-5" \
93
- --prompt "Review the board and triage new issues"
108
+ prodboard add "Fix login bug" -d "OAuth callback URL is wrong" -s todo
109
+ prodboard add "Add dark mode" -s todo
110
+ prodboard add "Write API tests" -s todo
111
+ prodboard ls
112
+ ```
94
113
 
95
- # List schedules
96
- prodboard schedule ls
97
- prodboard schedule ls --all --json
114
+ ### Starting the Scheduler
98
115
 
99
- # Edit a schedule
100
- prodboard schedule edit <id> --cron "0 10 * * *"
116
+ ```bash
117
+ # Start the cron daemon (keeps running in foreground)
118
+ prodboard daemon
101
119
 
102
- # Enable/disable
103
- prodboard schedule enable <id>
104
- prodboard schedule disable <id>
120
+ # Or preview what's scheduled without running anything
121
+ prodboard daemon --dry-run
122
+ ```
105
123
 
106
- # Delete
107
- prodboard schedule rm <id> --force
124
+ ## CLI Reference
125
+
126
+ ### Issues
108
127
 
109
- # Run immediately (foreground)
110
- prodboard schedule run <id>
128
+ ```bash
129
+ prodboard add "Fix bug" -d "description" -s todo # Create
130
+ prodboard ls # List (table)
131
+ prodboard ls --status todo --status in-progress # Filter by status
132
+ prodboard ls --search "login" --json # Search + JSON output
133
+ prodboard show <id> # Details + comments
134
+ prodboard edit <id> --title "New title" -s review # Update fields
135
+ prodboard mv <id> done # Change status
136
+ prodboard rm <id> --force # Delete
137
+ ```
111
138
 
112
- # View run history
113
- prodboard schedule logs
114
- prodboard schedule logs --schedule <id> --limit 10
139
+ ### Comments
115
140
 
116
- # View statistics
117
- prodboard schedule stats
118
- prodboard schedule stats --schedule <id> --days 7
141
+ ```bash
142
+ prodboard comment <id> "Looking into this" # Add comment
143
+ prodboard comment <id> "Fixed" --author claude # With author
144
+ prodboard comments <id> # List comments
119
145
  ```
120
146
 
121
- ### Daemon
147
+ ### Schedules
122
148
 
123
149
  ```bash
124
- # Start daemon (foreground, for systemd)
125
- prodboard daemon
150
+ prodboard schedule add --name "job" --cron "0 9 * * *" --prompt "Do X"
151
+ prodboard schedule ls # List schedules
152
+ prodboard schedule edit <id> --cron "0 10 * * *" # Edit
153
+ prodboard schedule enable <id> # Enable
154
+ prodboard schedule disable <id> # Disable
155
+ prodboard schedule rm <id> --force # Delete
156
+ prodboard schedule run <id> # Run immediately
157
+ prodboard schedule logs # Run history
158
+ prodboard schedule stats --days 7 # Statistics
159
+ ```
126
160
 
127
- # Dry run (show schedules without executing)
128
- prodboard daemon --dry-run
161
+ ### Daemon
129
162
 
130
- # Check daemon status
131
- prodboard daemon status
163
+ ```bash
164
+ prodboard daemon # Start (foreground)
165
+ prodboard daemon --dry-run # Preview schedules
166
+ prodboard daemon status # Check if running
132
167
  ```
133
168
 
134
169
  ### Other
135
170
 
136
171
  ```bash
137
- prodboard config # Show current configuration
138
- prodboard version # Show version
139
- prodboard help # Show help
172
+ prodboard config # Show configuration
173
+ prodboard version # Show version
140
174
  ```
141
175
 
142
- ## MCP Tools Reference
143
-
144
- | Tool | Description |
145
- |------|-------------|
146
- | `board_summary` | Overview of issues by status, recent issues |
147
- | `list_issues` | List issues with optional filters |
148
- | `get_issue` | Get full issue details with comments |
149
- | `create_issue` | Create a new issue |
150
- | `update_issue` | Update issue fields |
151
- | `delete_issue` | Delete an issue |
152
- | `add_comment` | Add a comment (default author: claude) |
153
- | `pick_next_issue` | Claim next todo, move to in-progress |
154
- | `complete_issue` | Mark done with optional comment |
155
- | `list_schedules` | List scheduled tasks |
156
- | `create_schedule` | Create a scheduled task |
157
- | `update_schedule` | Update a scheduled task |
158
- | `delete_schedule` | Delete a scheduled task |
159
- | `list_runs` | View run history |
160
-
161
- ### MCP Resources
162
-
163
- | URI | Description |
164
- |-----|-------------|
165
- | `prodboard://issues` | Board summary (same as board_summary) |
166
- | `prodboard://schedules` | Active schedules with next run times |
176
+ IDs support prefix matching — use `a3f9` instead of the full `a3f9b2c1d4e5f678`.
177
+
178
+ ## MCP Tools
179
+
180
+ These are the tools Claude Code sees when connected to the board:
181
+
182
+ | Tool | What Claude Uses It For |
183
+ |------|------------------------|
184
+ | `board_summary` | See issue counts and recent activity |
185
+ | `list_issues` | Browse issues with filters |
186
+ | `get_issue` | Read full issue details and comments |
187
+ | `create_issue` | Log a new task or bug |
188
+ | `update_issue` | Change title, description, or status |
189
+ | `delete_issue` | Remove an issue |
190
+ | `add_comment` | Leave notes on issues (default author: "claude") |
191
+ | `pick_next_issue` | Claim the oldest todo, move to in-progress |
192
+ | `complete_issue` | Mark done with an optional summary comment |
193
+ | `list_schedules` | See scheduled jobs |
194
+ | `create_schedule` | Set up a new cron job |
195
+ | `update_schedule` | Modify a schedule |
196
+ | `delete_schedule` | Remove a schedule |
197
+ | `list_runs` | Check run history and results |
198
+
199
+ MCP resources: `prodboard://issues` (board summary) and `prodboard://schedules` (active schedules).
167
200
 
168
201
  ## Configuration
169
202
 
170
- Config file: `~/.prodboard/config.jsonc` (JSONC format — comments allowed)
203
+ Config file: `~/.prodboard/config.jsonc`
171
204
 
172
205
  ```jsonc
173
206
  {
174
207
  "general": {
175
- // Issue statuses in display order
176
208
  "statuses": ["todo", "in-progress", "review", "done", "archived"],
177
- // Default status for new issues
178
209
  "defaultStatus": "todo",
179
- // Optional prefix for issue IDs
180
210
  "idPrefix": ""
181
211
  },
182
212
  "daemon": {
183
- // Max concurrent scheduled runs
184
213
  "maxConcurrentRuns": 2,
185
- // Default max turns for Claude
186
214
  "maxTurns": 50,
187
- // Absolute max (cannot be overridden)
188
215
  "hardMaxTurns": 200,
189
- // Run timeout in seconds
190
216
  "runTimeoutSeconds": 1800,
191
- // Days to keep run history
192
217
  "runRetentionDays": 30,
193
- // Log level: debug, info, warn, error
194
218
  "logLevel": "info",
195
- // Worktree usage: auto, always, never
196
219
  "useWorktrees": "auto"
197
220
  }
198
221
  }
199
222
  ```
200
223
 
201
- ## Scheduler Guide
224
+ ## Scheduler Details
202
225
 
203
226
  ### Cron Syntax
204
227
 
205
- Standard 5-field cron expressions:
228
+ Standard 5-field cron:
206
229
 
207
230
  ```
208
- minute (0-59)
209
- hour (0-23)
210
- day of month (1-31)
211
- month (1-12)
212
- day of week (0-6, 0=Sunday)
231
+ ┌───────────── minute (0-59)
232
+ │ ┌─────────── hour (0-23)
233
+ │ │ ┌───────── day of month (1-31)
234
+ │ │ │ ┌─────── month (1-12)
235
+ │ │ │ │ ┌───── day of week (0-6, Sun=0)
236
+ │ │ │ │ │
237
+ * * * * *
213
238
  ```
214
239
 
215
- Examples:
216
- - `0 9 * * 1-5` — Weekdays at 9:00 AM
217
- - `*/15 * * * *` Every 15 minutes
218
- - `0 0 1 * *` First of every month at midnight
219
- - `0 9,17 * * *` 9 AM and 5 PM daily
240
+ | Expression | Meaning |
241
+ |-----------|---------|
242
+ | `0 9 * * 1-5` | Weekdays at 9 AM |
243
+ | `*/15 * * * *` | Every 15 minutes |
244
+ | `0 0 1 * *` | First of every month |
245
+ | `0 9,17 * * *` | 9 AM and 5 PM daily |
220
246
 
221
247
  ### Template Variables
222
248
 
223
- Use in schedule prompts:
249
+ Use in schedule prompts to inject board context:
224
250
 
225
- | Variable | Description |
226
- |----------|-------------|
227
- | `{{board_summary}}` | Compact summary: "3 todo, 1 in-progress, 0 review" |
251
+ | Variable | Value |
252
+ |----------|-------|
253
+ | `{{board_summary}}` | "3 todo, 1 in-progress, 0 review" |
228
254
  | `{{todo_count}}` | Number of todo issues |
229
255
  | `{{in_progress_count}}` | Number of in-progress issues |
230
256
  | `{{datetime}}` | Current ISO 8601 timestamp |
231
257
  | `{{schedule_name}}` | Name of the schedule |
232
258
 
233
- Example:
234
-
235
259
  ```bash
236
260
  prodboard schedule add \
237
261
  --name "morning-standup" \
238
262
  --cron "0 9 * * 1-5" \
239
- --prompt "Board status: {{board_summary}}. Pick and work on the next todo issue."
263
+ --prompt "Board: {{board_summary}}. Pick the next todo and work on it."
240
264
  ```
241
265
 
242
- ## Running as a Service
243
-
244
- ### systemd
245
-
246
- Create `/etc/systemd/system/prodboard.service`:
266
+ ### Running as a systemd Service
247
267
 
248
- ```ini
249
- [Unit]
250
- Description=prodboard scheduler daemon
251
- After=network.target
268
+ ```bash
269
+ # Install and start as a user-level systemd service (no sudo needed)
270
+ prodboard install
252
271
 
253
- [Service]
254
- Type=simple
255
- User=your-user
256
- ExecStart=/usr/local/bin/bun run prodboard daemon
257
- Restart=on-failure
258
- RestartSec=10
272
+ # Check status
273
+ systemctl --user status prodboard
259
274
 
260
- [Install]
261
- WantedBy=multi-user.target
262
- ```
275
+ # Remove the service
276
+ prodboard uninstall
263
277
 
264
- ```bash
265
- sudo systemctl enable prodboard
266
- sudo systemctl start prodboard
267
- sudo systemctl status prodboard
278
+ # Reinstall (e.g. after updating prodboard)
279
+ prodboard install --force
268
280
  ```
269
281
 
270
282
  ## Troubleshooting
271
283
 
272
- **"prodboard is not initialized"**
273
- Run `prodboard init` to create `~/.prodboard/`.
284
+ **"prodboard is not initialized"** — Run `prodboard init`.
274
285
 
275
- **MCP server not connecting**
276
- Check that `~/.prodboard/mcp.json` exists and the path to prodboard is correct.
286
+ **MCP not connecting** — Verify `claude mcp add prodboard -- bunx prodboard mcp` was run, or check `~/.prodboard/mcp.json`.
277
287
 
278
- **Daemon not starting**
279
- Check `~/.prodboard/logs/daemon.log` for errors. Ensure claude CLI is installed and accessible.
288
+ **Daemon not starting** — Check `~/.prodboard/logs/daemon.log`. Make sure `claude` CLI is installed and `ANTHROPIC_API_KEY` is set.
280
289
 
281
- **Stale PID file**
282
- If `prodboard daemon status` shows "stale PID file", the daemon crashed. It will auto-clean the PID file. Run `prodboard daemon` to restart.
290
+ **Stale PID file** — The daemon crashed. Run `prodboard daemon` to restart (auto-cleans stale PIDs).
283
291
 
284
292
  ## Development
285
293
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prodboard",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Self-hosted, CLI-first issue tracker and cron scheduler for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,127 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import * as os from "os";
4
+
5
+ const SERVICE_NAME = "prodboard";
6
+ const SERVICE_DIR = path.join(os.homedir(), ".config", "systemd", "user");
7
+ const SERVICE_PATH = path.join(SERVICE_DIR, `${SERVICE_NAME}.service`);
8
+
9
+ function parseArgs(args: string[]): { flags: Record<string, boolean> } {
10
+ const flags: Record<string, boolean> = {};
11
+ for (const arg of args) {
12
+ if (arg === "--force" || arg === "-f") {
13
+ flags.force = true;
14
+ }
15
+ }
16
+ return { flags };
17
+ }
18
+
19
+ async function systemctlAvailable(): Promise<boolean> {
20
+ try {
21
+ const proc = Bun.spawn(["systemctl", "--version"], {
22
+ stdout: "ignore",
23
+ stderr: "ignore",
24
+ });
25
+ const code = await proc.exited;
26
+ return code === 0;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+
32
+ async function runSystemctl(...args: string[]): Promise<{ exitCode: number; stdout: string; stderr: string }> {
33
+ const proc = Bun.spawn(["systemctl", "--user", ...args], {
34
+ stdout: "pipe",
35
+ stderr: "pipe",
36
+ });
37
+ const [stdout, stderr, exitCode] = await Promise.all([
38
+ new Response(proc.stdout).text(),
39
+ new Response(proc.stderr).text(),
40
+ proc.exited,
41
+ ]);
42
+ return { exitCode, stdout, stderr };
43
+ }
44
+
45
+ export function generateServiceFile(bunPath: string, prodboardPath: string, home: string): string {
46
+ return `[Unit]
47
+ Description=prodboard scheduler daemon
48
+ After=network.target
49
+
50
+ [Service]
51
+ Type=simple
52
+ ExecStart=${bunPath} run ${prodboardPath} daemon
53
+ Restart=on-failure
54
+ RestartSec=10
55
+ Environment="HOME=${home}"
56
+
57
+ [Install]
58
+ WantedBy=default.target
59
+ `;
60
+ }
61
+
62
+ export async function install(args: string[]): Promise<void> {
63
+ const { flags } = parseArgs(args);
64
+
65
+ if (!(await systemctlAvailable())) {
66
+ console.error("systemd is not available on this system.");
67
+ console.error("The install command requires systemd (Linux).");
68
+ process.exit(1);
69
+ }
70
+
71
+ const alreadyInstalled = fs.existsSync(SERVICE_PATH);
72
+
73
+ if (alreadyInstalled && !flags.force) {
74
+ console.log("prodboard is already installed as a systemd service.");
75
+ const { stdout } = await runSystemctl("status", SERVICE_NAME);
76
+ console.log(stdout);
77
+ return;
78
+ }
79
+
80
+ const bunPath = Bun.which("bun") ?? process.execPath;
81
+ const prodboardPath = Bun.which("prodboard") ?? `${bunPath} x prodboard`;
82
+ const home = os.homedir();
83
+
84
+ const serviceContent = generateServiceFile(bunPath, prodboardPath, home);
85
+
86
+ fs.mkdirSync(SERVICE_DIR, { recursive: true });
87
+ fs.writeFileSync(SERVICE_PATH, serviceContent);
88
+ console.log(`Service file written to ${SERVICE_PATH}`);
89
+
90
+ const reload = await runSystemctl("daemon-reload");
91
+ if (reload.exitCode !== 0) {
92
+ console.error("Failed to reload systemd:", reload.stderr);
93
+ process.exit(1);
94
+ }
95
+
96
+ const enable = await runSystemctl("enable", SERVICE_NAME);
97
+ if (enable.exitCode !== 0) {
98
+ console.error("Failed to enable service:", enable.stderr);
99
+ process.exit(1);
100
+ }
101
+
102
+ const start = await runSystemctl("start", SERVICE_NAME);
103
+ if (start.exitCode !== 0) {
104
+ console.error("Failed to start service:", start.stderr);
105
+ process.exit(1);
106
+ }
107
+
108
+ console.log("prodboard service installed, enabled, and started.");
109
+ const { stdout } = await runSystemctl("status", SERVICE_NAME);
110
+ console.log(stdout);
111
+ }
112
+
113
+ export async function uninstall(_args: string[]): Promise<void> {
114
+ if (!fs.existsSync(SERVICE_PATH)) {
115
+ console.log("prodboard is not installed as a systemd service.");
116
+ return;
117
+ }
118
+
119
+ await runSystemctl("stop", SERVICE_NAME);
120
+ await runSystemctl("disable", SERVICE_NAME);
121
+
122
+ fs.unlinkSync(SERVICE_PATH);
123
+ console.log(`Removed ${SERVICE_PATH}`);
124
+
125
+ await runSystemctl("daemon-reload");
126
+ console.log("prodboard service uninstalled.");
127
+ }
package/src/index.ts CHANGED
@@ -142,6 +142,17 @@ export async function main(): Promise<void> {
142
142
  }
143
143
  break;
144
144
  }
145
+ case "install": {
146
+ ensureInitialized();
147
+ const { install } = await import("./commands/install.ts");
148
+ await install(args.slice(1));
149
+ break;
150
+ }
151
+ case "uninstall": {
152
+ const { uninstall } = await import("./commands/install.ts");
153
+ await uninstall(args.slice(1));
154
+ break;
155
+ }
145
156
  case "config": {
146
157
  ensureInitialized();
147
158
  const { loadConfig } = await import("./config.ts");
@@ -191,6 +202,8 @@ Commands:
191
202
  comments <id> List comments for an issue
192
203
  schedule <sub> Manage scheduled tasks
193
204
  daemon Start the scheduler daemon
205
+ install Install systemd service
206
+ uninstall Remove systemd service
194
207
  config Show configuration
195
208
  mcp Start MCP server (stdio)
196
209
  version Show version