forgedock 1.6.0 → 1.7.1

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/docs/OPENCODE.md CHANGED
@@ -1,312 +1,280 @@
1
1
  # OpenCode Support
2
2
 
3
- ForgeDock has an OpenCode adapter that lets OpenCode run the ForgeDock pipeline
4
- using its native bash tool and the `gh` CLI.
5
-
6
- ## Architecture
7
-
8
- Shared source:
9
- - `commands/**/*.md` remains the workflow spec for all runtimes
10
-
11
- Claude Code wrapper:
12
- - `install.sh` (or `npx forgedock`) symlinks command files into `~/.claude/commands/`
13
-
14
- Codex wrapper:
15
- - `install-codex.sh` generates namespaced skills in `~/.codex/skills/`
16
-
17
- Aider wrapper:
18
- - `install-aider.sh` writes `~/.aider-forge.md` loaded via `--read`
19
-
20
- **OpenCode wrapper** (this document):
21
- - `install-opencode.sh` writes `~/.opencode-forge.md` — a conventions file
22
- OpenCode loads via the `instructions` field in `opencode.json`
23
- - `install-opencode.sh` also patches `~/.config/opencode/opencode.json` to
24
- register ForgeDock pipeline commands as native OpenCode slash commands
25
- (`/work-on`, `/review-pr`, `/quality-gate`, `/orchestrate`)
26
-
27
- This is a conventions-file + command-registration architecture. The shared
28
- `commands/` directory remains the single source of truth — the adapter
29
- registers entry points that read from it.
30
-
31
- ## Feasibility
32
-
33
- OpenCode is the **highest-fidelity** non-Claude Code adapter because:
34
-
35
- | Capability | Requirement | OpenCode support |
36
- |-----------|-------------|-----------------|
37
- | Load instruction files | `instructions` field in `opencode.json` | Native |
38
- | Execute shell commands | `gh`, `git`, standard tools | Native `Bash` tool |
39
- | Read/write files | File editing | Native `Read`/`Write`/`Edit` tools |
40
- | GitHub API | `gh` CLI | Via `Bash("gh ...")` |
41
- | Multi-step workflows | Follow sequential instructions | Supported |
42
- | Compaction resilience | Re-read GitHub state at phase start | Supported (via `Bash("gh ...")`) |
43
- | Native slash commands | `/work-on 967` in TUI | Via `command` config |
44
- | Tool name parity | Same tool names as Claude Code | Direct — no translation needed |
45
-
46
- **Key advantage over Aider and Cursor**: OpenCode shares Claude Code's tool
47
- names (`Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`) — no
48
- translation table required for most operations. Pipeline command specs run
49
- nearly unmodified.
3
+ ForgeDock's OpenCode integration uses native OpenCode commands, subagents, and
4
+ plugins while keeping `commands/**/*.md` as the only workflow source of truth.
5
+ The older global-instructions and `opencode.json` patching adapter has been
6
+ retired because it loaded ForgeDock prose into unrelated sessions, registered
7
+ only four commands, used the wrong argument placeholder, and assumed OpenCode
8
+ had neither skills nor subagents.
50
9
 
51
10
  ## Install
52
11
 
53
- ### Option A — standalone bash installer
54
-
55
12
  ```bash
56
- cd /path/to/forgedock
57
- ./install-opencode.sh
13
+ npx forgedock opencode install
58
14
  ```
59
15
 
60
- This writes `~/.opencode-forge.md` with ForgeDock conventions and patches
61
- `~/.config/opencode/opencode.json` with:
62
- - `instructions`: adds `~/.opencode-forge.md` to OpenCode's system prompt
63
- - `command`: registers `/work-on`, `/review-pr`, `/quality-gate`, `/orchestrate`
64
-
65
- ### Option B — via npx forgedock
66
-
67
- When `opencode` is detected on your PATH, `npx forgedock` writes
68
- `~/.opencode-forge.md` and patches `opencode.json` as an additional install
69
- step. No existing Claude Code files are affected.
16
+ For the optional command tier:
70
17
 
