prodboard 0.4.0 → 0.5.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # prodboard
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#23](https://github.com/G4brym/prodboard/pull/23) [`146b3b5`](https://github.com/G4brym/prodboard/commit/146b3b5105ad127c3eb31f4e8c6ea19918329380) Thanks [@G4brym](https://github.com/G4brym)! - Optimize MCP list handlers: trim prompt from list_schedules, add get_schedule tool, exclude stderr_tail from list_runs defaults
8
+
3
9
  ## 0.4.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -150,8 +150,11 @@ prodboard comments <id> # List comments
150
150
 
151
151
  ```bash
152
152
  prodboard schedule add --name "job" --cron "0 9 * * *" --prompt "Do X"
153
+ prodboard schedule add --name "fast" --cron "*/30 * * * *" --prompt "Do Y" --model claude-sonnet-4-6
153
154
  prodboard schedule ls # List schedules
154
155
  prodboard schedule edit <id> --cron "0 10 * * *" # Edit
156
+ prodboard schedule edit <id> --model claude-opus-4-6 # Set model
157
+ prodboard schedule edit <id> --model "" # Clear model override
155
158
  prodboard schedule enable <id> # Enable
156
159
  prodboard schedule disable <id> # Disable
157
160
  prodboard schedule rm <id> --force # Delete
@@ -193,7 +196,8 @@ These are the tools Claude Code sees when connected to the board:
193
196
  | `add_comment` | Leave notes on issues (default author: "claude") |
194
197
  | `pick_next_issue` | Claim the oldest todo, move to in-progress |
195
198
  | `complete_issue` | Mark done with an optional summary comment |
196
- | `list_schedules` | See scheduled jobs |
199
+ | `list_schedules` | See scheduled jobs (compact, excludes prompt) |
200
+ | `get_schedule` | Read full schedule details including prompt |
197
201
  | `create_schedule` | Set up a new cron job |
198
202
  | `update_schedule` | Modify a schedule |
199
203
  | `delete_schedule` | Remove a schedule |
@@ -226,6 +230,34 @@ OpenCode-specific settings:
226
230
  }
227
231
  ```
228
232
 
233
+ ## Model Selection
234
+
235
+ You can control which model is used for scheduled runs at two levels:
236
+
237
+ **Global default** — Set `daemon.model` in your config to apply to all schedules:
238
+
239
+ ```jsonc
240
+ {
241
+ "daemon": {
242
+ "model": "claude-sonnet-4-6"
243
+ }
244
+ }
245
+ ```
246
+
247
+ **Per-schedule override** — Set `--model` when creating or editing a schedule:
248
+
249
+ ```bash
250
+ prodboard schedule add --name "triage" --cron "0 9 * * *" --prompt "Triage the board" --model claude-opus-4-6
251
+ prodboard schedule edit <id> --model claude-haiku-4-5-20251001
252
+ prodboard schedule edit <id> --model "" # clear override, fall back to global
253
+ ```
254
+
255
+ **Resolution order:** schedule `--model` > `daemon.model` > agent's built-in default. For OpenCode, `daemon.opencode.model` sits between the global `daemon.model` and the agent default.
256
+
257
+ Example model IDs:
258
+ - Claude Code: `claude-sonnet-4-6`, `claude-opus-4-6`, `claude-haiku-4-5-20251001`
259
+ - OpenCode: `anthropic/claude-sonnet-4-20250514`, etc.
260
+
229
261
  ## Configuration
230
262
 
231
263
  Config file: `~/.prodboard/config.jsonc`
@@ -239,6 +271,7 @@ Config file: `~/.prodboard/config.jsonc`
239
271
  },
240
272
  "daemon": {
241
273
  "agent": "claude", // "claude" or "opencode"
274
+ "model": null, // default model for runs (null = agent's default)
242
275
  "basePath": null, // base path for worktrees and runs (null = use schedule workdir)
243
276
  "useTmux": true, // wrap agent runs in tmux sessions
244
277
  "maxConcurrentRuns": 2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prodboard",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Self-hosted, CLI-first issue tracker and cron scheduler for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/mcp.ts CHANGED
@@ -149,7 +149,7 @@ const TOOLS = [
149
149
  },
150
150
  {
151
151
  name: "list_schedules",
152
- description: "List scheduled tasks with their status and last run info.",
152
+ description: "List scheduled tasks (compact: excludes prompt, agents_json, allowed_tools). Use get_schedule for full details.",
153
153
  inputSchema: {
154
154
  type: "object" as const,
155
155
  properties: {
@@ -157,6 +157,17 @@ const TOOLS = [
157
157
  },
158
158
  },
159
159
  },
160
+ {
161
+ name: "get_schedule",
162
+ description: "Get full details of a scheduled task, including prompt text.",
163
+ inputSchema: {
164
+ type: "object" as const,
165
+ properties: {
166
+ id: { type: "string" as const, description: "Schedule ID or prefix" },
167
+ },
168
+ required: ["id"],
169
+ },
170
+ },
160
171
  {
161
172
  name: "create_schedule",
162
173
  description: "Create a new scheduled task.",
@@ -380,13 +391,29 @@ export async function handleListSchedules(db: Database, params: any) {
380
391
  lastRun = rq.getLastRun(db, s.id);
381
392
  }
382
393
  result.push({
383
- ...s,
394
+ id: s.id,
395
+ name: s.name,
396
+ cron: s.cron,
397
+ workdir: s.workdir,
398
+ enabled: s.enabled,
399
+ model: s.model,
400
+ max_turns: s.max_turns,
401
+ use_worktree: s.use_worktree,
402
+ source: s.source,
403
+ created_at: s.created_at,
404
+ updated_at: s.updated_at,
384
405
  last_run: lastRun ? { status: lastRun.status, finished_at: lastRun.finished_at } : null,
385
406
  });
386
407
  }
387
408
  return result;
388
409
  }
389
410
 
411
+ export async function handleGetSchedule(db: Database, params: any) {
412
+ const sq = await getScheduleQueries();
413
+ if (!sq) throw new Error("Schedule module not available");
414
+ return sq.getScheduleByPrefix(db, params.id);
415
+ }
416
+
390
417
  export async function handleCreateSchedule(db: Database, params: any) {
391
418
  const sq = await getScheduleQueries();
392
419
  if (!sq) throw new Error("Schedule module not available");
@@ -544,6 +571,9 @@ export async function startMcpServer(): Promise<void> {
544
571
  case "list_schedules":
545
572
  result = await handleListSchedules(db, params ?? {});
546
573
  break;
574
+ case "get_schedule":
575
+ result = await handleGetSchedule(db, params ?? {});
576
+ break;
547
577
  case "create_schedule":
548
578
  result = await handleCreateSchedule(db, params ?? {});
549
579
  break;
@@ -70,7 +70,7 @@ export function listRuns(
70
70
  const columns = opts?.include_output
71
71
  ? "r.*"
72
72
  : `r.id, r.schedule_id, r.status, r.pid, r.started_at, r.finished_at,
73
- r.exit_code, r.stderr_tail, r.session_id, r.worktree_path,
73
+ r.exit_code, r.session_id, r.worktree_path,
74
74
  r.tokens_in, r.tokens_out, r.cost_usd, r.tools_used,
75
75
  r.issues_touched, r.tmux_session, r.agent`;
76
76