forgedock 1.5.1 → 1.7.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/docs/OPENCODE.md CHANGED
@@ -1,312 +1,192 @@
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
19
+ npx forgedock opencode install --extras
73
20
  ```
74
21
 
75
- ## Usage
76
-
77
- ### Native slash commands (recommended)
78
-
79
- After running `install-opencode.sh`, use ForgeDock commands in the OpenCode
80
- TUI:
22
+ Restart OpenCode after install or update. OpenCode loads commands and plugins
23
+ at startup.
81
24
 
82
- ```
83
- /work-on 967
84
- /review-pr 123
85
- /quality-gate
86
- ```
87
-
88
- Or headlessly via `opencode run`:
89
-
90
- ```bash
91
- opencode run --command work-on "967"
92
- opencode run --command review-pr "123"
93
- ```
25
+ The installer does not edit `opencode.json` or `opencode.jsonc`. It writes only
26
+ ForgeDock-owned files under OpenCode's config directory and records them in
27
+ `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
 
99
- ```
100
- Read the file /path/to/forgedock/commands/work-on.md and run the pipeline for issue 967.
33
+ ```text
34
+ /forge/work-on 967
35
+ /forge/review-pr 123
36
+ /forge/quality-gate
37
+ /forge/orchestrate milestone checkout-v2
101
38
  ```
102
39
 
103
- OpenCode will load the spec and execute each phase using its native tools.
104
-
105
- ### Phase routing with forge-run.sh
106
-
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
- ```
46
+ ## Architecture
120
47
 
121
- ## Tool Translation
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.
122
51
 
123
- OpenCode and Claude Code share the same tool names. Most pipeline operations
124
- run without modification:
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
58
+ ```
125
59
 
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 |
60
+ The generated plugin has no prompt text. It:
138
61
 
139
- ### Nested Skill references
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
+ - selects Git Bash on Windows only when the user has not explicitly configured
66
+ an OpenCode shell, because the shared workflows and helper scripts use Bash.
140
67
 
141
- When a command spec calls `Skill("x")` or references another command, read
142
- the referenced command spec directly:
68
+ OpenCode's provider configuration remains entirely user-owned. ForgeDock does
69
+ not require Anthropic when invoked through OpenCode; any provider and model
70
+ supported by the user's OpenCode configuration can execute the commands.
143
71
 
144
- ```
145
- # Load the referenced command spec:
146
- Read("/path/to/forgedock/commands/quality-gate.md")
147
- ```
72
+ ## Token Efficiency
148
73
 
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`
74
+ The adapter follows these rules:
154
75
 
155
- ## GitHub Operations
76
+ - No global ForgeDock `instructions` entry.
77
+ - No generated skill for every source file. Large skill catalogs add metadata
78
+ to every session even when ForgeDock is unused.
79
+ - Only top-level user entry commands are registered.
80
+ - Nested phase specs are loaded only when their dispatcher reaches them.
81
+ - Task/Agent work uses OpenCode subagents only for the parallelism, isolation,
82
+ or context-pressure cases required by the shared workflow.
83
+ - GitHub state and the durable engine remain the recovery source instead of
84
+ replaying prior prompt context.
156
85
 
157
- All FORGE annotations are written to GitHub issue/PR comments via the `gh`
158
- CLI. Use `Bash()` for every GitHub operation.
86
+ The generated adapter preamble is intentionally small. It maps Claude Code's
87
+ in-conversation `Skill(...)` loading to a lazy read of the corresponding shared
88
+ spec. It maps isolated `Task(...)` and permitted `Agent(...)` calls to
89
+ OpenCode's native `task` tool.
159
90
 
160
- ### Label management
91
+ `commands/work-on.md` is still a large entry dispatcher and is loaded in full,
92
+ matching the Claude Code path. The adapter prevents additional eager loading,
93
+ but reducing that entry cost requires decomposing the shared authoritative spec
94
+ rather than maintaining an OpenCode-only copy.
161
95
 
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'")
165
- ```
166
-
167
- ### Reading existing annotations
96
+ ## Lifecycle
168
97
 
169
98
  ```bash
