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.
Files changed (3) hide show
  1. package/README.md +28 -394
  2. package/README.zh-CN.md +55 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,421 +1,55 @@
1
1
  # opencode-planpilot
2
2
 
3
- Planpilot for OpenCode. Provides plan/step/goal workflow with auto-continue for AI steps and a native `planpilot` tool.
3
+ Chinese version: [README.zh-CN.md](README.zh-CN.md)
4
4
 
5
- ## Features
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
- ## Install
7
+ ## Why Teams Use Planpilot
13
8
 
14
- Add to `opencode.json`:
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
- ```json
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
- Planpilot stores all local state under a single directory (database, plan markdown snapshots, and the default config file).
16
+ Add the plugin to your OpenCode config file `opencode.json`:
54
17
 
55
- - OpenCode config root
56
- - Default: `~/.config/opencode` (XDG config)
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
- Data layout under the Planpilot data directory:
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
- "autoContinue": {
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
- Notes:
27
+ OpenCode installs npm plugins automatically when the session starts.
174
28
 
175
- - `session.idle` and `session.status=idle` are always auto-continue triggers and cannot be disabled.
176
- - Additional triggers are optional and configured in:
29
+ ## Quick Start with Natural Language
177
30
 
178
- - Default: `~/.config/opencode/.planpilot/config.json`
179
- - Override path: `OPENCODE_PLANPILOT_CONFIG=/abs/path/to/config.json`
31
+ Example prompt:
180
32
 
181
- Example:
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
- ### Field reference
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
- Controls retrying a failed auto-continue send (`session.promptAsync`).
39
+ Planpilot ships first-class OpenCode Studio integration:
270
40
 
271
- - `enabled` (boolean): enable/disable retries.
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
- #### Event rules (`autoContinue.on*`)
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
- Event rules let Planpilot attempt an auto-continue send when a specific OpenCode event occurs.
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
- - `enabled` (boolean): enable/disable the rule.
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
- Event summary text is what keyword matching runs against:
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
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-planpilot",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "Planpilot plugin for OpenCode",
5
5
  "type": "module",
6
6
  "opencodeStudio": {