71
18
  ```bash
72
- npx forgedock
73
- ```
74
-
75
- ## Usage
76
-
77
- ### Native slash commands (recommended)
78
-
79
- After running `install-opencode.sh`, use ForgeDock commands in the OpenCode
80
- TUI:
81
-
82
- ```
83
- /work-on 967
84
- /review-pr 123
85
- /quality-gate
19
+ npx forgedock opencode install --extras
86
20
  ```
87
21
 
88
- Or headlessly via `opencode run`:
22
+ Restart OpenCode after install or update. OpenCode loads commands, skills, and
23
+ plugins at startup.
89
24
 
90
- ```bash
91
- opencode run --command work-on "967"
92
- opencode run --command review-pr "123"
93
- ```
25
+ The native adapter does not add or modify user-owned OpenCode settings. It
26
+ writes only ForgeDock-owned files under OpenCode's config directory and records
27
+ them in `forgedock/manifest.json` for safe updates and removal.
94
28
 
95
- ### Manual pipeline loading
29
+ ## Usage
96
30
 
97
- Read a pipeline command spec directly and follow it:
31
+ Commands are namespaced to avoid collisions:
98
32
 
33
+ ```text
34
+ /forge/work-on 967
35
+ /forge/review-pr 123
36
+ /forge/quality-gate
37
+ /forge/orchestrate milestone checkout-v2
99
38
  ```
100
- Read the file /path/to/forgedock/commands/work-on.md and run the pipeline for issue 967.
101
- ```
102
-
103
- OpenCode will load the spec and execute each phase using its native tools.
104
-
105
- ### Phase routing with forge-run.sh
106
39
 
107
- `forge-run.sh` emits JSON phase state for the current issue without invoking
108
- an LLM. Use it to determine the current pipeline phase:
40
+ Headless OpenCode invocation uses the same command names:
109
41
 
110
42
  ```bash
111
- Bash("/path/to/forgedock/scripts/forge-run.sh work-on 967 -R OWNER/REPO")
43
+ opencode run --command forge/work-on "967"
112
44
  ```
113
45
 
114
- Output (NDJSON):
115
- ```json
116
- {"event":"phase_detected","command":"work-on","issue":967,"phase":"no-comments","ts":"..."}
117
- {"event":"phase_detail","phase":"no-comments","lane":"feature","branch":"milestone/dev-exp","labels":[]}
118
- {"event":"action_required","phase":"no-comments","action":"No pipeline activity detected. Invoke /work-on 967 to start investigation.","ts":"..."}
119
- ```
120
-
121
- ## Tool Translation
122
-
123
- OpenCode and Claude Code share the same tool names. Most pipeline operations
124
- run without modification:
125
-
126
- | Claude Code | OpenCode | Notes |
127
- |-------------|----------|-------|
128
- | `Bash("git status")` | `Bash("git status")` | Direct |
129
- | `Read("path/to/file")` | `Read("path/to/file")` | Direct |
130
- | `Write("path", content)` | `Write("path", content)` | Direct |
131
- | `Edit("path", ...)` | `Edit("path", ...)` | Direct |
132
- | `Glob("**/*.md")` | `Glob("**/*.md")` | Direct |
133
- | `Grep(pattern, path)` | `Grep(pattern, path)` | Direct |
134
- | `WebFetch(url)` | `WebFetch(url)` | Direct |
135
- | `Skill("work-on", args="123")` | Read `commands/work-on.md` | No skill loader — read spec directly |
136
- | `Skill("review-pr", args="456")` | Read `commands/review-pr.md` | No skill loader — read spec directly |
137
- | `Agent(...)` / `Task(...)` | Continue the sub-task inline | No sub-agent model; inline it |
138
-
139
- ### Nested Skill references
46
+ ## Architecture
140
47
 
141
- When a command spec calls `Skill("x")` or references another command, read
142
- the referenced command spec directly:
48
+ The installed command files are thin entry adapters. A command loads exactly
49
+ one authoritative spec from ForgeDock's stable installation and translates
50
+ runtime mechanics without copying workflow behavior.
143
51
 
52
+ ```text
53
+ OpenCode /forge/work-on
54
+ -> small generated command adapter
55
+ -> commands/work-on.md
56
+ -> only the nested phase spec reached by the dispatcher
57
+ -> GitHub labels and FORGE annotations remain durable state
144
58
  ```
145
- # Load the referenced command spec:
146
- Read("/path/to/forgedock/commands/quality-gate.md")
147
- ```
148
-
149
- Map command names to file paths:
150
- - `Skill("work-on")` → `commands/work-on.md`
151
- - `Skill("review-pr")` → `commands/review-pr.md`
152
- - `Skill("quality-gate")` → `commands/quality-gate.md`
153
- - `Skill("orchestrate")` → `commands/orchestrate.md`
154
59
 