170
- Bash("gh api repos/OWNER/REPO/issues/123/comments \
171
- --jq '.[] | select(.body | contains(\"FORGE:INVESTIGATOR\")) | .body'")
99
+ npx forgedock opencode status
100
+ npx forgedock opencode install # update/repair
101
+ npx forgedock opencode install --extras
102
+ npx forgedock opencode uninstall
172
103
  ```
173
104
 
174
- ### Writing a FORGE annotation comment
175
-
176
- For multi-line comment bodies, write the content to a temp file first:
105
+ Updates are deterministic and prune stale ForgeDock-owned command files.
106
+ Uninstall removes only files listed in the ownership manifest and still marked
107
+ with a ForgeDock sentinel. User-owned commands, plugins, and files placed in
108
+ the `forgedock/` namespace are never removed; that namespace is pruned only
109
+ when it is empty.
110
+ Install also removes the previous ForgeDock-managed `~/.opencode-forge.md`
111
+ instructions file and its exact legacy config entries when they are present.
177
112
 
178
- ```bash
179
- # Write comment body to temp file (avoids shell quoting issues)
180
- Write("/tmp/forge_comment.md", """<!-- FORGE:INVESTIGATOR -->
181
- ## Investigation Report
113
+ ## Locations
182
114
 
183
- **Verdict**: CONFIRMED
184
- ...
185
- <!-- INVESTIGATION:COMPLETE -->""")
115
+ Default global location:
186
116
 
187
- Bash("gh issue comment 123 -R OWNER/REPO --body \"$(cat /tmp/forge_comment.md)\"")
117
+ ```text
118
+ ~/.config/opencode/
119
+ commands/forge/*.md
120
+ plugins/forgedock.js
121
+ forgedock/manifest.json
188
122
  ```
189
123
 
190
- ### Creating a PR
124
+ `XDG_CONFIG_HOME` and `OPENCODE_CONFIG_DIR` are honored when set. An npm/npx
125
+ installation first persists the required ForgeDock payload under `~/.forge` so
126
+ generated commands never point into an evictable package cache. A stable Git
127
+ clone is referenced directly.
191
128
 
192
- ```bash
193
- Write("/tmp/pr_body.md", """## Summary
194
- ...
129
+ ## Current Boundary
195
130
 
196
- Closes #967""")
131
+ This integration provides native interactive command and subagent execution.
132
+ The separate `forgedock run` and `forgedock run-issue` backend still supports
133
+ only Claude CLI and the Anthropic API. An OpenCode engine backend must be added
134
+ and validated before ForgeDock can claim provider-neutral headless parity.
197
135
 
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)\"")
203
- ```
136
+ Claude's `PreToolUse` safety hook has not yet been ported to an OpenCode plugin.
137
+ The shared workflow rules and deterministic scripts still apply, but equivalent
138
+ mechanical enforcement must be implemented and tested before claiming complete
139
+ Claude-runtime safety parity.
204
140
 
205
- ## Worktrees
141
+ OpenCode 1.18.4 keeps background subagents experimental. When they are not
142
+ enabled, the command adapter requires independent foreground tasks to be
143
+ launched concurrently where supported and uses ForgeDock's GitHub-label polling
144
+ fallback. This preserves isolated review contexts but does not yet prove equal
145
+ wall-clock behavior for `/forge/orchestrate`.
206
146
 
207
- ForgeDock uses git worktrees to isolate branch work. Create one with:
147
+ Commands that inspect Claude-specific transcripts or Claude installation state
148
+ remain runtime-specific and should not be represented as portable until they
149
+ receive dedicated implementations.
208
150
 
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")
213
- ```
151
+ ## Orchestration Runtime
214
152
 
215
- Work inside the worktree for all file edits and commits:
153
+ OpenCode orchestration uses the native OpenCode `task` tool for isolated issue
154
+ work and follows the shared `commands/work-on.md` state machine. It must not
155
+ route through `forgedock run-issue` when that would select the Claude CLI or
156
+ Anthropic API backend. If the host does not expose an OpenCode runtime marker,
157
+ set the runtime explicitly before launching a headless command:
216
158
 
217
159
  ```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")
160
+ FORGE_RUNTIME=opencode opencode run --command forge/orchestrate "fast-lane"
221
161
  ```
222
162
 
223
- ## FORGE Annotation Protocol
163
+ Each task re-reads GitHub labels and `FORGE:*` comments after every phase and
164
+ continues until `workflow:merged`, `workflow:invalid`, `needs-human`, or
165
+ `workflow:awaiting-merge`. If native task dispatch is unavailable, post a
166
+ `FORGE:OPENCODE_BLOCKED` diagnostic naming the missing capability and add
167
+ `needs-human`; do not leave an issue stranded at `workflow:engine-error`.
224
168
 
225
- Every pipeline stage writes a structured annotation to GitHub. Key rules:
169
+ This runtime branch is additive. Claude keeps its existing engine and
170
+ background-agent paths, and Codex keeps its installed namespaced skills and
171
+ repo-local adapters.
226
172
 
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.
173
+ ## Runtime Paths
235
174
 
236
- ### Label state machine
175
+ The shared orchestration spec resolves `classify-lane.sh` by runtime:
237
176
 
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
- ```
177
+ | Runtime | Helper precedence | Worktree root |
178
+ |---------|-------------------|---------------|
179
+ | Claude | `${FORGE_HOME}/scripts`, then `~/.claude/scripts`, then the repository `scripts/` | `.claude/worktrees/` |
180
+ | OpenCode | `${FORGE_HOME}/scripts`, then the repository `scripts/`, then `~/.opencode/scripts` | `.opencode/worktrees/` |
181
+ | Codex | `${FORGE_HOME}/scripts`, then the repository `scripts/` | `.codex/worktrees/` |
301
182
 
302
- Existing config keys (provider, model, etc.) are preserved. ForgeDock only
303
- adds to the `instructions` array and `command` object — never overwrites.
183
+ Set `FORGE_RUNTIME=opencode` for headless OpenCode sessions when no native
184
+ OpenCode marker is available. The resolver is used by initial dispatch and all
185
+ review-finding classification loops, so an OpenCode installation never needs
186
+ `~/.claude` while the Claude precedence and fallback remain unchanged.
304
187
 
305
- ## Reference
188
+ ## Source References
306
189
 
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
190
+ - Shared workflows: [`commands/`](../commands/)
191
+ - Installer implementation: [`bin/opencode-adapter.mjs`](../bin/opencode-adapter.mjs)
192
+ - 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.5.1",
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.0",
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",
@@ -102,6 +102,7 @@ MARKER_REGISTRY="
102
102
  DESIGN
103
103
  DISPATCHER
104
104
  DOSSIER_UPDATED
105
+ ENGINE_FALLBACK
105
106
  FAST_PATH
106
107
  FINDING_SOURCE
107
108
  FIX_CI