omo-slim-plan 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 +21 -0
- package/README.md +234 -0
- package/bin/install.js +557 -0
- package/package.json +19 -0
- package/plugin/planflow-notify.mjs +158 -0
- package/plugin/planflow-providers.mjs +305 -0
- package/plugin/planflow.js +217 -0
- package/templates/command/plan-review.md +54 -0
- package/templates/command/plan.md +58 -0
- package/templates/command/start-work.md +65 -0
- package/templates/plans/README.md +62 -0
- package/templates/skills/plan-workflow/SKILL.md +126 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 omo-slim-plan maintainers
|
|
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,234 @@
|
|
|
1
|
+
# omo-slim-plan
|
|
2
|
+
|
|
3
|
+
Lightweight **plan-first** workflow for [OpenCode](https://opencode.ai) + [oh-my-opencode-slim](https://github.com/sisyphuslabs/omo): AI writes a decision-complete plan first, a human chooses what happens next, execution updates checkboxes in the plan file, and webhook notifications (Telegram primary, extensible) fire at the gate points. Not full omo/ultrawork — no boulder, no dual-review, no CAS.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
/plan → .plans/<slug>.md (status: ready) → human gate
|
|
7
|
+
│
|
|
8
|
+
├─ start-work <slug> → execute, sync checkboxes
|
|
9
|
+
│ └─ all done → awaiting-acceptance → human accept → status: accepted
|
|
10
|
+
├─ plan-review <slug> → @oracle review → Notes → back to gate
|
|
11
|
+
└─ revise → edit plan, stay ready
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **`/plan`** — explore the repo, write a decision-complete plan to `.plans/<slug>.md`, set `status: ready`, stop for a human choice. Never implements product code.
|
|
17
|
+
- **`/start-work`** — execute an existing plan, update `- [ ]` → `- [x]` after each verified todo, present an acceptance summary when done, wait for human accept/reject.
|
|
18
|
+
- **`/plan-review`** — delegate plan review to the `oracle` agent, write findings into the plan `## Notes`, return to the human gate.
|
|
19
|
+
- **Checkbox progress as source of truth** — the plan file is the only progress ledger; no completion claims without checked boxes.
|
|
20
|
+
- **Telegram + extensible webhooks** — Telegram Bot API by default; generic JSON POST; local command provider; all behind a small provider map you can extend.
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- OpenCode + oh-my-opencode-slim (agents: explorer / fixer / designer / oracle / librarian)
|
|
25
|
+
- Node.js **18+** (installer and plugin use only `node:` builtins — zero npm runtime dependencies)
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx omo-slim-plan
|
|
31
|
+
# or from GitHub
|
|
32
|
+
npx github:Daedalusys/omo-slim-plan
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
From a local checkout:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
node bin/install.js # install
|
|
39
|
+
node bin/install.js --dry-run # preview only
|
|
40
|
+
node bin/install.js --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
What the installer does:
|
|
44
|
+
|
|
45
|
+
| Step | Destination |
|
|
46
|
+
|------|-------------|
|
|
47
|
+
| Commands | `~/.config/opencode/command/{plan,start-work,plan-review}.md` |
|
|
48
|
+
| Skill | `~/.config/skillshare/skills/plan-workflow/SKILL.md` if skillshare exists, else `~/.config/opencode/skills/plan-workflow/` |
|
|
49
|
+
| Plugin | `~/.config/opencode/plugin/{planflow.js,planflow-notify.mjs,planflow-providers.mjs}` |
|
|
50
|
+
| Config | `~/.config/opencode/planflow.json` (created if missing; never clobbered unless `--force`) |
|
|
51
|
+
| Plugin registration | `"planflow"` added to the `plugin` array in `~/.config/opencode/opencode.json` |
|
|
52
|
+
|
|
53
|
+
`OPencode_CONFIG` overrides the config root. `--config <path>` sets it too (directory, or a `planflow.json` path). Existing targets are backed up to `*.bak-<timestamp>` before overwrite. After install: **restart OpenCode**.
|
|
54
|
+
|
|
55
|
+
## Configure Telegram
|
|
56
|
+
|
|
57
|
+
1. Talk to [@BotFather](https://t.me/BotFather) on Telegram → `/newbot` → copy the **bot token**.
|
|
58
|
+
2. Add the bot to your target chat, then get the **chat id** (e.g. via `https://api.telegram.org/bot<TOKEN>/getUpdates`, or send a message and inspect the response).
|
|
59
|
+
3. Fill in `~/.config/opencode/planflow.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"version": 1,
|
|
64
|
+
"plansDir": ".plans",
|
|
65
|
+
"webhook": {
|
|
66
|
+
"provider": "telegram",
|
|
67
|
+
"telegram": {
|
|
68
|
+
"botToken": "123456:ABC-your-token",
|
|
69
|
+
"chatId": "-1001234567890"
|
|
70
|
+
},
|
|
71
|
+
"generic": { "url": "", "headers": {} },
|
|
72
|
+
"command": { "cmd": "" },
|
|
73
|
+
"events": {
|
|
74
|
+
"plan-ready": true,
|
|
75
|
+
"awaiting-review": true,
|
|
76
|
+
"task-done": false,
|
|
77
|
+
"awaiting-acceptance": true
|
|
78
|
+
},
|
|
79
|
+
"titlePrefix": "[omo-slim-plan]"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or pass flags at install time:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
node bin/install.js --telegram-token "123456:ABC..." --telegram-chat-id "-1001234567890"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Event toggles
|
|
91
|
+
|
|
92
|
+
| event | default | when |
|
|
93
|
+
|-------|---------|------|
|
|
94
|
+
| `plan-ready` | on | plan written, `status: ready` |
|
|
95
|
+
| `awaiting-review` | on | `/plan-review` starts (oracle review) |
|
|
96
|
+
| `task-done` | off | each todo completed during `/start-work` |
|
|
97
|
+
| `awaiting-acceptance` | on | all Todos + Final checks done |
|
|
98
|
+
|
|
99
|
+
Set any event to `false` to silence it. **A missing/unconfigured provider never blocks the workflow** — notify failures are logged and work continues.
|
|
100
|
+
|
|
101
|
+
## Custom webhook providers
|
|
102
|
+
|
|
103
|
+
Provider map lives in `plugin/planflow-providers.mjs`:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
export const PROVIDERS = {
|
|
107
|
+
telegram: telegramProvider, // POST api.telegram.org
|
|
108
|
+
generic: genericProvider, // POST JSON to webhook.generic.url
|
|
109
|
+
command: commandProvider, // run local command via spawn
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Generic provider
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
"webhook": {
|
|
117
|
+
"provider": "generic",
|
|
118
|
+
"generic": {
|
|
119
|
+
"url": "https://example.com/hooks/planflow",
|
|
120
|
+
"headers": { "Authorization": "Bearer ..." }
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Payload shape:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"event": "plan-ready",
|
|
130
|
+
"plan": ".plans/foo.md",
|
|
131
|
+
"title": "[omo-slim-plan] Plan ready: foo",
|
|
132
|
+
"message": "Plan .plans/foo.md status: ready",
|
|
133
|
+
"remaining": 3,
|
|
134
|
+
"session": "",
|
|
135
|
+
"source": "omo-slim-plan"
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Command provider
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
"webhook": {
|
|
143
|
+
"provider": "command",
|
|
144
|
+
"command": { "cmd": "curl -s -X POST -d \"$PLANFLOW_MESSAGE\" https://example.com/hook" }
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
- Executes with `spawn` (non-interactive, 10s timeout). **No shell interpolation of untrusted text into the command** — values go through env only:
|
|
149
|
+
- `PLANFLOW_EVENT`, `PLANFLOW_PLAN`, `PLANFLOW_TITLE`, `PLANFLOW_MESSAGE`, `PLANFLOW_REMAINING`
|
|
150
|
+
- Optional placeholders in `cmd`: `{{event}}`, `{{plan}}`, `{{title}}`, `{{message}}`, `{{remaining}}` — substituted only from the same caller-controlled safe strings, shell-escaped.
|
|
151
|
+
|
|
152
|
+
### Adding your own provider
|
|
153
|
+
|
|
154
|
+
1. Write `async function myProvider(cfg, payload) { return { ok: true }; }` in `planflow-providers.mjs`.
|
|
155
|
+
2. Register it: `export const PROVIDERS = { ..., my: myProvider }`.
|
|
156
|
+
3. Set `"webhook": { "provider": "my", "my": { ... } }` in `planflow.json`.
|
|
157
|
+
|
|
158
|
+
Contract: return `{ ok, skipped?, reason?, status?, error? }`; never throw; treat missing config as `{ ok: false, reason: "my_not_configured" }`.
|
|
159
|
+
|
|
160
|
+
## Workflow overview
|
|
161
|
+
|
|
162
|
+
```mermaid
|
|
163
|
+
flowchart TD
|
|
164
|
+
A["User: plan this request"] --> B["/plan — explore repo (read-only)"]
|
|
165
|
+
B --> C["Write .plans/<slug>.md<br/>status: ready"]
|
|
166
|
+
C --> D["notify plan-ready"]
|
|
167
|
+
D --> E{"Human gate"}
|
|
168
|
+
E -->|"start-work <slug>"| F["/start-work — execute todos"]
|
|
169
|
+
E -->|"plan-review <slug>"| G["/plan-review — @oracle → Notes"]
|
|
170
|
+
E -->|"revise"| B
|
|
171
|
+
G --> E
|
|
172
|
+
F --> H["Sync checkboxes after each todo"]
|
|
173
|
+
H --> I{"All todos + F1-F3 done?"}
|
|
174
|
+
I -->|no| F
|
|
175
|
+
I -->|yes| J["status: done · notify awaiting-acceptance"]
|
|
176
|
+
J --> K{"Human accept?"}
|
|
177
|
+
K -->|accept| L["status: accepted ✓"]
|
|
178
|
+
K -->|reject| F
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Plan file contract (excerpt):
|
|
182
|
+
|
|
183
|
+
```markdown
|
|
184
|
+
# my-feature
|
|
185
|
+
- status: ready
|
|
186
|
+
- created: 2026-01-01
|
|
187
|
+
- slug: my-feature
|
|
188
|
+
|
|
189
|
+
## TL;DR
|
|
190
|
+
## Scope
|
|
191
|
+
## Must-NOT
|
|
192
|
+
## Todos
|
|
193
|
+
- [ ] 1. <title>
|
|
194
|
+
- 验收: <agent-executable criteria>
|
|
195
|
+
- 证据: <exact command or path>
|
|
196
|
+
## Final checks
|
|
197
|
+
- [ ] F1. 计划符合度
|
|
198
|
+
- [ ] F2. 质量与测试通过
|
|
199
|
+
- [ ] F3. 与 Scope/Must-NOT 一致
|
|
200
|
+
## Notes
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Status machine: `draft → ready → (approved) → in-progress → done → accepted`.
|
|
204
|
+
|
|
205
|
+
Full contract: the installed **plan-workflow** skill (`~/.config/opencode/skills/plan-workflow/SKILL.md` or skillshare equivalent).
|
|
206
|
+
|
|
207
|
+
## Plans convention (`.plans/`)
|
|
208
|
+
|
|
209
|
+
- One plan per file: `.plans/<slug>.md` (lowercase-hyphen slug).
|
|
210
|
+
- Located in **each project's** project root — the installer never drops plans into random projects.
|
|
211
|
+
- **Default: commit plans** into the project repo (they are small and reviewable). Do **not** commit boulder-style heavy artifacts. Teams that want plans local-only can gitignore `.plans/`.
|
|
212
|
+
- See `templates/plans/README.md` for the copy-able directory README.
|
|
213
|
+
|
|
214
|
+
## Uninstall
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
npx omo-slim-plan --uninstall
|
|
218
|
+
# or from a checkout
|
|
219
|
+
node bin/install.js --uninstall
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Removes installed commands, the skill, plugin files, and `"planflow"` from `opencode.json`'s plugin array. **Keeps `planflow.json`** (your tokens) unless you pass `--force`. Project `.plans/` directories are never touched.
|
|
223
|
+
|
|
224
|
+
## Security
|
|
225
|
+
|
|
226
|
+
- **Never commit `planflow.json`** — it may contain Telegram bot tokens or webhook URLs. The file lives in `~/.config/opencode/`, outside your project repo.
|
|
227
|
+
- Tokens are never logged by the plugin (provider errors are redacted).
|
|
228
|
+
- Command-provider messages are passed via environment variables, not interpolated into the command string.
|
|
229
|
+
- The installer refuses to write outside your OpenCode config root and skillshare root; every overwrite is backed up first.
|
|
230
|
+
- Notifications are best-effort side channels: an unconfigured or failing webhook never blocks plan/execute/acceptance.
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
MIT © 2026 omo-slim-plan maintainers
|