opencode-planpilot 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 canxin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # opencode-planpilot
2
+
3
+ Planpilot rewritten in TypeScript for OpenCode. Provides plan/step/goal workflow with auto-continue for AI steps and a native `planpilot` tool.
4
+
5
+ ## Features
6
+ - Plan/step/goal hierarchy with automatic status rollups
7
+ - SQLite storage with markdown plan snapshots
8
+ - Native OpenCode tool plus optional CLI
9
+ - Auto-continue on `session.idle` when next step is assigned to `ai`
10
+
11
+ ## Requirements
12
+ - Bun runtime (uses `bun:sqlite` at runtime)
13
+
14
+ ## Install
15
+
16
+ Add to `opencode.json`:
17
+
18
+ ```json
19
+ {
20
+ "$schema": "https://opencode.ai/config.json",
21
+ "plugin": ["opencode-planpilot"]
22
+ }
23
+ ```
24
+
25
+ OpenCode installs npm plugins automatically at startup.
26
+
27
+ ## Details
28
+ Usage and storage info: `docs/planpilot.md`
29
+
30
+ ## License
31
+ MIT
@@ -0,0 +1,219 @@
1
+ # Planpilot (OpenCode Tool)
2
+
3
+ ## Tool Name
4
+ `planpilot`
5
+
6
+ ## What it is
7
+ Planpilot is a planner/tracker for multi-step work. It manages plans, steps, and goals, and automatically rolls up status.
8
+
9
+ ## OpenCode Tool Usage (Required)
10
+ Use the custom `planpilot` tool. Do **not** call the CLI via `bash` for planning.
11
+
12
+ ### Tool schema
13
+ - `argv?: string[]` - preferred; avoids quoting issues
14
+ - `command?: string` - optional; one command string
15
+
16
+ Rules:
17
+ - Provide either `argv` or `command`.
18
+ - Do **not** pass `--session-id` or `--cwd`; the tool injects them automatically from the current session.
19
+ - If both `argv` and `command` are provided, `argv` is used.
20
+
21
+ Example tool args:
22
+
23
+ ```json
24
+ { "argv": ["plan", "add", "Release v1.2", "Plan description"] }
25
+ ```
26
+
27
+ ```json
28
+ { "command": "plan add \"Release v1.2\" \"Plan description\"" }
29
+ ```
30
+
31
+ ## CLI (Optional)
32
+ A CLI binary named `planpilot` is available for manual use. If you use the CLI directly, you must pass `--session-id` and `--cwd` yourself.
33
+
34
+ ## Storage
35
+ - Database: `~/.config/opencode/.planpilot/planpilot.db`
36
+ - Plan snapshots: `~/.config/opencode/.planpilot/plans/`
37
+ - Override base directory: `OPENCODE_PLANPILOT_DIR` or `OPENCODE_PLANPILOT_HOME`
38
+
39
+ ## Hierarchy
40
+ - Plan contains steps; step contains goals.
41
+ - Goals are the smallest units of work; steps group goals; plans group steps.
42
+
43
+ ## AI Workflow Guidelines
44
+ - Use Planpilot for all planning, status, and progress tracking; do not use built-in plan/todo tools or other methods to track plan/step/goal status.
45
+ - Treat tool output as authoritative. Do not invent IDs; only use IDs shown by `list`/`show`.
46
+ - If the tool is missing or unavailable, ask the user to enable/install the plugin.
47
+ - Record implementation details using Planpilot comments (plan/step/goal `--comment` or `comment` commands). Before starting a step or goal, think through the next actions and capture that context in comments so the plan stays actionable.
48
+ - Before starting a new plan, do deep analysis; then create the plan with clear steps and goals.
49
+ - When creating a plan or step, prefer `add-tree` to define all steps/goals upfront.
50
+ - Prefer assigning steps to `ai`; only assign `human` for truly critical/high-risk items or when passwords, `sudo` access, irreversible git history rewrites, or remote git changes are required. If `human` steps are necessary, batch them, make the step content explicit about what the human must do, and only ask for user input when the next step is assigned to `human`.
51
+ - Adjust plans/steps/goals only when necessary; avoid frequent arbitrary changes.
52
+ - Update status promptly as work completes; mark goals done, and let steps/plans auto-refresh unless a step/plan has no children (then use `step done`/`plan done`).
53
+ - In each reply turn, complete at most one step; do not advance multiple steps in a single response.
54
+
55
+ ## Status Management
56
+ - Status values: `todo`, `done`.
57
+ - Goals are manual (`goal done`); steps/plans auto-refresh from child status, and use `step done`/`plan done` only when they have no children (`step done --all-goals` marks all goals done and then marks the step done). Auto status changes print as `Auto status updates:` with reasons.
58
+ - Parent status auto-flips to `todo` on incomplete child work and to `done` when all children are done. If a plan has 0 steps or a step has 0 goals, no auto-flip happens; use `plan done` / `step done` as needed.
59
+ - If the user completed a `human` step, verify/mark each goal and clearly list what remains.
60
+ - When a step becomes `done` and there is another pending step, the CLI will print the next-step instruction: for `ai`, end the turn so Planpilot can surface it; for `human`, show the step detail and tell the user to complete the goals, then end the turn. When a plan becomes `done` (automatic or manual), the CLI will prompt you to summarize completed results and end the turn.
61
+
62
+ ## Active Plan Management
63
+ - Use `plan activate` / `plan deactivate` to manage, and no active plan means the plan is paused until reactivated. Plans auto-deactivate on `done` (manual or automatic) or removal.
64
+ - Each plan can be active in only one session at a time; use `plan activate --force` to take over. Default to no `--force`, and if activation fails due to another session, ask the user whether to take over.
65
+ - Use `plan show-active` to know which plan is active and get its details.
66
+
67
+ ## Auto-Continue Behavior (OpenCode Plugin)
68
+ - The plugin listens to `session.idle` / `session.status` (idle) events.
69
+ - If there is an active plan and the next pending step is assigned to `ai`, it appends a `Planpilot (auto):` message to the prompt and submits it so the model continues the plan.
70
+ - It does nothing when there is no active plan or when the next step is assigned to `human`.
71
+
72
+ ## ID Notes
73
+ - Plan/step/goal IDs are database IDs and may be non-contiguous or not start at 1; always use the actual IDs shown by `list`/`show`.
74
+
75
+ ## Commands
76
+
77
+ - IMPORTANT: Do NOT pass `--cwd` or `--session-id` when using the tool. These are injected automatically.
78
+
79
+ ### plan
80
+ - Plan data is stored under OpenCode config: `~/.config/opencode/.planpilot/` (overridable via `OPENCODE_PLANPILOT_DIR` or `OPENCODE_PLANPILOT_HOME`).
81
+ - `plan add <title> <content>`: create a plan.
82
+ - Output: `Created plan ID: <id>: <title>`.
83
+ - `plan add-tree <title> <content> --step <content> [--executor ai|human] [--goal <goal> ...] [--step <content> ...]`: create a plan with steps/goals in one command.
84
+ - Output: `Created plan ID: <id>: <title> (steps: <n>, goals: <n>)`.
85
+ - Behavior: the newly created plan is automatically activated for the current session.
86
+ - Repeatable groups: you can repeat the `--step ... [--executor ...] [--goal ...]` group multiple times.
87
+ - Each `--executor` / `--goal` applies to the most recent `--step`.
88
+ - Example (tool args):
89
+ ```json
90
+ {"argv":["plan","add-tree","Release v1.2","Plan description","--step","Cut release branch","--executor","human","--goal","Create branch","--goal","Tag base","--step","Build artifacts","--executor","ai","--goal","Build packages"]}
91
+ ```
92
+ - Another example (3 steps, some without goals/executor):
93
+ ```json
94
+ {"argv":["plan","add-tree","Onboarding","Setup plan","--step","Create accounts","--goal","GitHub","--goal","Slack","--step","Install tooling","--executor","ai","--step","Read handbook"]}
95
+ ```
96
+ - `plan list [--scope project|all] [--status todo|done|all] [--limit N] [--page N] [--order id|title|created|updated] [--desc]`: list plans. Default: `--scope project`, `--status all`, `--limit 20`, `--page 1`, order by `updated` desc (most recent first).
97
+ - Output: prints a header line, then one line per plan with `ID STAT STEPS TITLE COMMENT` (`STEPS` is `done/total`); use `plan show` for full details.
98
+ - Output (empty): `No plans found.`
99
+ - Order: defaults to `updated` with most recent first. Use `--order` and `--desc` to override.
100
+ - Pagination: If `--page` is provided without `--limit`, the default limit is used.
101
+ - If `--page` exceeds the total pages, a warning is printed and no rows are returned.
102
+ - Footer: prints `Page N / Limit N` after the list.
103
+ - `plan count [--scope project|all] [--status todo|done|all]`: count plans matching the filters. Output: `Total: <n>`.
104
+ - `plan search --search <term> [--search <term> ...] [--search-mode any|all] [--search-field plan|title|content|comment|steps|goals|all] [--match-case] [--scope project|all] [--status todo|done|all] [--limit N] [--page N] [--order id|title|created|updated] [--desc]`: search plans. Default: `--scope project`, `--status all`, `--limit 20`, `--page 1`, order by `updated` desc.
105
+ - Output: same format as `plan list`.
106
+ - Output (empty): `No plans found.`
107
+ - Advanced search:
108
+ - `--search <term>` (repeatable): filter plans by text (required).
109
+ - `--search-mode any|all`: match any term or require all terms (default: `all`).
110
+ - `--search-field plan|title|content|comment|steps|goals|all` (default: `plan`).
111
+ - `--match-case`: make search case-sensitive.
112
+ - Pagination: If `--page` is provided without `--limit`, the default limit is used.
113
+ - If `--page` exceeds the total pages, a warning is printed and no rows are returned.
114
+ - Footer: prints `Page N / Limit N` after the list.
115
+ - `plan show <id>`: prints plan details and nested steps/goals (includes ids for plan/step/goal).
116
+ - Output: plan header includes `Plan ID: <id>`, `Title`, `Status`, `Content`, `Created`, `Updated`, and `Comment` when present.
117
+ - Output: each step line includes step id and executor; progress (`goals done/total`) is shown only when the step has goals. Each goal line includes goal id.
118
+ - `plan export <id> <path>`: export plan details to a markdown file.
119
+ - Output: `Exported plan ID: <id> to <path>`.
120
+ - `plan update <id> [--title <title>] [--content <content>] [--status todo|done] [--comment <comment>]`: update fields; `--status done` is allowed only when all steps are done or the plan has no steps.
121
+ - Output: `Updated plan ID: <id>: <title>`.
122
+ - Errors: multi-line `Error: Invalid input:` with `cannot mark plan done; next pending step:` on the next line, followed by the same step detail output as `step show`.
123
+ - `plan done <id>`: mark plan done (same rule as `plan update --status done`).
124
+ - Output: `Plan ID: <id> marked done.`
125
+ - Output (active plan): `Active plan deactivated because plan is done.`
126
+ - Errors: multi-line `Error: Invalid input:` with `cannot mark plan done; next pending step:` on the next line, followed by the same step detail output as `step show`.
127
+ - `plan comment <id1> <comment1> [<id2> <comment2> ...]`: add or replace comments for one or more plans.
128
+ - Output (single): `Updated plan comment for plan ID: <id>.`
129
+ - Output (batch): `Updated plan comments for <n> plans.`
130
+ - Each plan comment uses an `<id> <comment>` pair; you can provide multiple pairs in one call.
131
+ - Example:
132
+ ```json
133
+ {"argv":["plan","comment","12","high priority","15","waiting on input"]}
134
+ ```
135
+ - `plan remove <id>`: remove plan (and its steps/goals).
136
+ - Output: `Plan ID: <id> removed.`
137
+ - `plan activate <id> [--force]`: set the active plan.
138
+ - Output: `Active plan set to <id>: <title>`.
139
+ - `--force` takes over a plan already active in another session.
140
+ - Errors: `Error: Invalid input: cannot activate plan; plan is done`.
141
+ - Errors: `Error: Invalid input: plan id <id> is already active in session <session_id> (use --force to take over)`.
142
+ - `plan show-active`: prints the active plan details (same format as `plan show`).
143
+ - Output: the same plan detail format as `plan show`.
144
+ - Output (empty): `No active plan.`
145
+ - Output (missing): `Active plan ID: <id> not found.`
146
+ - `plan deactivate`: unset the active plan (does not delete any plan).
147
+ - Output: `Active plan deactivated.`
148
+
149
+ ### step
150
+ - `step add <plan_id> <content1> [<content2> ...] [--at <pos>] [--executor ai|human]`: add steps.
151
+ - Output (single): `Created step ID: <id> for plan ID: <plan_id>`.
152
+ - Output (batch): `Created <n> steps for plan ID: <plan_id>`.
153
+ - `step add-tree <plan_id> <content> [--executor ai|human] [--goal <goal> ...]`: create one step with goals in one command.
154
+ - Output: `Created step ID: <id> for plan ID: <plan_id> (goals: <n>)`.
155
+ - Example:
156
+ ```json
157
+ {"argv":["step","add-tree","1","Draft summary","--executor","ai","--goal","Collect inputs","--goal","Write draft"]}
158
+ ```
159
+ - `step list <plan_id> [--status todo|done|all] [--executor ai|human] [--limit N] [--page N]`: list steps. Default: `--status all`, `--limit 20`, `--page 1`. Steps are always returned in their plan order.
160
+ - Output: prints a header line, then one line per step with `ID STAT ORD EXEC GOALS CONTENT COMMENT` (`ORD` is the step order within the plan; `GOALS` is `done/total`); use `step show` for full details.
161
+ - Output (empty): `No steps found for plan ID: <plan_id>.`
162
+ - Pagination: If `--page` is provided without `--limit`, the default limit is used.
163
+ - If `--page` exceeds the total pages, a warning is printed and no rows are returned.
164
+ - Footer: prints `Page N / Limit N` after the list.
165
+ - `step count <plan_id> [--status todo|done|all] [--executor ai|human]`: count steps matching the filters. Output: `Total: <n>`.
166
+ - `step show <id>`: prints a single step with full details and its nested goals (includes ids for step/goal).
167
+ - Output: step header includes `Step ID: <id>`, `Plan ID`, `Status`, `Executor`, `Content`, `Created`, `Updated`, and `Comment` when present.
168
+ - Output: lists all goals with `[status]` and goal id.
169
+ - `step show-next`: show the next pending step for the active plan (same format as `step show`).
170
+ - Output (empty): `No active plan.` or `No pending step.`.
171
+ - `step update <id> [--content <content>] [--status todo|done] [--executor ai|human] [--comment <comment>]`: update fields; `--status done` is allowed only when all goals are done or the step has no goals.
172
+ - Output: `Updated step ID: <id>.`.
173
+ - Errors: `Error: Invalid input: cannot mark step done; next pending goal: <content> (id <id>)`.
174
+ - `step comment <id1> <comment1> [<id2> <comment2> ...]`: add or replace comments for one or more steps.
175
+ - Output (single): `Updated step comments for plan ID: <plan_id>.`
176
+ - Output (batch): `Updated step comments for <n> plans.`
177
+ - Each step comment uses an `<id> <comment>` pair; you can provide multiple pairs in one call.
178
+ - Example:
179
+ ```json
180
+ {"argv":["step","comment","45","blocked by API","46","ready to start"]}
181
+ ```
182
+ - `step done <id> [--all-goals]`: mark step done (same rule as `step update --status done`). Use `--all-goals` to mark all goals in the step done first, then mark the step done.
183
+ - Output: `Step ID: <id> marked done.`
184
+ - Errors: `Error: Invalid input: cannot mark step done; next pending goal: <content> (id <id>)`.
185
+ - `step move <id> --to <pos>`: reorder and print the same one-line list as `step list`.
186
+ - Output: `Reordered steps for plan ID: <plan_id>:` + list.
187
+ - `step remove <id1> [<id2> ...]`: remove step(s).
188
+ - Output (single): `Step ID: <id> removed.`
189
+ - Output (batch): `Removed <n> steps.`
190
+ - Errors: `Error: Not found: step id(s) not found: <id1>[, <id2> ...]`.
191
+
192
+ ### goal
193
+ - `goal add <step_id> <content1> [<content2> ...]`: add goals to a step.
194
+ - Output (single): `Created goal ID: <id> for step ID: <step_id>`.
195
+ - Output (batch): `Created <n> goals for step ID: <step_id>`.
196
+ - `goal list <step_id> [--status todo|done|all] [--limit N] [--page N]`: list goals. Default: `--status all`, `--limit 20`, `--page 1`, order by `updated` desc (most recent first).
197
+ - Output: prints a header line, then one line per goal with `ID STAT CONTENT COMMENT`.
198
+ - Output (empty): `No goals found for step ID: <step_id>.`
199
+ - Pagination: If `--page` is provided without `--limit`, the default limit is used.
200
+ - If `--page` exceeds the total pages, a warning is printed and no rows are returned.
201
+ - Footer: prints `Page N / Limit N` after the list.
202
+ - `goal count <step_id> [--status todo|done|all]`: count goals matching the filters. Output: `Total: <n>`.
203
+ - `goal update <id> [--content <content>] [--status todo|done] [--comment <comment>]`: update fields.
204
+ - Output: `Updated goal <id>.`
205
+ - `goal comment <id1> <comment1> [<id2> <comment2> ...]`: add or replace comments for one or more goals.
206
+ - Output (single): `Updated goal comments for plan ID: <plan_id>.`
207
+ - Output (batch): `Updated goal comments for <n> plans.`
208
+ - Each goal comment uses an `<id> <comment>` pair; you can provide multiple pairs in one call.
209
+ - Example:
210
+ ```json
211
+ {"argv":["goal","comment","78","done","81","needs review"]}
212
+ ```
213
+ - `goal done <id1> [<id2> ...]`: mark one or more goals done.
214
+ - Output (single): `Goal ID: <id> marked done.`
215
+ - Output (batch): `Goals marked done: <n>.`
216
+ - `goal remove <id1> [<id2> ...]`: remove goal(s).
217
+ - Output (single): `Goal ID: <id> removed.`
218
+ - Output (batch): `Removed <n> goals.`
219
+ - Errors: `Error: Not found: goal id(s) not found: <id1>[, <id2> ...]`.
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "opencode-planpilot",
3
+ "version": "0.1.0",
4
+ "description": "Planpilot plugin for OpenCode (TypeScript rewrite)",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/canxin121/opencode-planpilot.git"
9
+ },
10
+ "homepage": "https://github.com/canxin121/opencode-planpilot",
11
+ "bugs": {
12
+ "url": "https://github.com/canxin121/opencode-planpilot/issues"
13
+ },
14
+ "packageManager": "bun@1.3.6",
15
+ "main": "./src/index.ts",
16
+ "types": "./src/index.ts",
17
+ "bin": {
18
+ "planpilot": "src/cli.ts",
19
+ "opencode-planpilot": "src/cli.ts"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "import": "./src/index.ts",
24
+ "types": "./src/index.ts"
25
+ },
26
+ "./cli": {
27
+ "import": "./src/cli.ts",
28
+ "types": "./src/cli.ts"
29
+ }
30
+ },
31
+ "files": [
32
+ "src",
33
+ "docs",
34
+ "README.md",
35
+ "LICENSE"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "dev": "tsup --watch",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "lint": "eslint . --ext .ts",
42
+ "lint:fix": "eslint . --ext .ts --fix"
43
+ },
44
+ "dependencies": {
45
+ "xdg-basedir": "^5.1.0"
46
+ },
47
+ "peerDependencies": {
48
+ "@opencode-ai/plugin": "*"
49
+ },
50
+ "devDependencies": {
51
+ "@opencode-ai/plugin": "*",
52
+ "@types/node": "^25.0.8",
53
+ "bun-types": "^1.3.6",
54
+ "eslint": "^9.39.2",
55
+ "@eslint/js": "^9.39.2",
56
+ "@typescript-eslint/eslint-plugin": "^8.53.0",
57
+ "@typescript-eslint/parser": "^8.53.0",
58
+ "tsup": "^8.5.1",
59
+ "typescript": "^5.9.3"
60
+ },
61
+ "license": "MIT"
62
+ }