155
- ## GitHub Operations
156
-
157
- All FORGE annotations are written to GitHub issue/PR comments via the `gh`
158
- CLI. Use `Bash()` for every GitHub operation.
159
-
160
- ### Label management
161
-
162
- ```bash
163
- Bash("gh issue edit 123 -R OWNER/REPO --add-label 'workflow:investigating'")
164
- Bash("gh issue edit 123 -R OWNER/REPO --remove-label 'workflow:investigating'")
60
+ The generated plugin has no prompt text. It:
61
+
62
+ - injects `FORGE_HOME` into OpenCode shell environments;
63
+ - defaults `subagent_depth` to 2 when the user has not configured it, while
64
+ preserving explicit lower limits;
65
+ - grants the built-in `general` subagent permission to invoke native `task`
66
+ unless the user explicitly configured a task permission;
67
+ - opts into OpenCode background subagents by default so each completed issue can
68
+ wake the parent orchestrator independently; set
69
+ `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=false` to opt out;
70
+ - selects Git Bash on Windows only when the user has not explicitly configured
71
+ an OpenCode shell, because the shared workflows and helper scripts use Bash.
72
+
73
+ The adapter also registers every eligible ForgeDock workflow as a native
74
+ OpenCode skill. Top-level and nested source paths are normalized to valid
75
+ hyphenated skill names while the wrapper continues to point at the authoritative
76
+ source file:
77
+
78
+ ```text
79
+ commands/work-on.md -> skills/work-on/SKILL.md
80
+ commands/work-on/investigate.md -> skills/work-on-investigate/SKILL.md
81
+ commands/review-pr.md -> skills/review-pr/SKILL.md
165
82
  ```
166
83
 
167
- ### Reading existing annotations
168
-
169
- ```bash
170
- Bash("gh api repos/OWNER/REPO/issues/123/comments \
171
- --jq '.[] | select(.body | contains(\"FORGE:INVESTIGATOR\")) | .body'")
84
+ The wrapper is intentionally thin. It carries the workflow's `name` and
85
+ `description` frontmatter, preserves the current-context arguments, and loads
86
+ only the referenced `commands/**/*.md` spec.
87
+
88
+ OpenCode's provider configuration remains entirely user-owned. ForgeDock does
89
+ not require Anthropic when invoked through OpenCode; any provider and model
90
+ supported by the user's OpenCode configuration can execute the commands.
91
+
92
+ ## Token Efficiency
93
+
94
+ The adapter follows these rules:
95
+
96
+ - No global ForgeDock `instructions` entry.
97
+ - Top-level user entry commands are registered under `/forge/*`.
98
+ - Every eligible workflow is registered as a native skill so nested
99
+ `Skill(...)` dispatch resolves through OpenCode's `skill` tool instead of
100
+ filesystem guessing.
101
+ - Nested phase specs are loaded only when their dispatcher reaches them.
102
+ - Task/Agent work uses OpenCode subagents only for the parallelism, isolation,
103
+ or context-pressure cases required by the shared workflow.
104
+ - Orchestration dispatches independent issues with `task(background=true)` and
105
+ processes each injected task-result event immediately; it does not wait for a
106
+ wave or the slowest sibling.
107
+ - GitHub state and the durable engine remain the recovery source instead of
108
+ replaying prior prompt context.
109
+
110
+ The generated adapter preamble is intentionally small. It maps Claude Code's
111
+ in-conversation `Skill(...)` loading to the normalized native skill name and
112
+ authoritative shared spec. It maps isolated `Task(...)` and permitted
113
+ `Agent(...)` calls to OpenCode's native `task` tool. Before the shared review
114
+ specs evaluate Claude's literal `Task`/`Agent` names, an OpenCode runtime marker
115
+ selects `DISPATCH_TOOL=task`; the absence of those Claude names must not produce
116
+ a false `FORGE:REVIEW_BLOCKED` result.
117
+
118
+ Every isolated review dispatch uses the explicit native argument shape. Every
119
+ native task call must include the schema-required `subagent_type` at the top
120
+ level alongside its `description` and `prompt`:
121
+
122
+ ```js
123
+ { description: "...", prompt: "...", subagent_type: "general", background: true }
172
124
  ```
173
125
 
174
- ### Writing a FORGE annotation comment
175
-
176
- For multi-line comment bodies, write the content to a temp file first:
177
-
178
- ```bash
179
- # Write comment body to temp file (avoids shell quoting issues)
180
- Write("/tmp/forge_comment.md", """<!-- FORGE:INVESTIGATOR -->
181
- ## Investigation Report
182
-
183
- **Verdict**: CONFIRMED
184
- ...
185
- <!-- INVESTIGATION:COMPLETE -->""")
126
+ Implementation and review work uses `general`; read-only discovery uses
127
+ `explore`. Claude `general-purpose` maps to `general` and
128
+ `codebase-explorer` maps to `explore`. When a source task omits its type, the
129
+ generated adapter safely defaults it to `general`; unsupported types stop with
130
+ `FORGE_OPENCODE_CAPABILITY_ERROR` instead of reaching schema validation.
131
+ If the native `task` capability itself is unavailable, the workflow posts
132
+ `FORGE:REVIEW_BLOCKED` and stops rather than falling back to inline review or
133
+ another pipeline controller.
134
+ The generated plugin adds `background: true` unless
135
+ `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=false` is explicitly set.
186
136
 
187
- Bash("gh issue comment 123 -R OWNER/REPO --body \"$(cat /tmp/forge_comment.md)\"")
188
- ```
137
+ `commands/work-on.md` is still a large entry dispatcher and is loaded in full,
138
+ matching the Claude Code path. The adapter prevents additional eager loading,
139
+ but reducing that entry cost requires decomposing the shared authoritative spec
140
+ rather than maintaining an OpenCode-only copy.
189
141
 
190
- ### Creating a PR
142
+ ## Lifecycle
191
143
 
192
144
  ```bash
193
- Write("/tmp/pr_body.md", """## Summary
194
- ...
195
-
196
- Closes #967""")
197
-
198
- Bash("gh pr create -R OWNER/REPO \
199
- --base milestone/developer-experience-distribution \
200
- --head feat/opencode-adapter-967 \
201
- --title 'feat: OpenCode adapter (#967)' \
202
- --body \"$(cat /tmp/pr_body.md)\"")
145
+ npx forgedock opencode status
146
+ npx forgedock opencode install # update/repair
147
+ npx forgedock opencode install --extras
148
+ npx forgedock opencode uninstall
203
149
  ```
204
150
 
205
- ## Worktrees
206
-
207
- ForgeDock uses git worktrees to isolate branch work. Create one with:
208
-
209
- ```bash
210
- Bash("git fetch origin")
211
- Bash("git worktree add .claude/worktrees/feat-my-feature-123 \
212
- -b feat/my-feature-123 origin/staging")
151
+ `npx forgedock update` also refreshes an existing managed OpenCode adapter,
152
+ including its plugin and generated skills. It preserves the installed core vs.
153
+ `--extras` tier, migrates the sentinel-marked legacy adapter, and does not
154
+ install OpenCode files when no ForgeDock adapter is already registered.
155
+
156
+ Updates are deterministic and prune stale ForgeDock-owned command files.
157
+ Uninstall removes only files listed in the ownership manifest and still marked
158
+ with a ForgeDock sentinel. User-owned commands, plugins, and files placed in
159
+ the `forgedock/` namespace are never removed; that namespace is pruned only
160
+ when it is empty.
161
+ For backward compatibility, install and uninstall may rewrite `opencode.json`
162
+ only to remove legacy entries whose two-key `description` and `template` still
163
+ exactly match one of the definitions emitted by the retired adapter and point to
164
+ the active ForgeDock home (or the home recorded in the ownership manifest during
165
+ uninstall), and the sentinel-marked legacy instructions file is present. It also
166
+ removes references to that managed `~/.opencode-forge.md` instructions file. The
167
+ migration does not rewrite `opencode.jsonc`. User-owned settings and customized commands are preserved;
168
+ definitions with extra keys, edited fields, different
169
+ paths, a missing ownership marker, or ambiguous ownership are left in place. If
170
+ a legacy config cannot be parsed or written, the migration leaves the legacy
171
+ artifacts in place.
172
+
173
+ ## Locations
174
+
175
+ Default global location:
176
+
177
+ ```text
178
+ ~/.config/opencode/
179
+ commands/forge/*.md
180
+ skills/<workflow-name>/SKILL.md
181
+ plugins/forgedock.js
182
+ forgedock/manifest.json
213
183
  ```
214
184
 
215
- Work inside the worktree for all file edits and commits:
185
+ `XDG_CONFIG_HOME` and `OPENCODE_CONFIG_DIR` are honored when set. An npm/npx
186
+ installation first persists the required ForgeDock payload under `~/.forge` so
187
+ generated commands never point into an evictable package cache. A stable Git
188
+ clone is referenced directly.
189
+
190
+ ## Current Boundary
191
+
192
+ This integration provides native interactive command and subagent execution.
193
+ The separate `forgedock run` and `forgedock run-issue` backend still supports
194
+ only Claude CLI and the Anthropic API. An OpenCode engine backend must be added
195
+ and validated before ForgeDock can claim provider-neutral headless parity.
196
+
197
+ The ForgeDock plugin provides the OpenCode-specific runtime boundary for shell
198
+ and task execution. Its `tool.execute.before` hook rejects Claude-backed and
199
+ recursive ForgeDock controller commands, and normalizes native task arguments
200
+ before execution; the shared workflow rules and deterministic scripts remain
201
+ the source of truth for all other behavior.
202
+
203
+ OpenCode 1.18.4 keeps background subagents experimental. ForgeDock opts into
204
+ that feature by default because the streaming DAG depends on the parent session
205
+ receiving one completion event per child. A native background task returns a
206
+ `<task id="..." state="running">` marker immediately and later injects a
207
+ `state="completed"` or `state="error"` result into the parent session. The
208
+ orchestrator maps that id to the issue, re-reads GitHub state, and dispatches
209
+ newly unlocked successors in the same response.
210
+
211
+ If `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=false` is explicitly set,
212
+ ForgeDock uses independent foreground tasks where OpenCode can execute them
213
+ concurrently and labels the run as degraded. Foreground tasks cannot provide
214
+ the same per-completion wake behavior, so this opt-out intentionally restores a
215
+ wave-like fallback rather than silently claiming Claude-equivalent throughput.
216
+
217
+ Commands that inspect Claude-specific transcripts or Claude installation state
218
+ remain runtime-specific and should not be represented as portable until they
219
+ receive dedicated implementations.
220
+
221
+ ## Orchestration Runtime
222
+
223
+ OpenCode orchestration uses the native OpenCode `task` tool for isolated issue
224
+ work and follows the shared `commands/work-on.md` state machine. Each ready
225
+ issue is launched as `task(subagent_type="general", background=true)` and its
226
+ task-result event is treated as the completion notification for that issue. It
227
+ must not
228
+ route through `forgedock run-issue` when that would select the Claude CLI or
229
+ Anthropic API backend. If the host does not expose an OpenCode runtime marker,
230
+ set the runtime explicitly before launching a headless command:
216
231
 
217
232
  ```bash
218
- Read("/path/to/repo/.claude/worktrees/feat-my-feature-123/file.py")
219
- Edit("/path/to/repo/.claude/worktrees/feat-my-feature-123/file.py", ...)
220
- Bash("git -C /path/to/repo/.claude/worktrees/feat-my-feature-123 status")
233
+ FORGE_RUNTIME=opencode opencode run --command forge/orchestrate "fast-lane"
221
234
  ```
222
235
 
223
- ## FORGE Annotation Protocol
224
-
225
- Every pipeline stage writes a structured annotation to GitHub. Key rules:
226
-
227
- 1. **Idempotency**: Check for existing annotations BEFORE starting a phase.
228
- Do not re-run a completed phase.
229
- 2. **Compaction resilience**: Write annotations AFTER completing each
230
- significant step. GitHub is the persistent state layer.
231
- 3. **Restart partial annotations**: If an annotation exists without its
232
- `:COMPLETE` sentinel, delete it and restart the phase.
233
- 4. **Respect label state**: Labels track workflow state. Read and set them
234
- at each phase boundary.
235
-
236
- ### Label state machine
237
-
238
- ```
239
- workflow:investigating
240
- → workflow:ready-to-build (investigation complete)
241
- → workflow:building (build started)
242
- → workflow:in-review (PR created)
243
- → workflow:merged (PR merged) [TERMINAL]
244
-
245
- workflow:invalid [TERMINAL]
246
- workflow:decomposed [TERMINAL]
247
- needs-human [TERMINAL]
248
- ```
249
-
250
- Stop the pipeline when any terminal label is set.
251
-
252
- ## Limitations
253
-
254
- | Capability | Claude Code | OpenCode (this adapter) |
255
- |------------|-------------|------------------------|
256
- | Skill loading | Dynamic (`~/.claude/commands/`) | Read `commands/*.md` directly |
257
- | Native slash commands | `/work-on 967` | `/work-on 967` (via `command` config) |
258
- | Tool name parity | Native | Direct (same names) |
259
- | Sub-agent invocation | `Skill("review-pr")` | Read `commands/review-pr.md` directly |
260
- | Session continuity | Native compaction resilience | Re-read GitHub state each session |
261
- | Multi-phase pipeline | Automatic (single continuous session) | Supported (GitHub state is persistent) |
262
-
263
- **Sub-skill invocation**: When a command spec calls `Skill("x")`, OpenCode
264
- has no native skill loader. Read the referenced command spec file directly
265
- instead.
266
-
267
- **Parallel tasks**: When a command spec calls `Agent(...)` or `Task(...)` for
268
- parallelism (e.g., multi-agent review in `review-pr-agents.md`), execute the
269
- sub-tasks sequentially. OpenCode runs one agent context at a time.
270
-
271
- ## Configuration
272
-
273
- `install-opencode.sh` patches `~/.config/opencode/opencode.json`. Example
274
- of what is added:
275
-
276
- ```json
277
- {
278
- "instructions": [
279
- "~/.opencode-forge.md"
280
- ],
281
- "command": {
282
- "work-on": {
283
- "description": "Run the ForgeDock full issue pipeline (investigate → build → review → merge)",
284
- "template": "Read /path/to/forgedock/commands/work-on.md and execute the pipeline for issue {{args}}."
285
- },
286
- "review-pr": {
287
- "description": "Run the ForgeDock PR review pipeline",
288
- "template": "Read /path/to/forgedock/commands/review-pr.md and execute the PR review for PR {{args}}."
289
- },
290
- "quality-gate": {
291
- "description": "Run ForgeDock pre-commit quality checks",
292
- "template": "Read /path/to/forgedock/commands/quality-gate.md and run all quality gate checks."
293
- },
294
- "orchestrate": {
295
- "description": "Run ForgeDock parallel multi-issue orchestration",
296
- "template": "Read /path/to/forgedock/commands/orchestrate.md and orchestrate the issues: {{args}}."
297
- }
298
- }
299
- }
300
- ```
301
-
302
- Existing config keys (provider, model, etc.) are preserved. ForgeDock only
303
- adds to the `instructions` array and `command` object — never overwrites.
304
-
305
- ## Reference
306
-
307
- - [FORGE Protocol spec](FORGE-PROTOCOL.md) — annotation format, label state machine
308
- - [Aider adapter](AIDER.md) — parallel adapter reference (Aider uses `/run` translation)
309
- - [Codex adapter](CODEX.md) — parallel adapter reference (Codex skill model)
310
- - [Pipeline commands](../commands/) — shared workflow specs (authoritative for all runtimes)
311
- - [`install-opencode.sh`](../install-opencode.sh) — installer script
312
- - [`scripts/forge-run.sh`](../scripts/forge-run.sh) — universal shell phase router
236
+ Each task re-reads GitHub labels and `FORGE:*` comments after every phase and
237
+ continues until `workflow:merged`, `workflow:invalid`, `needs-human`, or
238
+ `workflow:awaiting-merge`. The parent orchestrator processes every child
239
+ completion independently, so a completed predecessor can unlock and dispatch
240
+ its successors while unrelated issues continue running. If native task
241
+ dispatch is unavailable, post a
242
+ `FORGE:OPENCODE_BLOCKED` diagnostic naming the missing capability and add
243
+ `needs-human`; do not leave an issue stranded at `workflow:engine-error`.
244
+
245
+ If a generated command or skill cannot load its authoritative workflow, it must
246
+ stop with an actionable `FORGE_OPENCODE_CAPABILITY_ERROR`. It must not recover
247
+ by invoking `forgedock run-issue`, `npx forgedock run-issue`, or a recursive
248
+ `opencode run`; those paths select a competing controller or Claude-backed
249
+ backend.
250
+
251
+ The same boundary is enforced below the plugin for direct CLI callers. With
252
+ `FORGE_RUNTIME=opencode`, `forgedock run`, `forgedock run-issue`, and Claude
253
+ backend preflight fail before selecting a provider. The stable error is
254
+ `FORGE_OPENCODE_CAPABILITY_ERROR`; continue by using the registered native
255
+ Skill and Task workflow instead.
256
+
257
+ This runtime branch is additive. Claude keeps its existing engine and
258
+ background-agent paths, and Codex keeps its installed namespaced skills and
259
+ repo-local adapters.
260
+
261
+ ## Runtime Paths
262
+
263
+ The shared orchestration spec resolves `classify-lane.sh` by runtime:
264
+
265
+ | Runtime | Helper precedence | Worktree root |
266
+ |---------|-------------------|---------------|
267
+ | Claude | `${FORGE_HOME}/scripts`, then `~/.claude/scripts`, then the repository `scripts/` | `.claude/worktrees/` |
268
+ | OpenCode | `${FORGE_HOME}/scripts`, then the repository `scripts/`, then `~/.opencode/scripts` | `.opencode/worktrees/` |
269
+ | Codex | `${FORGE_HOME}/scripts`, then the repository `scripts/` | `.codex/worktrees/` |
270
+
271
+ Set `FORGE_RUNTIME=opencode` for headless OpenCode sessions when no native
272
+ OpenCode marker is available. The resolver is used by initial dispatch and all
273
+ review-finding classification loops, so an OpenCode installation never needs
274
+ `~/.claude` while the Claude precedence and fallback remain unchanged.
275
+
276
+ ## Source References
277
+
278
+ - Shared workflows: [`commands/`](../commands/)
279
+ - Installer implementation: [`bin/opencode-adapter.mjs`](../bin/opencode-adapter.mjs)
280
+ - FORGE protocol: [`docs/spec/forge-protocol-v1.md`](spec/forge-protocol-v1.md)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "forgedock",
3
- "version": "1.6.0",
4
- "description": "Autonomous dev pipeline for Claude Code. GitHub as institutional memory — every issue, PR, and annotation survives context resets and makes the next agent smarter.",
3
+ "version": "1.7.1",
4
+ "description": "Autonomous development pipeline for coding agents. GitHub as institutional memory, with native Claude Code and OpenCode entrypoints.",
5
5
  "bin": {
6
6
  "forgedock": "bin/forgedock.mjs"
7
7
  },
@@ -16,6 +16,7 @@
16
16
  "llm",
17
17
  "knowledge-graph",
18
18
  "claude",
19
+ "opencode",
19
20
  "anthropic",
20
21
  "agentic-ai",
21
22
  "devtools",