choda-deck 0.1.0 → 0.2.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/README.md +230 -68
- package/dist/cli.cjs +39261 -0
- package/dist/{session-rules.md → mcp-rules.md} +94 -83
- package/dist/mcp-server.cjs +1562 -358
- package/package.json +78 -74
|
@@ -1,83 +1,94 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
Behavioral contract for session
|
|
4
|
-
|
|
5
|
-
## On session_start
|
|
6
|
-
|
|
7
|
-
`session_start` now requires a `taskId` — the task is bound to the session at creation and auto-set to IN-PROGRESS.
|
|
8
|
-
|
|
9
|
-
Before calling `session_start`:
|
|
10
|
-
|
|
11
|
-
1. Call `task_list` (or `roadmap`) to show the user available tasks, grouped by priority (high → medium → low).
|
|
12
|
-
2. Wait for the user to pick a task. Do not guess.
|
|
13
|
-
3. Call `session_start({ projectId, taskId, workspaceId?, cwd? })`. Always pass `cwd` (current shell directory) so the MCP can auto-detect `workspaceId` for projects with registered workspaces — the MCP server's own cwd is fixed and cannot be inferred.
|
|
14
|
-
4. Echo the `lastSession` block to the user verbatim — resume point, decisions, loose ends, tasks updated, commits. Do not summarize.
|
|
15
|
-
5. Create a feature branch for the task:
|
|
16
|
-
- Branch name: `feat/<task-id>-<short-slug>` (e.g. `feat/task-564-session-conv-ui`)
|
|
17
|
-
- Required: `git checkout -b feat/<task-id>-<short-slug>`
|
|
18
|
-
- Optional (if user wants parallel worktree): detect repo root via `git rev-parse --show-toplevel`, then `git worktree add <repo-root>.worktrees/<slug> -b feat/<task-id>-<short-slug>`
|
|
19
|
-
- Ask the user whether they want a worktree or just a branch before proceeding.
|
|
20
|
-
|
|
21
|
-
Workspace resolution order (when project has ≥1 workspace registered):
|
|
22
|
-
- explicit `workspaceId` wins
|
|
23
|
-
- else `cwd` is matched against registered workspace cwds (longest prefix wins for nested repos)
|
|
24
|
-
- else MCP throws — pick a workspace explicitly or call `workspace_add`
|
|
25
|
-
|
|
26
|
-
If the project has no workspaces registered, `workspaceId` may be `null` (backward-compatible).
|
|
27
|
-
|
|
28
|
-
Blocking conditions (MCP returns an error):
|
|
29
|
-
- Task not found
|
|
30
|
-
- Task already `DONE` — reopen it with `task_update` first
|
|
31
|
-
- Task already bound to another active session — end that session first
|
|
32
|
-
- Project has workspaces but neither `workspaceId` nor a matching `cwd` was provided
|
|
33
|
-
|
|
34
|
-
## On session_checkpoint
|
|
35
|
-
|
|
36
|
-
`session_checkpoint` snapshots progress on an active session **without ending it**. Overwrite-in-place — each call replaces the previous checkpoint.
|
|
37
|
-
|
|
38
|
-
When to checkpoint:
|
|
39
|
-
|
|
40
|
-
- Before risky operations (rebase, force-push, schema migration, large refactor)
|
|
41
|
-
- Before context window compaction (when conversation grows long)
|
|
42
|
-
- Every ~30 minutes of active work, or after a meaningful sub-step
|
|
43
|
-
- When pausing work mid-task (lunch, meeting) — so a future `session_resume` recovers state cleanly
|
|
44
|
-
|
|
45
|
-
Required field:
|
|
46
|
-
|
|
47
|
-
- **resumePoint** — one sentence describing exactly where you stopped and what to pick up next
|
|
48
|
-
|
|
49
|
-
Recommended fields (include whichever apply):
|
|
50
|
-
|
|
51
|
-
- **lastConversationId** — most recent conversation touched (resume context)
|
|
52
|
-
- **dirtyFiles** — files edited but not yet committed (so resume knows what's in flight)
|
|
53
|
-
- **lastCommit** — last commit SHA written this session (resume git position)
|
|
54
|
-
- **notes** — free-form context that matters for resume (decisions made, dead ends ruled out)
|
|
55
|
-
|
|
56
|
-
Do not call `session_checkpoint` as a substitute for `session_end`. Checkpoint = pause; end = finalize + handoff.
|
|
57
|
-
|
|
58
|
-
## On session_resume
|
|
59
|
-
|
|
60
|
-
`session_resume` returns the session row, last checkpoint, linked conversations, and active context sources. Use after crash, restart, or context compaction — not as a way to spawn a new session for the same task.
|
|
61
|
-
|
|
62
|
-
After calling `session_resume`:
|
|
63
|
-
|
|
64
|
-
1. **Echo the checkpoint summary verbatim** — `resumePoint`, `notes`, `dirtyFiles`, `lastCommit`, `lastConversationId`. Do not summarize. Butter needs the same view the prior session had.
|
|
65
|
-
2. **Confirm task binding** — name the `taskId` and current status. If the task is no longer IN-PROGRESS, surface the discrepancy before proceeding.
|
|
66
|
-
3. **Resume from `resumePoint`** — pick up the exact next step. Do not re-plan from scratch.
|
|
67
|
-
4. **Do not call `session_start`** — resume reactivates the existing session; starting a new one orphans the checkpoint and creates duplicate state.
|
|
68
|
-
|
|
69
|
-
If no checkpoint exists (resumed session was never checkpointed), say so explicitly and ask Butter where to pick up before continuing.
|
|
70
|
-
|
|
71
|
-
## On session_end
|
|
72
|
-
|
|
73
|
-
When preparing the session_end payload, always include:
|
|
74
|
-
|
|
75
|
-
- **resumePoint** (required) — one sentence describing where you stopped and what the next session should pick up.
|
|
76
|
-
- **tasksUpdated** (required if session had a taskId) — list of task ids and their new status.
|
|
77
|
-
- **decisions** — architectural or implementation decisions made this session. Explicit > implicit.
|
|
78
|
-
- **looseEnds** — anything unfinished, deferred, or noted for later. Include pre-existing issues you touched but did not resolve.
|
|
79
|
-
- **commits** — commit SHAs + short message if commits were made.
|
|
80
|
-
|
|
81
|
-
Never end a session with only resumePoint. If the session was trivial (read-only), explicitly note "no changes" in looseEnds.
|
|
82
|
-
|
|
83
|
-
`looseEnds` are auto-converted to inbox entries (status=raw) under the session's project — one entry per item, tagged with the source session/task ID. Butter reviews the inbox in `/daily` and decides which deserve to become TODO tasks via `inbox_convert`. Keep each loose end short (1 line, concrete) — they are capture, not specification.
|
|
1
|
+
# MCP Rules
|
|
2
|
+
|
|
3
|
+
Behavioral contract for MCP tools (session + conversation). Edit this file to update compliance rules — no MCP restart needed. Each `## On <tool_name>` section is loaded by the matching tool handler and injected into its response.
|
|
4
|
+
|
|
5
|
+
## On session_start
|
|
6
|
+
|
|
7
|
+
`session_start` now requires a `taskId` — the task is bound to the session at creation and auto-set to IN-PROGRESS.
|
|
8
|
+
|
|
9
|
+
Before calling `session_start`:
|
|
10
|
+
|
|
11
|
+
1. Call `task_list` (or `roadmap`) to show the user available tasks, grouped by priority (high → medium → low).
|
|
12
|
+
2. Wait for the user to pick a task. Do not guess.
|
|
13
|
+
3. Call `session_start({ projectId, taskId, workspaceId?, cwd? })`. Always pass `cwd` (current shell directory) so the MCP can auto-detect `workspaceId` for projects with registered workspaces — the MCP server's own cwd is fixed and cannot be inferred.
|
|
14
|
+
4. Echo the `lastSession` block to the user verbatim — resume point, decisions, loose ends, tasks updated, commits. Do not summarize.
|
|
15
|
+
5. Create a feature branch for the task:
|
|
16
|
+
- Branch name: `feat/<task-id>-<short-slug>` (e.g. `feat/task-564-session-conv-ui`)
|
|
17
|
+
- Required: `git checkout -b feat/<task-id>-<short-slug>`
|
|
18
|
+
- Optional (if user wants parallel worktree): detect repo root via `git rev-parse --show-toplevel`, then `git worktree add <repo-root>.worktrees/<slug> -b feat/<task-id>-<short-slug>`
|
|
19
|
+
- Ask the user whether they want a worktree or just a branch before proceeding.
|
|
20
|
+
|
|
21
|
+
Workspace resolution order (when project has ≥1 workspace registered):
|
|
22
|
+
- explicit `workspaceId` wins
|
|
23
|
+
- else `cwd` is matched against registered workspace cwds (longest prefix wins for nested repos)
|
|
24
|
+
- else MCP throws — pick a workspace explicitly or call `workspace_add`
|
|
25
|
+
|
|
26
|
+
If the project has no workspaces registered, `workspaceId` may be `null` (backward-compatible).
|
|
27
|
+
|
|
28
|
+
Blocking conditions (MCP returns an error):
|
|
29
|
+
- Task not found
|
|
30
|
+
- Task already `DONE` — reopen it with `task_update` first
|
|
31
|
+
- Task already bound to another active session — end that session first
|
|
32
|
+
- Project has workspaces but neither `workspaceId` nor a matching `cwd` was provided
|
|
33
|
+
|
|
34
|
+
## On session_checkpoint
|
|
35
|
+
|
|
36
|
+
`session_checkpoint` snapshots progress on an active session **without ending it**. Overwrite-in-place — each call replaces the previous checkpoint.
|
|
37
|
+
|
|
38
|
+
When to checkpoint:
|
|
39
|
+
|
|
40
|
+
- Before risky operations (rebase, force-push, schema migration, large refactor)
|
|
41
|
+
- Before context window compaction (when conversation grows long)
|
|
42
|
+
- Every ~30 minutes of active work, or after a meaningful sub-step
|
|
43
|
+
- When pausing work mid-task (lunch, meeting) — so a future `session_resume` recovers state cleanly
|
|
44
|
+
|
|
45
|
+
Required field:
|
|
46
|
+
|
|
47
|
+
- **resumePoint** — one sentence describing exactly where you stopped and what to pick up next
|
|
48
|
+
|
|
49
|
+
Recommended fields (include whichever apply):
|
|
50
|
+
|
|
51
|
+
- **lastConversationId** — most recent conversation touched (resume context)
|
|
52
|
+
- **dirtyFiles** — files edited but not yet committed (so resume knows what's in flight)
|
|
53
|
+
- **lastCommit** — last commit SHA written this session (resume git position)
|
|
54
|
+
- **notes** — free-form context that matters for resume (decisions made, dead ends ruled out)
|
|
55
|
+
|
|
56
|
+
Do not call `session_checkpoint` as a substitute for `session_end`. Checkpoint = pause; end = finalize + handoff.
|
|
57
|
+
|
|
58
|
+
## On session_resume
|
|
59
|
+
|
|
60
|
+
`session_resume` returns the session row, last checkpoint, linked conversations, and active context sources. Use after crash, restart, or context compaction — not as a way to spawn a new session for the same task.
|
|
61
|
+
|
|
62
|
+
After calling `session_resume`:
|
|
63
|
+
|
|
64
|
+
1. **Echo the checkpoint summary verbatim** — `resumePoint`, `notes`, `dirtyFiles`, `lastCommit`, `lastConversationId`. Do not summarize. Butter needs the same view the prior session had.
|
|
65
|
+
2. **Confirm task binding** — name the `taskId` and current status. If the task is no longer IN-PROGRESS, surface the discrepancy before proceeding.
|
|
66
|
+
3. **Resume from `resumePoint`** — pick up the exact next step. Do not re-plan from scratch.
|
|
67
|
+
4. **Do not call `session_start`** — resume reactivates the existing session; starting a new one orphans the checkpoint and creates duplicate state.
|
|
68
|
+
|
|
69
|
+
If no checkpoint exists (resumed session was never checkpointed), say so explicitly and ask Butter where to pick up before continuing.
|
|
70
|
+
|
|
71
|
+
## On session_end
|
|
72
|
+
|
|
73
|
+
When preparing the session_end payload, always include:
|
|
74
|
+
|
|
75
|
+
- **resumePoint** (required) — one sentence describing where you stopped and what the next session should pick up.
|
|
76
|
+
- **tasksUpdated** (required if session had a taskId) — list of task ids and their new status.
|
|
77
|
+
- **decisions** — architectural or implementation decisions made this session. Explicit > implicit.
|
|
78
|
+
- **looseEnds** — anything unfinished, deferred, or noted for later. Include pre-existing issues you touched but did not resolve.
|
|
79
|
+
- **commits** — commit SHAs + short message if commits were made.
|
|
80
|
+
|
|
81
|
+
Never end a session with only resumePoint. If the session was trivial (read-only), explicitly note "no changes" in looseEnds.
|
|
82
|
+
|
|
83
|
+
`looseEnds` are auto-converted to inbox entries (status=raw) under the session's project — one entry per item, tagged with the source session/task ID. Butter reviews the inbox in `/daily` and decides which deserve to become TODO tasks via `inbox_convert`. Keep each loose end short (1 line, concrete) — they are capture, not specification.
|
|
84
|
+
|
|
85
|
+
## On conversation_read
|
|
86
|
+
|
|
87
|
+
Discussion etiquette (advisory, injected only when `conv.status` is `open` or `discussing`; skipped for `decided`/`closed`/`stale`):
|
|
88
|
+
|
|
89
|
+
- Read the full thread first. Don't restate prior points unless correcting them.
|
|
90
|
+
- State your position in 1 line, then 2-3 concrete reasons (not generic pros/cons).
|
|
91
|
+
- Address the latest unresolved point. If you disagree, challenge it directly — don't add parallel views.
|
|
92
|
+
- When you see convergence, propose a decision and name any remaining risk briefly.
|
|
93
|
+
- Cover business + implementation + test impact when relevant; skip non-applicable angles.
|
|
94
|
+
- Keep it proportional. Small threads stay short.
|