opencode-planpilot 0.2.4 → 0.3.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 +28 -394
- package/README.zh-CN.md +55 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,421 +1,55 @@
|
|
|
1
1
|
# opencode-planpilot
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Chinese version: [README.zh-CN.md](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Plan/step/goal hierarchy with status auto-propagation upward (goals -> steps -> plan)
|
|
7
|
-
- SQLite storage with markdown plan snapshots
|
|
8
|
-
- Native OpenCode tool for plan/step/goal operations
|
|
9
|
-
- Auto-continue on `session.idle` when next step is assigned to `ai`
|
|
10
|
-
- Configurable auto-continue triggers for stop/pause/error events (with keyword filters)
|
|
5
|
+
Planpilot adds a structured execution loop to OpenCode so multi-step work stays organized, visible, and easier to complete.
|
|
11
6
|
|
|
12
|
-
##
|
|
7
|
+
## Why Teams Use Planpilot
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
- Turn complex work into a clear `plan -> step -> goal` workflow.
|
|
10
|
+
- Keep momentum by auto-continuing when the next pending step is assigned to `ai`.
|
|
11
|
+
- Persist progress locally (database + markdown snapshots) so context is never lost.
|
|
12
|
+
- Keep collaboration natural: you describe intent in plain language, and Planpilot keeps execution structured.
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
"plugin": ["opencode-planpilot"]
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
OpenCode installs npm plugins automatically at startup.
|
|
23
|
-
|
|
24
|
-
## Studio Integration
|
|
25
|
-
|
|
26
|
-
- Studio manifest is generated at `dist/studio.manifest.json`.
|
|
27
|
-
- Bridge entrypoint is generated at `dist/studio-bridge.js` and is invoked by the manifest.
|
|
28
|
-
- Web mount assets are generated under `dist/studio-web/`.
|
|
29
|
-
|
|
30
|
-
The Studio bridge accepts JSON on stdin and returns a JSON envelope on stdout (`{ ok, data | error }`).
|
|
31
|
-
|
|
32
|
-
Key actions:
|
|
33
|
-
|
|
34
|
-
- `config.get`, `config.set`
|
|
35
|
-
- `runtime.snapshot`, `runtime.next`, `runtime.pause`, `runtime.resume`
|
|
36
|
-
- `plan.*`, `step.*`, `goal.*` (including `plan.createTree` / `plan.addTree`)
|
|
37
|
-
- `events.poll` for change cursors + event envelopes
|
|
38
|
-
|
|
39
|
-
Studio UI integration includes:
|
|
40
|
-
|
|
41
|
-
- `chat.sidebar` mount for runtime + next-step context
|
|
42
|
-
- `settings.panel` capability backed by plugin settings schema
|
|
43
|
-
|
|
44
|
-
## Configuration
|
|
45
|
-
|
|
46
|
-
Planpilot configuration comes from:
|
|
47
|
-
|
|
48
|
-
- Environment variables (to control where data/config is stored)
|
|
49
|
-
- An optional JSON config file (to control auto-continue behavior)
|
|
50
|
-
|
|
51
|
-
### Paths and environment variables
|
|
14
|
+
## Installation
|
|
52
15
|
|
|
53
|
-
|
|
16
|
+
Add the plugin to your OpenCode config file `opencode.json`:
|
|
54
17
|
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
- Override: `OPENCODE_CONFIG_DIR=/abs/path`
|
|
58
|
-
- Planpilot data directory
|
|
59
|
-
- Default: `~/.config/opencode/.planpilot`
|
|
60
|
-
- If `OPENCODE_CONFIG_DIR` is set, the default becomes `${OPENCODE_CONFIG_DIR}/.planpilot`.
|
|
61
|
-
- Override: `OPENCODE_PLANPILOT_DIR=/abs/path` (or the legacy alias `OPENCODE_PLANPILOT_HOME`)
|
|
62
|
-
- Planpilot config file
|
|
63
|
-
- Default: `~/.config/opencode/.planpilot/config.json`
|
|
64
|
-
- If `OPENCODE_PLANPILOT_DIR` is set, the default becomes `${OPENCODE_PLANPILOT_DIR}/config.json`.
|
|
65
|
-
- Override: `OPENCODE_PLANPILOT_CONFIG=/abs/path/to/config.json`
|
|
66
|
-
- If a relative path is provided, it is resolved to an absolute path.
|
|
18
|
+
- Unix/macOS: `~/.config/opencode/opencode.json`
|
|
19
|
+
- Windows: `%USERPROFILE%\\.config\\opencode\\opencode.json` (for example: `C:\\Users\\<your-user>\\.config\\opencode\\opencode.json`)
|
|
67
20
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `planpilot.db` - SQLite database (plans/steps/goals + active plan pointer)
|
|
71
|
-
- `plans/plan_<id>.md` - Markdown plan snapshots (kept in sync on write operations)
|
|
72
|
-
|
|
73
|
-
### Config load + validation behavior
|
|
74
|
-
|
|
75
|
-
- Missing config file: Planpilot falls back to defaults (idle-only triggers).
|
|
76
|
-
- Invalid JSON / invalid shape: Planpilot falls back to defaults and logs a load warning.
|
|
77
|
-
- Normalization:
|
|
78
|
-
- Unknown fields are ignored.
|
|
79
|
-
- String arrays are trimmed, empty strings removed, and duplicates de-duped.
|
|
80
|
-
- Number arrays are filtered to finite numbers, truncated to integers, and de-duped.
|
|
81
|
-
- Integers that must be positive (e.g. `maxAttempts`) fall back to defaults if invalid.
|
|
82
|
-
|
|
83
|
-
Note on live changes:
|
|
84
|
-
|
|
85
|
-
- The core plugin currently loads `autoContinue.*` once at initialization. If you change `autoContinue.*`, restart OpenCode (or reload the plugin) for the new values to take effect.
|
|
86
|
-
- `runtime.paused` is exposed via Studio and persisted to the config file, but the core auto-continue loop does not currently consult it.
|
|
87
|
-
|
|
88
|
-
### Config file schema
|
|
89
|
-
|
|
90
|
-
All fields are optional; missing values fall back to safe defaults.
|
|
91
|
-
|
|
92
|
-
Default config:
|
|
93
|
-
|
|
94
|
-
```json
|
|
21
|
+
```jsonc
|
|
95
22
|
{
|
|
96
|
-
"
|
|
97
|
-
"sendRetry": {
|
|
98
|
-
"enabled": true,
|
|
99
|
-
"maxAttempts": 3,
|
|
100
|
-
"delaysMs": [1500, 5000, 15000]
|
|
101
|
-
},
|
|
102
|
-
"onSessionError": {
|
|
103
|
-
"enabled": false,
|
|
104
|
-
"force": true,
|
|
105
|
-
"keywords": {
|
|
106
|
-
"any": [],
|
|
107
|
-
"all": [],
|
|
108
|
-
"none": [],
|
|
109
|
-
"matchCase": false
|
|
110
|
-
},
|
|
111
|
-
"errorNames": [],
|
|
112
|
-
"statusCodes": [],
|
|
113
|
-
"retryableOnly": false
|
|
114
|
-
},
|
|
115
|
-
"onSessionRetry": {
|
|
116
|
-
"enabled": false,
|
|
117
|
-
"force": false,
|
|
118
|
-
"keywords": {
|
|
119
|
-
"any": [],
|
|
120
|
-
"all": [],
|
|
121
|
-
"none": [],
|
|
122
|
-
"matchCase": false
|
|
123
|
-
},
|
|
124
|
-
"attemptAtLeast": 1
|
|
125
|
-
},
|
|
126
|
-
"onPermissionAsked": {
|
|
127
|
-
"enabled": false,
|
|
128
|
-
"force": false,
|
|
129
|
-
"keywords": {
|
|
130
|
-
"any": [],
|
|
131
|
-
"all": [],
|
|
132
|
-
"none": [],
|
|
133
|
-
"matchCase": false
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
"onPermissionRejected": {
|
|
137
|
-
"enabled": false,
|
|
138
|
-
"force": true,
|
|
139
|
-
"keywords": {
|
|
140
|
-
"any": [],
|
|
141
|
-
"all": [],
|
|
142
|
-
"none": [],
|
|
143
|
-
"matchCase": false
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
"onQuestionAsked": {
|
|
147
|
-
"enabled": false,
|
|
148
|
-
"force": false,
|
|
149
|
-
"keywords": {
|
|
150
|
-
"any": [],
|
|
151
|
-
"all": [],
|
|
152
|
-
"none": [],
|
|
153
|
-
"matchCase": false
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
"onQuestionRejected": {
|
|
157
|
-
"enabled": false,
|
|
158
|
-
"force": true,
|
|
159
|
-
"keywords": {
|
|
160
|
-
"any": [],
|
|
161
|
-
"all": [],
|
|
162
|
-
"none": [],
|
|
163
|
-
"matchCase": false
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
"runtime": {
|
|
168
|
-
"paused": false
|
|
169
|
-
}
|
|
23
|
+
"plugin": ["opencode-planpilot"]
|
|
170
24
|
}
|
|
171
25
|
```
|
|
172
26
|
|
|
173
|
-
|
|
27
|
+
OpenCode installs npm plugins automatically when the session starts.
|
|
174
28
|
|
|
175
|
-
|
|
176
|
-
- Additional triggers are optional and configured in:
|
|
29
|
+
## Quick Start with Natural Language
|
|
177
30
|
|
|
178
|
-
|
|
179
|
-
- Override path: `OPENCODE_PLANPILOT_CONFIG=/abs/path/to/config.json`
|
|
31
|
+
Example prompt:
|
|
180
32
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
```json
|
|
184
|
-
{
|
|
185
|
-
"autoContinue": {
|
|
186
|
-
"sendRetry": {
|
|
187
|
-
"enabled": true,
|
|
188
|
-
"maxAttempts": 3,
|
|
189
|
-
"delaysMs": [1500, 5000, 15000]
|
|
190
|
-
},
|
|
191
|
-
"onSessionError": {
|
|
192
|
-
"enabled": true,
|
|
193
|
-
"force": true,
|
|
194
|
-
"errorNames": ["APIError", "UnknownError"],
|
|
195
|
-
"statusCodes": [408, 429, 500, 502, 503, 504],
|
|
196
|
-
"retryableOnly": true,
|
|
197
|
-
"keywords": {
|
|
198
|
-
"any": ["rate", "overload", "timeout"],
|
|
199
|
-
"all": [],
|
|
200
|
-
"none": ["aborted"],
|
|
201
|
-
"matchCase": false
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
"onSessionRetry": {
|
|
205
|
-
"enabled": false,
|
|
206
|
-
"force": false,
|
|
207
|
-
"attemptAtLeast": 2,
|
|
208
|
-
"keywords": {
|
|
209
|
-
"any": ["overloaded", "rate"],
|
|
210
|
-
"all": [],
|
|
211
|
-
"none": [],
|
|
212
|
-
"matchCase": false
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
"onPermissionAsked": {
|
|
216
|
-
"enabled": false,
|
|
217
|
-
"force": false,
|
|
218
|
-
"keywords": {
|
|
219
|
-
"any": [],
|
|
220
|
-
"all": [],
|
|
221
|
-
"none": [],
|
|
222
|
-
"matchCase": false
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
"onPermissionRejected": {
|
|
226
|
-
"enabled": true,
|
|
227
|
-
"force": true,
|
|
228
|
-
"keywords": {
|
|
229
|
-
"any": ["write"],
|
|
230
|
-
"all": [],
|
|
231
|
-
"none": [],
|
|
232
|
-
"matchCase": false
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
"onQuestionAsked": {
|
|
236
|
-
"enabled": false,
|
|
237
|
-
"force": false,
|
|
238
|
-
"keywords": {
|
|
239
|
-
"any": [],
|
|
240
|
-
"all": [],
|
|
241
|
-
"none": [],
|
|
242
|
-
"matchCase": false
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
"onQuestionRejected": {
|
|
246
|
-
"enabled": true,
|
|
247
|
-
"force": true,
|
|
248
|
-
"keywords": {
|
|
249
|
-
"any": ["confirm"],
|
|
250
|
-
"all": [],
|
|
251
|
-
"none": [],
|
|
252
|
-
"matchCase": false
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
33
|
+
```text
|
|
34
|
+
Use planpilot.
|
|
257
35
|
```
|
|
258
36
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
#### `runtime`
|
|
262
|
-
|
|
263
|
-
- `runtime.paused` (boolean)
|
|
264
|
-
- Persisted to the config file and surfaced in Studio runtime snapshots.
|
|
265
|
-
- Currently not used by the core auto-continue loop (see note above).
|
|
266
|
-
|
|
267
|
-
#### `autoContinue.sendRetry`
|
|
37
|
+
## OpenCode Studio Experience
|
|
268
38
|
|
|
269
|
-
|
|
39
|
+
Planpilot ships first-class OpenCode Studio integration:
|
|
270
40
|
|
|
271
|
-
-
|
|
272
|
-
- `maxAttempts` (integer, min 1): maximum number of attempts per plan/step signature.
|
|
273
|
-
- `delaysMs` (integer[], min 1): backoff delays in milliseconds.
|
|
274
|
-
- Attempt 1 uses `delaysMs[0]`, attempt 2 uses `delaysMs[1]`, etc.
|
|
275
|
-
- If attempts exceed the array length, the last delay is used.
|
|
41
|
+
- Learn more: [opencode-studio](https://github.com/canxin121/opencode-studio)
|
|
276
42
|
|
|
277
|
-
|
|
43
|
+
- Runtime context in the Studio sidebar (active plan, next step, progress state).
|
|
44
|
+
- A Studio settings panel for Planpilot runtime and auto-continue controls.
|
|
45
|
+
- A Studio bridge for reading/writing runtime and configuration state.
|
|
278
46
|
|
|
279
|
-
|
|
280
|
-
Each rule has the same base shape:
|
|
47
|
+
If you already run multi-step work in OpenCode, using OpenCode Studio is the fastest way to monitor flow, tune behavior, and keep your team aligned from one UI.
|
|
281
48
|
|
|
282
|
-
|
|
283
|
-
- `force` (boolean): bypass default safety guards when the rule matches.
|
|
284
|
-
- Guards that `force=true` can bypass include:
|
|
285
|
-
- last assistant message was aborted (`MessageAbortedError`)
|
|
286
|
-
- last assistant message is not "ready" (e.g. finished with tool-calls)
|
|
287
|
-
- `keywords` (object): substring match rules against the event summary text.
|
|
288
|
-
- `any`: if non-empty, at least one term must appear.
|
|
289
|
-
- `all`: all terms must appear.
|
|
290
|
-
- `none`: no terms may appear.
|
|
291
|
-
- `matchCase`: case-sensitive matching when true.
|
|
292
|
-
- If all arrays are empty, the keyword rule matches everything.
|
|
49
|
+
## Details
|
|
293
50
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
- `onSessionError`: summary includes `error=<name>`, optional `status=<code>`, optional `retryable=<bool>`, plus message text.
|
|
297
|
-
- `onSessionRetry`: summary includes `attempt=<n>`, optional `next=<ms>`, plus message text.
|
|
298
|
-
- `onPermissionAsked`: summary includes `<permission>` and optional `patterns=a,b,c`.
|
|
299
|
-
- `onPermissionRejected`: summary includes the asked summary (if available), plus `request=<id> reply=reject`.
|
|
300
|
-
- `onQuestionAsked`: summary concatenates question `header` + `question` items (joined with ` | `).
|
|
301
|
-
- `onQuestionRejected`: summary includes the asked summary (if available), plus `request=<id> question=rejected`.
|
|
302
|
-
|
|
303
|
-
Event-specific fields:
|
|
304
|
-
|
|
305
|
-
- `autoContinue.onSessionError`
|
|
306
|
-
- `errorNames` (string[]): if non-empty, only match when `error.name` is in the list.
|
|
307
|
-
- `statusCodes` (integer[]): if non-empty, only match when `error.data.statusCode` is in the list.
|
|
308
|
-
- `retryableOnly` (boolean): when true, only match when `error.data.isRetryable === true`.
|
|
309
|
-
- `autoContinue.onSessionRetry`
|
|
310
|
-
- `attemptAtLeast` (integer, min 1): only match when `status.attempt >= attemptAtLeast`.
|
|
311
|
-
|
|
312
|
-
### Operational notes (non-configurable behavior)
|
|
313
|
-
|
|
314
|
-
- `session.idle` / `session.status=idle` always triggers an auto-continue check and cannot be disabled.
|
|
315
|
-
- Auto-continue only sends when an active plan exists and its next pending step has `executor="ai"`.
|
|
316
|
-
- Step wait annotations
|
|
317
|
-
- `planpilot step wait <step_id> --delay <ms> [--reason <text>]` stores wait markers in the step comment:
|
|
318
|
-
- `@wait-until=<epoch_ms>`
|
|
319
|
-
- `@wait-reason=<text>`
|
|
320
|
-
- When present, Planpilot will delay auto-sending that step until the timestamp.
|
|
321
|
-
- Manual-stop protection
|
|
322
|
-
- If OpenCode emits `MessageAbortedError`, Planpilot arms a manual-stop guard.
|
|
323
|
-
- While active: queued triggers/retries are canceled and auto-sends are suppressed.
|
|
324
|
-
- The guard is cleared when a new user message arrives.
|
|
325
|
-
|
|
326
|
-
### How to modify configuration
|
|
327
|
-
|
|
328
|
-
- Edit the JSON file directly
|
|
329
|
-
- Default path: `~/.config/opencode/.planpilot/config.json`
|
|
330
|
-
- Or set `OPENCODE_PLANPILOT_CONFIG` to use a different file.
|
|
331
|
-
- Use OpenCode Studio
|
|
332
|
-
- The Studio settings panel uses bridge actions `config.get` / `config.set`.
|
|
333
|
-
- The runtime toggle uses `runtime.pause` / `runtime.resume` (persists `runtime.paused`).
|
|
334
|
-
|
|
335
|
-
### Studio settings panel mapping (settingsSchema)
|
|
336
|
-
|
|
337
|
-
Planpilot advertises the `settings.panel` capability and ships a JSON Schema in `dist/studio.manifest.json` under `settingsSchema`.
|
|
338
|
-
OpenCode Studio uses this schema to render the settings form.
|
|
339
|
-
|
|
340
|
-
The schema is authored in `tsup.config.ts` and written into the generated Studio manifest at build time.
|
|
341
|
-
|
|
342
|
-
The settings panel fields map 1:1 to the config file object. The UI group/label corresponds to a config path like `autoContinue.onSessionError.keywords.any`.
|
|
343
|
-
|
|
344
|
-
Top-level groups:
|
|
345
|
-
|
|
346
|
-
- `Runtime` -> `runtime`
|
|
347
|
-
- `Auto continue` -> `autoContinue`
|
|
348
|
-
|
|
349
|
-
#### Runtime
|
|
350
|
-
|
|
351
|
-
- `Runtime > Paused` -> `runtime.paused` (boolean, default `false`)
|
|
352
|
-
|
|
353
|
-
#### Auto continue
|
|
354
|
-
|
|
355
|
-
Retry failed sends:
|
|
356
|
-
|
|
357
|
-
- `Auto continue > Retry failed sends > Enabled` -> `autoContinue.sendRetry.enabled` (boolean, default `true`)
|
|
358
|
-
- `Auto continue > Retry failed sends > Max attempts` -> `autoContinue.sendRetry.maxAttempts` (integer, minimum `1`, default `3`)
|
|
359
|
-
- `Auto continue > Retry failed sends > Delays (ms)` -> `autoContinue.sendRetry.delaysMs` (integer[], items minimum `1`, default `[1500, 5000, 15000]`)
|
|
360
|
-
|
|
361
|
-
Session error trigger:
|
|
362
|
-
|
|
363
|
-
- `Auto continue > On session error > Enabled` -> `autoContinue.onSessionError.enabled` (boolean, default `false`)
|
|
364
|
-
- `Auto continue > On session error > Force` -> `autoContinue.onSessionError.force` (boolean, default `true`)
|
|
365
|
-
- `Auto continue > On session error > Keywords > Any` -> `autoContinue.onSessionError.keywords.any` (string[], default `[]`)
|
|
366
|
-
- `Auto continue > On session error > Keywords > All` -> `autoContinue.onSessionError.keywords.all` (string[], default `[]`)
|
|
367
|
-
- `Auto continue > On session error > Keywords > None` -> `autoContinue.onSessionError.keywords.none` (string[], default `[]`)
|
|
368
|
-
- `Auto continue > On session error > Keywords > Match case` -> `autoContinue.onSessionError.keywords.matchCase` (boolean, default `false`)
|
|
369
|
-
- `Auto continue > On session error > Error names` -> `autoContinue.onSessionError.errorNames` (string[], default `[]`)
|
|
370
|
-
- `Auto continue > On session error > Status codes` -> `autoContinue.onSessionError.statusCodes` (integer[], default `[]`)
|
|
371
|
-
- `Auto continue > On session error > Retryable only` -> `autoContinue.onSessionError.retryableOnly` (boolean, default `false`)
|
|
372
|
-
|
|
373
|
-
Session retry trigger:
|
|
374
|
-
|
|
375
|
-
- `Auto continue > On session retry > Enabled` -> `autoContinue.onSessionRetry.enabled` (boolean, default `false`)
|
|
376
|
-
- `Auto continue > On session retry > Force` -> `autoContinue.onSessionRetry.force` (boolean, default `false`)
|
|
377
|
-
- `Auto continue > On session retry > Keywords > Any` -> `autoContinue.onSessionRetry.keywords.any` (string[], default `[]`)
|
|
378
|
-
- `Auto continue > On session retry > Keywords > All` -> `autoContinue.onSessionRetry.keywords.all` (string[], default `[]`)
|
|
379
|
-
- `Auto continue > On session retry > Keywords > None` -> `autoContinue.onSessionRetry.keywords.none` (string[], default `[]`)
|
|
380
|
-
- `Auto continue > On session retry > Keywords > Match case` -> `autoContinue.onSessionRetry.keywords.matchCase` (boolean, default `false`)
|
|
381
|
-
- `Auto continue > On session retry > Attempt at least` -> `autoContinue.onSessionRetry.attemptAtLeast` (integer, minimum `1`, default `1`)
|
|
382
|
-
|
|
383
|
-
Permission triggers:
|
|
384
|
-
|
|
385
|
-
- `Auto continue > On permission asked > Enabled` -> `autoContinue.onPermissionAsked.enabled` (boolean, default `false`)
|
|
386
|
-
- `Auto continue > On permission asked > Force` -> `autoContinue.onPermissionAsked.force` (boolean, default `false`)
|
|
387
|
-
- `Auto continue > On permission asked > Keywords > Any` -> `autoContinue.onPermissionAsked.keywords.any` (string[], default `[]`)
|
|
388
|
-
- `Auto continue > On permission asked > Keywords > All` -> `autoContinue.onPermissionAsked.keywords.all` (string[], default `[]`)
|
|
389
|
-
- `Auto continue > On permission asked > Keywords > None` -> `autoContinue.onPermissionAsked.keywords.none` (string[], default `[]`)
|
|
390
|
-
- `Auto continue > On permission asked > Keywords > Match case` -> `autoContinue.onPermissionAsked.keywords.matchCase` (boolean, default `false`)
|
|
391
|
-
|
|
392
|
-
- `Auto continue > On permission rejected > Enabled` -> `autoContinue.onPermissionRejected.enabled` (boolean, default `false`)
|
|
393
|
-
- `Auto continue > On permission rejected > Force` -> `autoContinue.onPermissionRejected.force` (boolean, default `true`)
|
|
394
|
-
- `Auto continue > On permission rejected > Keywords > Any` -> `autoContinue.onPermissionRejected.keywords.any` (string[], default `[]`)
|
|
395
|
-
- `Auto continue > On permission rejected > Keywords > All` -> `autoContinue.onPermissionRejected.keywords.all` (string[], default `[]`)
|
|
396
|
-
- `Auto continue > On permission rejected > Keywords > None` -> `autoContinue.onPermissionRejected.keywords.none` (string[], default `[]`)
|
|
397
|
-
- `Auto continue > On permission rejected > Keywords > Match case` -> `autoContinue.onPermissionRejected.keywords.matchCase` (boolean, default `false`)
|
|
398
|
-
|
|
399
|
-
Question triggers:
|
|
400
|
-
|
|
401
|
-
- `Auto continue > On question asked > Enabled` -> `autoContinue.onQuestionAsked.enabled` (boolean, default `false`)
|
|
402
|
-
- `Auto continue > On question asked > Force` -> `autoContinue.onQuestionAsked.force` (boolean, default `false`)
|
|
403
|
-
- `Auto continue > On question asked > Keywords > Any` -> `autoContinue.onQuestionAsked.keywords.any` (string[], default `[]`)
|
|
404
|
-
- `Auto continue > On question asked > Keywords > All` -> `autoContinue.onQuestionAsked.keywords.all` (string[], default `[]`)
|
|
405
|
-
- `Auto continue > On question asked > Keywords > None` -> `autoContinue.onQuestionAsked.keywords.none` (string[], default `[]`)
|
|
406
|
-
- `Auto continue > On question asked > Keywords > Match case` -> `autoContinue.onQuestionAsked.keywords.matchCase` (boolean, default `false`)
|
|
407
|
-
|
|
408
|
-
- `Auto continue > On question rejected > Enabled` -> `autoContinue.onQuestionRejected.enabled` (boolean, default `false`)
|
|
409
|
-
- `Auto continue > On question rejected > Force` -> `autoContinue.onQuestionRejected.force` (boolean, default `true`)
|
|
410
|
-
- `Auto continue > On question rejected > Keywords > Any` -> `autoContinue.onQuestionRejected.keywords.any` (string[], default `[]`)
|
|
411
|
-
- `Auto continue > On question rejected > Keywords > All` -> `autoContinue.onQuestionRejected.keywords.all` (string[], default `[]`)
|
|
412
|
-
- `Auto continue > On question rejected > Keywords > None` -> `autoContinue.onQuestionRejected.keywords.none` (string[], default `[]`)
|
|
413
|
-
- `Auto continue > On question rejected > Keywords > Match case` -> `autoContinue.onQuestionRejected.keywords.matchCase` (boolean, default `false`)
|
|
414
|
-
|
|
415
|
-
Notes:
|
|
416
|
-
|
|
417
|
-
- Studio persists settings by calling `config.set` and Planpilot writes the normalized config to the resolved config path.
|
|
418
|
-
- `runtime.pause` / `runtime.resume` also persist `runtime.paused` (and are used by the bundled runtime UI), but are separate from the settings panel.
|
|
51
|
+
Detailed configuration schema, bridge actions, parameter-level behavior, and event/trigger rules are documented in `DETAIL.md`.
|
|
419
52
|
|
|
420
53
|
## License
|
|
54
|
+
|
|
421
55
|
MIT
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# opencode-planpilot
|
|
2
|
+
|
|
3
|
+
English version: [README.md](README.md)
|
|
4
|
+
|
|
5
|
+
Planpilot 为 OpenCode 提供结构化执行循环,让多步骤工作更有条理、更可追踪,也更容易持续推进。
|
|
6
|
+
|
|
7
|
+
## 为什么选择 Planpilot
|
|
8
|
+
|
|
9
|
+
- 将复杂任务拆解为清晰的 `plan -> step -> goal` 流程。
|
|
10
|
+
- 当下一个待执行步骤归属 `ai` 时自动续跑,保持执行节奏。
|
|
11
|
+
- 本地持久化进度(数据库 + Markdown 快照),上下文不丢失。
|
|
12
|
+
- 你只需用自然语言下达目标,Planpilot 负责保持执行结构。
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
在 OpenCode 配置文件 `opencode.json` 中添加插件:
|
|
17
|
+
|
|
18
|
+
- Unix/macOS: `~/.config/opencode/opencode.json`
|
|
19
|
+
- Windows: `%USERPROFILE%\\.config\\opencode\\opencode.json` (for example: `C:\\Users\\<your-user>\\.config\\opencode\\opencode.json`)
|
|
20
|
+
|
|
21
|
+
```jsonc
|
|
22
|
+
{
|
|
23
|
+
"plugin": ["opencode-planpilot"]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
OpenCode 会在会话启动时自动安装 npm 插件。
|
|
28
|
+
|
|
29
|
+
## 自然语言快速开始
|
|
30
|
+
|
|
31
|
+
示例提示:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
使用 planpilot。
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## OpenCode Studio 集成体验
|
|
38
|
+
|
|
39
|
+
Planpilot 提供一流的 OpenCode Studio 集成体验:
|
|
40
|
+
|
|
41
|
+
- 项目地址:[opencode-studio](https://github.com/canxin121/opencode-studio)
|
|
42
|
+
|
|
43
|
+
- 在 Studio 侧边栏查看运行态上下文(活动计划、下一步、进度状态)。
|
|
44
|
+
- 使用 Studio 设置面板调整运行态和自动续跑配置。
|
|
45
|
+
- 通过 Studio bridge 读取与写入运行态和配置状态。
|
|
46
|
+
|
|
47
|
+
如果你已经在 OpenCode 中处理多步骤工作,OpenCode Studio 是最快的统一控制台,可用于监控流程、调优行为并保持团队协同。
|
|
48
|
+
|
|
49
|
+
## 详细说明
|
|
50
|
+
|
|
51
|
+
更细的配置结构、bridge action、参数级行为和触发规则,见 `DETAIL.zh-CN.md`。
|
|
52
|
+
|
|
53
|
+
## 许可证
|
|
54
|
+
|
|
55
|
+
MIT
|