opencode-overclock 0.3.0 → 0.5.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 +252 -111
- package/package.json +6 -4
- package/skills/codebase-design/DEEPENING.md +35 -0
- package/skills/codebase-design/DESIGN-IT-TWICE.md +34 -0
- package/skills/codebase-design/SKILL.md +93 -0
- package/skills/diagnosing-bugs/SKILL.md +123 -0
- package/skills/domain-modeling/ADR-FORMAT.md +55 -0
- package/skills/domain-modeling/CONTEXT-FORMAT.md +32 -0
- package/skills/domain-modeling/SKILL.md +102 -0
- package/skills/doubt/SKILL.md +80 -0
- package/skills/grilling/SKILL.md +96 -0
- package/skills/source-discipline/SKILL.md +78 -0
- package/skills/tdd/SKILL.md +87 -0
- package/skills/to-spec/SKILL.md +69 -0
- package/skills/to-spec/SPEC-TEMPLATE.md +50 -0
- package/skills/to-tickets/SKILL.md +74 -0
- package/skills/to-tickets/TICKET-TEMPLATE.md +41 -0
- package/src/bridge.ts +1 -0
- package/src/buddy/companion.ts +104 -5
- package/src/buddy/sprites.ts +4 -4
- package/src/buddy/tui.ts +175 -65
- package/src/core/bridge.ts +34 -0
- package/src/core/lifecycle.ts +67 -0
- package/src/core/policy.ts +128 -0
- package/src/core/summary.ts +33 -0
- package/src/core/types.ts +193 -0
- package/src/features/buddy.ts +1 -2
- package/src/features/guard.ts +421 -37
- package/src/features/index.ts +18 -4
- package/src/features/recovery.ts +153 -0
- package/src/features/safety.ts +147 -0
- package/src/features/sched.ts +183 -89
- package/src/features/tasks.ts +134 -33
- package/src/features/truncator.ts +116 -0
- package/src/features/usage.ts +46 -65
- package/src/features/workflow.ts +256 -0
- package/src/index.ts +96 -67
- package/src/lib/busy.ts +1 -25
- package/src/lib/exec.ts +13 -0
- package/src/lib/inject.ts +10 -56
- package/src/lib/mirror.ts +13 -0
- package/src/lib/probe.ts +1 -15
- package/src/lib/state.ts +10 -39
- package/src/lib/tmux.ts +1 -0
- package/src/lib/ui.ts +208 -0
- package/src/merge.ts +2 -66
- package/src/platform/probe.ts +25 -0
- package/src/platform/process/exec.ts +317 -0
- package/src/platform/process/tmux.ts +60 -0
- package/src/platform/session/busy.ts +33 -0
- package/src/platform/session/inject.ts +89 -0
- package/src/platform/session/notify.ts +20 -0
- package/src/platform/storage/state.ts +99 -0
- package/src/platform/storage/store.ts +61 -0
- package/src/summary.ts +1 -0
- package/src/tools.ts +8 -244
- package/src/tui.ts +57 -186
- package/src/types.ts +1 -73
- package/src/v2/context.ts +470 -0
- package/src/v2/host.ts +120 -0
- package/src/v2/loader.ts +150 -0
- package/src/workflow/agents/codebase-researcher.ts +27 -0
- package/src/workflow/agents/design-explorer.ts +33 -0
- package/src/workflow/agents/doubt-reviewer.ts +26 -0
- package/src/workflow/agents/engineering-coach.ts +23 -0
- package/src/workflow/agents/performance-auditor.ts +29 -0
- package/src/workflow/agents/security-auditor.ts +23 -0
- package/src/workflow/agents/spec-reviewer.ts +15 -0
- package/src/workflow/agents/standards-reviewer.ts +24 -0
- package/src/workflow/agents/test-engineer.ts +28 -0
- package/src/workflow/catalog.ts +210 -0
- package/src/workflow/templates/build.ts +47 -0
- package/src/workflow/templates/define.ts +45 -0
- package/src/workflow/templates/diagnose.ts +58 -0
- package/src/workflow/templates/plan.ts +52 -0
- package/src/workflow/templates/ship.ts +64 -0
- package/src/buddy/reactions.ts +0 -41
- package/src/buddy/types.ts +0 -30
- package/src/config.ts +0 -19
- package/src/features/checkpoints.ts +0 -128
- package/src/features/sandbox.ts +0 -104
- package/src/validate.ts +0 -197
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# opencode-overclock
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The modular workflow suite and power-ups for [opencode](https://opencode.ai): background
|
|
4
|
+
tasks, cron-style scheduling, quality-gate hooks, cost telemetry — and an ASCII companion.
|
|
5
5
|
|
|
6
6
|
Everything is a separate module you can turn off individually, so you can take one feature and
|
|
7
7
|
ignore the rest. When opencode ships a native equivalent, the matching module goes away.
|
|
@@ -13,18 +13,20 @@ opencode plugin -g opencode-overclock # every project
|
|
|
13
13
|
|
|
14
14
|
## What you get
|
|
15
15
|
|
|
16
|
-
| Module
|
|
17
|
-
|
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
16
|
+
| Module | What it does | Tools it adds |
|
|
17
|
+
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
18
|
+
| `workflow` | 5 lifecycle commands (`/define`, `/plan`, `/build`, `/diagnose`, `/ship`), 9 sandboxed subagents, and 9 bundled engineering skills (`tdd`, `grilling`, `doubt`, etc.). | — |
|
|
19
|
+
| `safety` | Blocks destructive git operations (`git reset --hard`, force-push, `clean -f`, `branch -D`, `stash drop`) in `bash` tool calls before they run. | — |
|
|
20
|
+
| `tasks` | Run shell commands in the background. The agent gets the result posted back into the session when they finish, and a nudge if one blocks on a prompt. | `task_run` `task_status` `task_output` `task_kill` |
|
|
21
|
+
| `sched` | Recurring prompts on a cron expression or an interval (`"5m"`). Survives restarts; an interval on the current session makes a loop. | `schedule_create` `schedule_list` `schedule_delete` |
|
|
22
|
+
| `guard` | Your own quality gates: run a command after the agent edits files, feed failures back on idle, edit recovery hints, and `floorGuard` anti-bypass protection. | — |
|
|
23
|
+
| `recovery` | Automatically heal provider errors (missing tool results, thinking block sequencing, context limit) and auto-resume sessions. | — |
|
|
24
|
+
| `truncator` | Context-protecting smart output truncation for high-volume tools (`task_output`, `bash`, `grep`, `glob`, `webfetch`) preserving header & tail diagnostics. | — |
|
|
25
|
+
| `usage` | Per-day and per-session cost and token totals, collected from the event bus (accessible via TUI `/oc-usage`). | — |
|
|
26
|
+
| `buddy` | An ASCII pet next to the prompt that reacts to what the session is doing. Purely cosmetic. | — |
|
|
25
27
|
|
|
26
28
|
On top of the tools, the TUI side adds desktop notifications when a turn finishes or the agent
|
|
27
|
-
needs you, plus `/oc-tasks`, `/oc-usage`, `/oc-schedules` and `/oc-buddy
|
|
29
|
+
needs you, plus `/oc-tasks`, `/oc-usage`, `/oc-schedules`, `/oc-buddy` (pet), `/oc-buddy-switch` (choose species), and `/oc-buddy-cycle` (next species).
|
|
28
30
|
|
|
29
31
|
**Please read this before installing:** overclock gives the agent the ability to run shell
|
|
30
32
|
commands in the background (`task_run`) and to schedule recurring prompts (`schedule_create`).
|
|
@@ -54,142 +56,283 @@ a plugin's `dispose` hook, without which this plugin's timers and watchers are n
|
|
|
54
56
|
|
|
55
57
|
## Configuration
|
|
56
58
|
|
|
57
|
-
Everything is optional. With no
|
|
58
|
-
|
|
59
|
-
gate. A reasonable `.opencode/overclock.json` to start from:
|
|
59
|
+
Everything is optional. With no options configured, overclock runs with sensible defaults: background
|
|
60
|
+
tasks, cron-style scheduling, quality gates, usage telemetry, and the buddy are active immediately.
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
Configure options directly in your project or global `opencode.json`:
|
|
63
|
+
|
|
64
|
+
```jsonc
|
|
65
|
+
{
|
|
66
|
+
"plugin": [
|
|
67
|
+
[
|
|
68
|
+
"opencode-overclock",
|
|
69
|
+
{
|
|
70
|
+
"tasks": { "killOnExit": true },
|
|
71
|
+
"guard": { "auto": true },
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
],
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
To turn an individual feature off:
|
|
79
|
+
|
|
80
|
+
```jsonc
|
|
81
|
+
{
|
|
82
|
+
"plugin": [
|
|
83
|
+
[
|
|
84
|
+
"opencode-overclock",
|
|
85
|
+
{
|
|
86
|
+
"buddy": false,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
],
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
| Module | Options |
|
|
94
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
95
|
+
| `workflow` | `enabled` bool · `commands` bool · `subagents` bool · `skillsPath` string |
|
|
96
|
+
| `safety` | `blockDestructiveGit` bool · `allowForcePush` bool · `allowStashDrop` bool · `customPatterns` array |
|
|
97
|
+
| `guard` | `hooks` array · `recipes` array (`["tsc", "eslint", "cargo", "ruff", "go"]`) · `auto` bool · `editRecovery` bool · `floorGuard` bool / obj |
|
|
98
|
+
| `tasks` | `killOnExit` bool · `stallDetection` bool · `stallThresholdMs` num · `stallCheckIntervalMs` num · `tmux` bool |
|
|
99
|
+
| `sched` | `skipIfBusy` bool |
|
|
100
|
+
| `recovery` | `maxAttempts` num · `cooldownMs` num · `autoResume` bool |
|
|
101
|
+
| `truncator` | `maxChars` num · `tools` array · `headLines` num · `tailLines` num |
|
|
102
|
+
| `usage`, `buddy` | — |
|
|
103
|
+
|
|
104
|
+
### Engineering harness & workflows (`workflow`)
|
|
105
|
+
|
|
106
|
+
Overclock bundles a structured software engineering harness that elevates opencode from a code generator into an elite engineering partner.
|
|
107
|
+
|
|
108
|
+
#### 1. Lifecycle Commands (The "When")
|
|
109
|
+
|
|
110
|
+
| Command | Purpose |
|
|
111
|
+
| :---------- | :--------------------------------------------------------------------------------------------------------------------------------- |
|
|
112
|
+
| `/define` | Structured inquiry via `grilling` and `domain-modeling`, or direct specification synthesis (`to-spec`) into `SPEC.md`. |
|
|
113
|
+
| `/plan` | Decomposes `SPEC.md` into vertical tracer bullets (`to-tickets`) with dependency DAGs and expand/contract migration branches. |
|
|
114
|
+
| `/build` | Autonomous TDD implementation (`tdd`) with stop-the-line tripwires (halts on 3 consecutive test failures or schema changes). |
|
|
115
|
+
| `/diagnose` | Disciplined 6-phase defect isolation loop with automated reproductions, tagged logging (`[DEBUG-xxxx]`), and regression tests. |
|
|
116
|
+
| `/ship` | Pre-launch gatekeeper running a parallel 4-way subagent audit across uncommitted, staged, and branch diffs with GO/NO-GO verdicts. |
|
|
117
|
+
|
|
118
|
+
#### 2. Bundled Engineering Skills (The "How")
|
|
119
|
+
|
|
120
|
+
Auto-discovered by opencode's `skill` tool when relevant:
|
|
121
|
+
|
|
122
|
+
- `tdd`: Test-driven development loop enforcing public seam tests before implementation and the Prove-It bug pattern.
|
|
123
|
+
- `grilling`: Requirements interrogation on the decision dependency frontier with opinionated defaults (`➡️ **Recommended:**`).
|
|
124
|
+
- `domain-modeling`: Ubiquitous language management (`CONTEXT.md`) and Architecture Decision Records (`ADR-FORMAT.md`).
|
|
125
|
+
- `to-spec`: Fast requirements synthesis into `SPEC.md` without reopening interview loops.
|
|
126
|
+
- `to-tickets`: Context-sized DAG task planning with expand-and-contract branches for wide refactors.
|
|
127
|
+
- `codebase-design`: Deep module architecture (Ousterhout), 4 dependency categories, and "Design It Twice" exploration.
|
|
128
|
+
- `diagnosing-bugs`: Systematic defect reproduction, ranked hypotheses, secret redaction, and tagged probes.
|
|
129
|
+
- `doubt`: Adversarial verification where artifacts are audited against contracts without author confirmation bias.
|
|
130
|
+
- `source-discipline`: Grounding framework code in official, version-matched documentation.
|
|
131
|
+
|
|
132
|
+
#### 3. Sandboxed Worker Subagents (The "Who")
|
|
133
|
+
|
|
134
|
+
Specialized leaf subagents invoked via the `task` tool with **enforced read-only tool sandboxing** (`tools: { write: false, edit: false }`, `permission: { edit: "deny" }`):
|
|
135
|
+
|
|
136
|
+
- `codebase-researcher`: Scout tracing call graphs, seams, and dependencies without cluttering orchestrator context.
|
|
137
|
+
- `design-explorer`: Architect formulating contrasting minimalist vs extensible interface proposals ("Design It Twice").
|
|
138
|
+
- `doubt-reviewer`: Adversarial verifier probing race conditions, error bounds, and silent assumptions.
|
|
139
|
+
- `standards-reviewer`: Senior reviewer auditing code diffs against Martin Fowler's code smells and repo idioms.
|
|
140
|
+
- `spec-reviewer`: Product reviewer ensuring strict compliance with `SPEC.md` and zero unrequested scope creep.
|
|
141
|
+
- `security-auditor`: Adversarial security engineer auditing diffs for OWASP Top 10 flaws and secret hygiene.
|
|
142
|
+
- `test-engineer`: QA engineer assessing test coverage gaps, assertion quality, and mocking boundaries.
|
|
143
|
+
- `performance-auditor`: Performance engineer identifying N+1 queries, unbounded memory, and latency bottlenecks.
|
|
144
|
+
- `engineering-coach`: Elite staff mentor providing Socratic debugging guidance and architectural critique.
|
|
145
|
+
|
|
146
|
+
### Quality gates (`guard`)
|
|
147
|
+
|
|
148
|
+
Quality gates let you define automated feedback loops. Whenever the agent modifies code with `edit`
|
|
149
|
+
or `write`, the guard runs your project's verification command in the background. If the command fails,
|
|
150
|
+
the error output is automatically fed back into the session once the agent finishes its turn, prompting
|
|
151
|
+
it to self-correct.
|
|
152
|
+
|
|
153
|
+
Because verification commands vary by language and repository, configure hooks in your project's
|
|
154
|
+
local `opencode.json`:
|
|
155
|
+
|
|
156
|
+
#### Stack recipes
|
|
157
|
+
|
|
158
|
+
##### TypeScript / JavaScript
|
|
159
|
+
|
|
160
|
+
```jsonc
|
|
62
161
|
{
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
"tasks": { "killOnExit": true }
|
|
75
|
-
}
|
|
162
|
+
"guard": {
|
|
163
|
+
"hooks": [
|
|
164
|
+
{
|
|
165
|
+
"name": "typecheck",
|
|
166
|
+
"tools": ["edit", "write"],
|
|
167
|
+
"pathFilter": "src/**/*.ts",
|
|
168
|
+
"run": "npm run typecheck",
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
76
172
|
}
|
|
77
173
|
```
|
|
78
174
|
|
|
79
|
-
|
|
80
|
-
idle), background tasks that don't outlive the session, plus scheduling, telemetry, checkpoints
|
|
81
|
-
and the buddy on their defaults. Swap `run` for whatever your project uses.
|
|
175
|
+
##### Python (Ruff / Pytest)
|
|
82
176
|
|
|
83
|
-
|
|
84
|
-
|
|
177
|
+
```jsonc
|
|
178
|
+
{
|
|
179
|
+
"guard": {
|
|
180
|
+
"hooks": [
|
|
181
|
+
{
|
|
182
|
+
"name": "lint",
|
|
183
|
+
"tools": ["edit", "write"],
|
|
184
|
+
"pathFilter": "**/*.py",
|
|
185
|
+
"run": "ruff check .",
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
```
|
|
85
191
|
|
|
86
|
-
|
|
87
|
-
|
|
192
|
+
##### Rust (Cargo)
|
|
193
|
+
|
|
194
|
+
```jsonc
|
|
195
|
+
{
|
|
196
|
+
"guard": {
|
|
197
|
+
"hooks": [
|
|
198
|
+
{
|
|
199
|
+
"name": "cargo-check",
|
|
200
|
+
"tools": ["edit", "write"],
|
|
201
|
+
"pathFilter": "**/*.rs",
|
|
202
|
+
"run": "cargo check",
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
}
|
|
88
207
|
```
|
|
89
208
|
|
|
90
|
-
|
|
91
|
-
| ------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
92
|
-
| `tasks` | `killOnExit` bool · `stallDetection` bool · `stallThresholdMs` num · `stallCheckIntervalMs` num |
|
|
93
|
-
| `sched` | `skipIfBusy` bool |
|
|
94
|
-
| `sandbox` | `net` bool |
|
|
95
|
-
| `guard` | `hooks` array |
|
|
96
|
-
| `usage`, `checkpoints`, `buddy` | — |
|
|
209
|
+
##### Go
|
|
97
210
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
211
|
+
```jsonc
|
|
212
|
+
{
|
|
213
|
+
"guard": {
|
|
214
|
+
"hooks": [
|
|
215
|
+
{
|
|
216
|
+
"name": "go-test",
|
|
217
|
+
"tools": ["edit", "write"],
|
|
218
|
+
"pathFilter": "**/*.go",
|
|
219
|
+
"run": "go test ./...",
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
}
|
|
224
|
+
```
|
|
101
225
|
|
|
102
|
-
|
|
226
|
+
##### Generic / Make
|
|
103
227
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
228
|
+
```jsonc
|
|
229
|
+
{
|
|
230
|
+
"guard": {
|
|
231
|
+
"hooks": [
|
|
232
|
+
{
|
|
233
|
+
"name": "check",
|
|
234
|
+
"tools": ["edit", "write"],
|
|
235
|
+
"run": "make check",
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### Hook options
|
|
109
243
|
|
|
110
|
-
|
|
244
|
+
| Field | Default | Description |
|
|
245
|
+
| ------------ | ----------- | ----------------------------------------------------------------------------- |
|
|
246
|
+
| `name` | _required_ | Identifier displayed in failure reports |
|
|
247
|
+
| `tools` | _required_ | Tools to trigger on, e.g. `["edit", "write"]` |
|
|
248
|
+
| `run` | _required_ | Shell command to execute (receives `$GUARD_TOOL` and `$GUARD_FILE` in env) |
|
|
249
|
+
| `pathFilter` | `undefined` | Optional glob pattern to limit triggers to relevant files (e.g. `**/*.py`) |
|
|
250
|
+
| `mode` | `"inject"` | `"inject"` waits for the session to go idle; `"append"` reports immediately |
|
|
251
|
+
| `debounceMs` | `2000` | Debounce duration for rapid successive edits |
|
|
252
|
+
| `timeoutMs` | `60000` | Execution timeout before killing the command |
|
|
253
|
+
| `maxDeferMs` | `300000` | Maximum time `"inject"` will wait for an idle session before reporting anyway |
|
|
254
|
+
| `onSuccess` | `"silent"` | `"silent"` or `"notify"` |
|
|
255
|
+
|
|
256
|
+
### Restricting and remapping tool names
|
|
111
257
|
|
|
112
258
|
If your setup only accepts certain tool names, list them in `toolAllowlist`. Any tool whose
|
|
113
|
-
name isn't permitted is withheld from the model rather than offered and refused
|
|
114
|
-
|
|
259
|
+
name isn't permitted is withheld from the model rather than offered and refused:
|
|
260
|
+
|
|
261
|
+
```jsonc
|
|
262
|
+
{
|
|
263
|
+
"plugin": [
|
|
264
|
+
[
|
|
265
|
+
"opencode-overclock",
|
|
266
|
+
{
|
|
267
|
+
"toolAllowlist": ["task_run", "task_status", "schedule_create"],
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
],
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
`toolNames` maps this plugin's tools onto custom names you want the model to see:
|
|
115
275
|
|
|
116
|
-
```
|
|
276
|
+
```jsonc
|
|
117
277
|
{
|
|
118
|
-
"
|
|
119
|
-
|
|
278
|
+
"plugin": [
|
|
279
|
+
[
|
|
280
|
+
"opencode-overclock",
|
|
281
|
+
{
|
|
282
|
+
"toolNames": { "task_run": "run_background_task" },
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
],
|
|
120
286
|
}
|
|
121
287
|
```
|
|
122
288
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
built-in (`bash`, `task`, …) or differs from one only by capitalisation — the first replaces
|
|
129
|
-
that built-in, the second reads as a duplicate to anything matching case-insensitively.
|
|
130
|
-
Descriptions mentioning a renamed tool are rewritten too, so the agent never gets instructions
|
|
131
|
-
naming a tool it wasn't given. Permission ids keep their declared names, so existing permission
|
|
132
|
-
config still applies.
|
|
133
|
-
|
|
134
|
-
#### Named lists
|
|
135
|
-
|
|
136
|
-
`toolAllowlist` entries can also name a bundled list, which expands to every name it permits.
|
|
137
|
-
Mix and match freely — `["claude-code", "MyExtraTool"]` is a bundled list plus one of your own.
|
|
138
|
-
|
|
139
|
-
`claude-code` is the tool set Claude Code registers. opencode's ids are snake_case and Claude
|
|
140
|
-
Code's are PascalCase, so the two vocabularies don't overlap and these names are free to use.
|
|
141
|
-
A bundled list also supplies default names for tools where it contains the same operation:
|
|
142
|
-
|
|
143
|
-
| Module | Declared | Sent as |
|
|
144
|
-
| ------- | ----------------- | ------------ |
|
|
145
|
-
| `tasks` | `task_run` | `TaskCreate` |
|
|
146
|
-
| `tasks` | `task_status` | `TaskList` |
|
|
147
|
-
| `tasks` | `task_output` | `TaskOutput` |
|
|
148
|
-
| `tasks` | `task_kill` | `TaskStop` |
|
|
149
|
-
| `sched` | `schedule_create` | `CronCreate` |
|
|
150
|
-
| `sched` | `schedule_list` | `CronList` |
|
|
151
|
-
| `sched` | `schedule_delete` | `CronDelete` |
|
|
152
|
-
|
|
153
|
-
That's the whole table, and it stops there on purpose. Nothing in the `claude-code` set means
|
|
154
|
-
"revert a session checkpoint" or "report token spend", so `checkpoints`, `usage` and
|
|
155
|
-
`bash_unsandboxed` get no default name: handing them an unrelated one would tell the model the
|
|
156
|
-
wrong thing about what they do. They're withheld until you choose a name yourself, and startup
|
|
157
|
-
says which names are free:
|
|
158
|
-
|
|
159
|
-
```json
|
|
289
|
+
### Running OpenCode V2 plugins on OpenCode V1
|
|
290
|
+
|
|
291
|
+
OpenCode V1 distributions cannot natively load V2 plugins (which export `{ id, setup }` or `{ id, effect }` instead of a server function). Overclock provides an embedded V2 host engine that runs V2 plugins side-by-side with V1 tools:
|
|
292
|
+
|
|
293
|
+
```jsonc
|
|
160
294
|
{
|
|
161
|
-
"
|
|
162
|
-
|
|
295
|
+
"plugin": [
|
|
296
|
+
[
|
|
297
|
+
"opencode-overclock",
|
|
298
|
+
{
|
|
299
|
+
"plugins": ["./plugins/custom-agent.ts", ["opencode-plugin-review", { "strict": true }]],
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
],
|
|
163
303
|
}
|
|
164
304
|
```
|
|
165
305
|
|
|
166
|
-
`
|
|
167
|
-
|
|
306
|
+
Overclock synthesizes a spec-compliant `PluginContext`, adapting V2 domain transforms (`agent`, `command`, `catalog`, `reference`, `skill`, `aisdk`) to live V1 config and chat hooks while keeping all V1 power tools active.
|
|
307
|
+
|
|
308
|
+
Startup tells you what was renamed, what was withheld, and warns on collisions with opencode
|
|
309
|
+
built-in tools. Descriptions mentioning a renamed tool are rewritten automatically.
|
|
168
310
|
|
|
169
311
|
## Notes on the TUI surface
|
|
170
312
|
|
|
171
313
|
The TUI plugin sends a desktop notification (with sound) when a turn completes or the agent
|
|
172
314
|
needs permission, asks a question, or errors — each individually switchable through plugin
|
|
173
|
-
options
|
|
315
|
+
options (`notifyIdle`, `notifyPermission`, `notifyQuestion`, `notifyError`, `buddy` in `tui.json`).
|
|
316
|
+
Its slash commands read the state files under `.opencode/overclock/`, so they work
|
|
174
317
|
without going through the model.
|
|
175
318
|
|
|
176
319
|
The buddy hatches once per install with a random species, rarity and name, persists in the
|
|
177
320
|
TUI's key-value store, hides itself below 100 columns, and needs `@opentui/solid` resolvable at
|
|
178
321
|
runtime. If it isn't, the buddy quietly sits out and the rest of the TUI plugin still loads.
|
|
322
|
+
Switch buddy on demand via `/oc-buddy-switch` (opens an interactive species picker or rolls a fresh companion)
|
|
323
|
+
or `/oc-buddy-cycle` (advances directly to the next species in rotation).
|
|
179
324
|
|
|
180
325
|
## Contributing
|
|
181
326
|
|
|
182
327
|
```
|
|
183
328
|
src/
|
|
184
|
-
index.ts entry:
|
|
329
|
+
index.ts entry: init enabled modules, merge hooks, hybrid V1/V2 export
|
|
185
330
|
tui.ts TUI plugin (notifications + slash commands), separate export
|
|
186
|
-
types
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
lib/ state dir + json, session inject + toast
|
|
192
|
-
features/ one file per module + registry
|
|
331
|
+
core/ types, lifecycle/hook merging, tool policy, capability summary, bridge
|
|
332
|
+
platform/ host adapters: process (exec/tmux), session (busy/inject/notify), storage (state/store), probe
|
|
333
|
+
buddy/ ASCII companion state, sprites, and TUI slot integration
|
|
334
|
+
v2/ embedded V2 plugin host, synthetic context, and dynamic loader
|
|
335
|
+
features/ feature modules (tasks, sched, guard, recovery, truncator, usage, buddy)
|
|
193
336
|
test/ bun test
|
|
194
337
|
```
|
|
195
338
|
|
|
@@ -197,8 +340,6 @@ Adding a feature:
|
|
|
197
340
|
|
|
198
341
|
1. Write `src/features/<name>.ts` exporting a `FeatureModule`.
|
|
199
342
|
2. Register it in `src/features/index.ts`.
|
|
200
|
-
3. If it adds tools, add each one to the `claude-code` table in `src/tools.ts`. A test fails
|
|
201
|
-
otherwise, since an unmapped tool is invisible behind a whitelisting gateway.
|
|
202
343
|
|
|
203
344
|
Background reading:
|
|
204
345
|
[docs/opencode-plugin-surface.md](docs/opencode-plugin-surface.md) maps opencode's
|
|
@@ -243,7 +384,7 @@ somewhere else.
|
|
|
243
384
|
### Headless end-to-end
|
|
244
385
|
|
|
245
386
|
```sh
|
|
246
|
-
timeout 90 opencode run -m
|
|
387
|
+
timeout 90 opencode run -m <provider>/<model> "Use task_run to run 'echo hi' ..." < /dev/null
|
|
247
388
|
```
|
|
248
389
|
|
|
249
390
|
- `< /dev/null` is required; an open stdin hangs.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-overclock",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Power-ups for opencode: background tasks, scheduling,
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Power-ups for opencode: background tasks, cron scheduling, quality-gate hooks, usage telemetry, and companion. Modular, toggleable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"./tui": "./src/tui.ts"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
-
"src"
|
|
19
|
+
"src",
|
|
20
|
+
"skills"
|
|
20
21
|
],
|
|
21
22
|
"keywords": [
|
|
22
23
|
"opencode",
|
|
@@ -39,7 +40,8 @@
|
|
|
39
40
|
},
|
|
40
41
|
"dependencies": {
|
|
41
42
|
"@opencode-ai/plugin": "1.18.9",
|
|
42
|
-
"croner": "^10.0.1"
|
|
43
|
+
"croner": "^10.0.1",
|
|
44
|
+
"yaml": "^2.7.0"
|
|
43
45
|
},
|
|
44
46
|
"peerDependencies": {
|
|
45
47
|
"@opentui/solid": ">=0.4.5"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Deepening: Dependency Categories and Seam Discipline
|
|
2
|
+
|
|
3
|
+
How to deepen a cluster of shallow modules into high-leverage architectural components.
|
|
4
|
+
|
|
5
|
+
## Dependency Categories
|
|
6
|
+
|
|
7
|
+
When assessing a module or candidate for deepening, classify its dependencies. The category dictates how the module is structured and tested across its seams:
|
|
8
|
+
|
|
9
|
+
### 1. In-Process (Pure Computation)
|
|
10
|
+
|
|
11
|
+
- **Characteristics:** In-memory state, algorithms, data transformations, zero network/disk I/O.
|
|
12
|
+
- **Deepening Strategy:** Merge shallow helpers and test directly through the deep module interface. No adapters, mocks, or ports needed.
|
|
13
|
+
|
|
14
|
+
### 2. Local-Substitutable
|
|
15
|
+
|
|
16
|
+
- **Characteristics:** Infrastructure dependencies with reliable in-memory or embedded substitutes (e.g. SQLite in `:memory:`, PGLite, in-memory filesystem, mock clock).
|
|
17
|
+
- **Deepening Strategy:** Deepen the module and run tests directly against the local substitute. The seam remains internal to the module; callers never configure or pass database handles.
|
|
18
|
+
|
|
19
|
+
### 3. Remote but Owned (Ports & Adapters)
|
|
20
|
+
|
|
21
|
+
- **Characteristics:** Internal microservices, background job queues, or intra-company APIs deployed across network boundaries.
|
|
22
|
+
- **Deepening Strategy:** Define a clean **port** (interface) at the seam. The deep module owns domain orchestration; the transport is injected via an **adapter**. Tests supply a fast in-memory adapter; production supplies an HTTP/gRPC/queue adapter.
|
|
23
|
+
|
|
24
|
+
### 4. True External (Third-Party Services)
|
|
25
|
+
|
|
26
|
+
- **Characteristics:** External vendors (Stripe, Twilio, SendGrid, AWS S3) outside your control.
|
|
27
|
+
- **Deepening Strategy:** The module defines a narrow domain port. Test suites supply a mock/stub adapter verifying request shapes; production supplies the vendor client adapter.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Seam Discipline
|
|
32
|
+
|
|
33
|
+
- **The Two-Adapter Rule:** One adapter means a hypothetical seam; two adapters means a real one. Do NOT introduce an interface or port unless at least two implementations are justified (typically production + in-memory test). A single-implementation interface is unnecessary indirection.
|
|
34
|
+
- **Internal vs External Seams:** A deep module may have internal seams (private helpers, internal storage engines) for its own tests. Do not leak internal seams to external callers.
|
|
35
|
+
- **The Interface is the Test Surface:** Write unit tests against the deep module interface, not against internal private functions. Tests survive internal refactoring when they test behavior, not implementation mechanics.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Design It Twice
|
|
2
|
+
|
|
3
|
+
When architecting a critical module, interface, or subsystem boundary, your first idea is almost never your best idea. First ideas are typically shallow adaptations of existing local constraints.
|
|
4
|
+
|
|
5
|
+
## The Exploration Protocol
|
|
6
|
+
|
|
7
|
+
### 1. Frame the Problem Space
|
|
8
|
+
|
|
9
|
+
Before generating interfaces, explicitly articulate:
|
|
10
|
+
|
|
11
|
+
- The caller goals and constraints the interface must satisfy.
|
|
12
|
+
- The dependency category (In-Process, Local-Substitutable, Remote-Owned, or True External) per [DEEPENING.md](DEEPENING.md).
|
|
13
|
+
- A concrete usage scenario with realistic inputs and outputs.
|
|
14
|
+
|
|
15
|
+
### 2. Formulate Radically Differently Constrained Interfaces
|
|
16
|
+
|
|
17
|
+
Generate at least 2 (preferably 3) contrasting architectural designs:
|
|
18
|
+
|
|
19
|
+
- **Option A (Minimalist / High-Leverage):** Absolute minimum public surface (1-3 intuitive functions). Maximum internal power hidden behind simple calls. Optimizes for caller ergonomics.
|
|
20
|
+
- **Option B (Extensible / Composable):** Explicit ports and adapters, pluggable pipeline or middleware, highly configurable. Optimizes for future variance and third-party extensions.
|
|
21
|
+
- **Option C (Default-Optimized):** The common 90% use case requires zero configuration, while advanced capabilities are exposed through optional progressive disclosure.
|
|
22
|
+
|
|
23
|
+
### 3. Compare Across Concrete Criteria
|
|
24
|
+
|
|
25
|
+
Evaluate the designs against:
|
|
26
|
+
|
|
27
|
+
1. **Depth (Leverage):** Ratio of internal power provided to interface complexity imposed on callers.
|
|
28
|
+
2. **Call-Site Simplicity:** How clean and readable is the calling code?
|
|
29
|
+
3. **Information Hiding:** Does the interface leak internal details, vendor types, or database identifiers?
|
|
30
|
+
4. **Blast Radius of Change:** If the internal implementation changes tomorrow, do callers need to change?
|
|
31
|
+
|
|
32
|
+
### 4. Provide an Opinionated Recommendation
|
|
33
|
+
|
|
34
|
+
Do not present a bland menu of options without guidance. Recommend the best approach (or a synthesized hybrid), clearly stating the trade-offs and rationale.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-design
|
|
3
|
+
description: Principles for deep module architecture and high-leverage interface design. Use when creating new services or modules, untangling tightly coupled subsystems, designing APIs, or refactoring architecture.
|
|
4
|
+
pack: core
|
|
5
|
+
license: MIT
|
|
6
|
+
attribution: Adapted from mattpocock/skills (MIT License)
|
|
7
|
+
references:
|
|
8
|
+
- DEEPENING.md
|
|
9
|
+
- DESIGN-IT-TWICE.md
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Codebase Design: Deep Modules & High-Leverage Architecture
|
|
13
|
+
|
|
14
|
+
Rooted in John Ousterhout's _A Philosophy of Software Design_ and domain-driven architectural patterns, this skill guides the creation of deep, high-leverage modules that make codebases simpler to understand, maintain, and evolve.
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- Designing a new service, package, module, or domain boundary.
|
|
19
|
+
- Decomposing a tangled god-object or sprawling utility library into cohesive components.
|
|
20
|
+
- Designing API contracts or SDK entry points for internal or external callers.
|
|
21
|
+
- Assessing architectural coupling and seam placement.
|
|
22
|
+
|
|
23
|
+
## When NOT to Use
|
|
24
|
+
|
|
25
|
+
- Routine bug fixes or isolated one-line edits.
|
|
26
|
+
- Editing declarative configuration files.
|
|
27
|
+
- Mechanical script maintenance.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Core Architectural Principles
|
|
32
|
+
|
|
33
|
+
### 1. Deep Modules (Depth Over Shallowness)
|
|
34
|
+
|
|
35
|
+
- **Shallow Module (Anti-pattern):** A module whose public interface is complicated relative to the small amount of capability it provides. (e.g. A 40-line wrapper around `fetch` that requires callers to pass 6 configuration objects).
|
|
36
|
+
- **Deep Module (Ideal):** A module that provides a simple, intuitive interface while concealing substantial complexity and power behind it. (e.g. Unix file I/O: `open`, `read`, `write`, `close` concealing disk block caching, buffer pools, and kernel drivers).
|
|
37
|
+
- **Measure of Architectural Leverage:**
|
|
38
|
+
$$\text{Leverage} = \frac{\text{Internal Functionality Provided}}{\text{Interface Complexity Imposed on Callers}}$$
|
|
39
|
+
|
|
40
|
+
### 2. Information Hiding vs Information Leakage
|
|
41
|
+
|
|
42
|
+
- **Information Hiding:** Knowledge of private algorithms, data representations, and third-party dependencies is strictly contained within the module.
|
|
43
|
+
- **Information Leakage:** Occurs when an internal change to a module forces ripple edits across caller code (e.g. exposing internal database IDs, ORM models, or vendor SDK types directly to consumers).
|
|
44
|
+
- **Hyrum's Law:** _"With a sufficient number of users of an API, all observable behaviors of your system will be depended on by somebody."_ Keep public surfaces strictly bounded.
|
|
45
|
+
|
|
46
|
+
### 3. The Full Caller Contract
|
|
47
|
+
|
|
48
|
+
An interface is not just a function signature or type signature. The full contract comprises:
|
|
49
|
+
|
|
50
|
+
- **Ordering:** Must `init()` be called before `run()`?
|
|
51
|
+
- **Error Modes:** How are failures surfaced (exceptions, result tuples, status codes)?
|
|
52
|
+
- **Invariants:** What assumptions must callers hold true?
|
|
53
|
+
- **Configuration & Defaults:** Are sane defaults supplied so simple callers do not configure knobs?
|
|
54
|
+
- **Performance & Resource Cleanup:** Must callers explicitly close or release handles?
|
|
55
|
+
|
|
56
|
+
### 4. Dependency Classification & Seams
|
|
57
|
+
|
|
58
|
+
Classify dependencies before introducing interfaces:
|
|
59
|
+
|
|
60
|
+
- See [DEEPENING.md](DEEPENING.md) for the 4 categories: In-Process, Local-Substitutable, Remote-Owned (Ports & Adapters), and True External.
|
|
61
|
+
- Observe the **Two-Adapter Rule**: Never create an interface or port unless at least two real adapters exist (typically production + in-memory test).
|
|
62
|
+
|
|
63
|
+
### 5. Design It Twice
|
|
64
|
+
|
|
65
|
+
When designing a critical subsystem or boundary:
|
|
66
|
+
|
|
67
|
+
- Never settle on the first design that comes to mind.
|
|
68
|
+
- Explore at least 2 contrasting architectural designs (e.g. Minimalist vs Extensible).
|
|
69
|
+
- See [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md) for the structured comparison protocol.
|
|
70
|
+
|
|
71
|
+
### 6. Chesterton's Fence in Refactoring
|
|
72
|
+
|
|
73
|
+
Before modifying or deleting code that appears redundant, verbose, or unusual, you MUST discover and explain why it was originally written. If you cannot explain why it exists, you are not qualified to change it.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Common Rationalizations
|
|
78
|
+
|
|
79
|
+
| Rationalization | Reality |
|
|
80
|
+
| :-------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- |
|
|
81
|
+
| _"More small files and 5-line classes are always cleaner."_ | Fragmenting logic creates shallow modules and cognitive indirection. Colocate cohesive logic into deep modules. |
|
|
82
|
+
| _"Expose all knobs so callers have maximum flexibility."_ | Forcing callers to configure dozens of low-level options leaks complexity. Provide high-leverage defaults. |
|
|
83
|
+
| _"I will create an interface just in case we need another implementation later."_ | Speculative interfaces add indirection without value. Introduce ports when you have two concrete adapters. |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Verification
|
|
88
|
+
|
|
89
|
+
Architectural design is complete when:
|
|
90
|
+
|
|
91
|
+
1. Callers can achieve primary use cases using 1-2 intuitive entry points.
|
|
92
|
+
2. Internal changes to storage, third-party libraries, or algorithms cause zero ripple effects on callers.
|
|
93
|
+
3. Automated tests exercise the public interface rather than private internal implementation details.
|