@oisincoveney/pipeline 1.20.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +66 -44
  2. package/defaults/opencode/plugins/pipeline-goal-context.ts +18 -0
  3. package/defaults/opencode-ecosystem.yaml +203 -0
  4. package/dist/commands/pipeline-command.js +0 -2
  5. package/dist/config.d.ts +264 -13
  6. package/dist/config.js +389 -160
  7. package/dist/gates.js +47 -48
  8. package/dist/index.d.ts +6 -5
  9. package/dist/index.js +58 -56
  10. package/dist/install-commands.js +142 -28
  11. package/dist/json-line-values.js +17 -0
  12. package/dist/mcp/gateway.js +144 -5
  13. package/dist/mcp/repo-local-backends.js +70 -0
  14. package/dist/mcp/toolhive-vmcp.js +72 -0
  15. package/dist/model-resolver.js +22 -0
  16. package/dist/package-assets.js +7 -0
  17. package/dist/pipeline-init.js +11 -256
  18. package/dist/pipeline-runtime.d.ts +2 -2
  19. package/dist/pipeline-runtime.js +183 -5
  20. package/dist/runner-event-sink.js +27 -7
  21. package/dist/runner-job/delivery.js +64 -15
  22. package/dist/runner-job/pr-summary.js +117 -0
  23. package/dist/runner-job/run.js +83 -30
  24. package/dist/runner-job/workspace.js +39 -5
  25. package/dist/runner-job-contract.d.ts +15 -1
  26. package/dist/runner-job-contract.js +5 -2
  27. package/dist/runner-job-k8s.d.ts +2 -0
  28. package/dist/runner-job-k8s.js +2 -0
  29. package/dist/runner-output.js +17 -34
  30. package/dist/runner.d.ts +3 -1
  31. package/dist/runner.js +30 -10
  32. package/dist/runtime/agent-node/agent-node.js +44 -7
  33. package/dist/runtime/builtins/builtins.js +28 -5
  34. package/dist/runtime/changed-files/changed-files.js +32 -4
  35. package/dist/runtime/context/context.js +1 -0
  36. package/dist/runtime/contracts/contracts.d.ts +17 -1
  37. package/dist/runtime/contracts/index.d.ts +1 -1
  38. package/dist/runtime/events/events.js +45 -1
  39. package/dist/runtime/goal-loop/continuation-prompt.js +125 -0
  40. package/dist/runtime/goal-loop.d.ts +37 -0
  41. package/dist/runtime/goal-loop.js +138 -0
  42. package/dist/runtime/goal-state/goal-requirement.js +11 -0
  43. package/dist/runtime/goal-state.d.ts +146 -0
  44. package/dist/runtime/goal-state.js +335 -0
  45. package/dist/runtime/json-validation/json-validation.js +8 -2
  46. package/dist/runtime/opencode-adapter.js +60 -0
  47. package/dist/runtime/parallel-node/parallel-node.js +1 -0
  48. package/dist/schedule-planner.d.ts +48 -24
  49. package/dist/schedule-planner.js +419 -98
  50. package/dist/standard-output-schemas.js +81 -0
  51. package/dist/workflow-planner.d.ts +1 -0
  52. package/dist/workflow-planner.js +1 -0
  53. package/docs/adr-opencode-first-goal-loop-runtime.md +73 -0
  54. package/docs/config-architecture.md +58 -16
  55. package/docs/mcp-gateway.md +42 -9
  56. package/docs/mcp-host-isolation.md +2 -1
  57. package/docs/operator-guide.md +98 -19
  58. package/docs/pipeline-console-runner-contract.md +14 -14
  59. package/docs/pipeline-smoke-recovery-plan.md +7 -8
  60. package/docs/slash-command-adapter-contract.md +15 -7
  61. package/package.json +10 -4
  62. package/dist/runtime/changed-files/index.js +0 -2
package/README.md CHANGED
@@ -1,16 +1,15 @@
1
1
  # @oisincoveney/pipeline
2
2
 
3
- Config-driven multi-agent pipeline runner for repository work. The source of
4
- truth is three YAML files: `.pipeline/runners.yaml` declares runner adapters,
5
- `.pipeline/profiles.yaml` declares reusable profiles and their grants, and
6
- `.pipeline/pipeline.yaml` declares orchestration, workflows, gates, hooks, and
7
- artifacts.
3
+ Config-driven multi-agent pipeline runner for repository work. Runtime config is
4
+ owned by the installed `@oisincoveney/pipeline` package. Repo-local `.pipeline`
5
+ paths are runtime artifact locations only; they are not the runtime config
6
+ source.
8
7
 
9
8
  ## Requirements
10
9
 
11
10
  - Bun 1.1 or newer
12
11
  - Node.js 22.13 or newer
13
- - `npx`, `backlog`, `uvx`, and Docker on `PATH` for default skills and MCP setup
12
+ - `npx`, `backlog`, `uvx`, and Docker on `PATH` for default skills and MCP gateway setup
14
13
  - At least one configured runner CLI on `PATH`: `codex`, `opencode`, `kimi`,
15
14
  `pi`, or a declared command runner
16
15
 
@@ -22,33 +21,32 @@ bun install --frozen-lockfile
22
21
 
23
22
  ## Start A Repository
24
23
 
25
- Scaffold the default YAML workflow:
24
+ Initialize package-owned pipeline support:
26
25
 
27
26
  ```shell
28
27
  pipe init
29
28
  ```
30
29
 
31
30
  `pipe init` installs default project skills with
32
- `npx skills add oisincoveney/skills` and registers default MCP servers with the
33
- MCPM CLI from https://mcpm.sh/. Default profiles point at the installed
34
- `.agents/skills/<skill>/SKILL.md` files in the target repository. The package
35
- invokes MCPM through `uvx --python 3.12 mcpm`, so generated `.mcp.json` entries
36
- do not depend on a globally installed `mcpm` binary. The default Qdrant/memory
37
- MCP is the Momokaya remote endpoint
38
- `https://memory-mcp.momokaya.ee/mcp/`.
39
-
40
- The default GitHub MCP registration uses GitHub's official container in
41
- read-only mode and reads `GITHUB_PERSONAL_ACCESS_TOKEN` from the environment.
42
- The Momokaya gateway endpoint is protected by Traefik HTTP Basic auth. Set
43
- `PIPELINE_MCP_GATEWAY_AUTHORIZATION` to the full HTTP `Authorization` header
44
- value before starting Codex or OpenCode:
31
+ `npx skills add oisincoveney/skills`, then writes generated OpenCode and Codex
32
+ command surfaces plus their singleton `pipeline-gateway` MCP entries. OpenCode
33
+ is the package default runtime; Codex remains a compatibility runner and host
34
+ surface. The command does not create repo-local `.pipeline` config files.
35
+
36
+ The default MCP gateway can run locally or point at the hosted Momokaya
37
+ gateway. Set `PIPELINE_MCP_GATEWAY_AUTHORIZATION` to the full HTTP
38
+ `Authorization` header value before starting Codex or OpenCode when using a
39
+ protected gateway:
45
40
 
46
41
  ```shell
47
42
  export PIPELINE_MCP_GATEWAY_AUTHORIZATION="Basic $(printf '%s' 'user:password' | base64)"
48
43
  ```
49
44
 
50
- `pipe init` writes project-level Codex and OpenCode config that points at the
51
- singleton `pipeline-gateway` MCP server.
45
+ To refresh or check generated host files later, use:
46
+
47
+ ```shell
48
+ pipe install-commands --host all --check
49
+ ```
52
50
 
53
51
  Check local prerequisites and config health:
54
52
 
@@ -136,9 +134,12 @@ validation, contract-version checks, and JSON Schema generation.
136
134
  Use `PIPELINE_TARGET_PATH=/path/to/worktree` when the checked-out target repo is
137
135
  mounted somewhere other than the process working directory.
138
136
 
139
- ## Minimal YAML
137
+ ## Custom YAML Parts
138
+
139
+ Runtime execution uses package-owned defaults. Tests and advanced embedding code
140
+ can still parse explicit YAML parts with `parsePipelineConfigParts()`.
140
141
 
141
- `.pipeline/runners.yaml`:
142
+ `runners`:
142
143
 
143
144
  ```yaml
144
145
  version: 1
@@ -156,7 +157,7 @@ runners:
156
157
  output_formats: [text, json, jsonl, json_schema]
157
158
  ```
158
159
 
159
- `.pipeline/profiles.yaml`:
160
+ `profiles`:
160
161
 
161
162
  ```yaml
162
163
  version: 1
@@ -182,7 +183,7 @@ profiles:
182
183
  format: text
183
184
  ```
184
185
 
185
- `.pipeline/pipeline.yaml`:
186
+ Example workflow shape:
186
187
 
187
188
  ```yaml
188
189
  version: 1
@@ -215,14 +216,12 @@ workflows:
215
216
  builtin: typecheck
216
217
  ```
217
218
 
218
- Projects can also declare `entrypoints` in `.pipeline/pipeline.yaml` to expose
219
- stable app or CLI names that resolve to workflows or schedule policies. Direct
220
- `--workflow` selection remains available and takes precedence over `--entrypoint`
221
- when both are set.
219
+ Package-owned defaults declare `entrypoints` that expose stable app or CLI names
220
+ resolving to workflows or schedule policies. Direct `--workflow` selection
221
+ remains available and takes precedence over `--entrypoint` when both are set.
222
222
 
223
- The default scaffold includes a full research, red, green, verify, learn
224
- workflow. See `docs/config-architecture.md` for a complete example and the host
225
- support matrix.
223
+ The package defaults include a full research, red, green, verify, learn
224
+ workflow. See `docs/config-architecture.md` for the host support matrix.
226
225
 
227
226
  ### Structural Parallelism
228
227
 
@@ -292,22 +291,45 @@ branches share a base SHA, and merges passing branches into an integration
292
291
  branch in declaration order. It reports merge conflicts; it does not resolve
293
292
  them automatically.
294
293
 
295
- Default profile skills are installed into `.agents/skills` by `pipe init`.
296
- Runtime MCP projection and host-specific isolation policy live in `src/mcp`; see
297
- [`docs/mcp-host-isolation.md`](docs/mcp-host-isolation.md) and
294
+ Default profile skills and generated host resources are installed by
295
+ `pipe init`. Runtime MCP projection and host-specific isolation policy live in
296
+ `src/mcp`; see [`docs/mcp-host-isolation.md`](docs/mcp-host-isolation.md) and
298
297
  [`docs/mcp-gateway.md`](docs/mcp-gateway.md).
299
298
 
299
+ ## OpenCode-First Goal Loop
300
+
301
+ Package defaults run built-in profiles through OpenCode first. Pipeline-owned
302
+ goal state remains authoritative: continuation prompts, stop reasons, verifier
303
+ evidence, acceptance evidence, changed files, and failed gates are stored by the
304
+ pipeline, not inferred from an OpenCode session. A goal is complete only when
305
+ deterministic verifier evidence and acceptance coverage are both present.
306
+
307
+ The curated OpenCode stack generated by package config includes:
308
+
309
+ - project commands, agents, projected skills, explicit permissions, LSP, and the
310
+ singleton `pipeline-gateway` MCP server;
311
+ - `.opencode/plugins/pipeline-goal-context.ts`, a package-owned compaction hook
312
+ that injects current goal-loop context into OpenCode continuation summaries;
313
+ - `@devtheops/opencode-plugin-otel@1.1.0` in `.opencode/opencode.json`;
314
+ - surfaced ecosystem inputs for DCP code, handoff/session capture,
315
+ background-agent delegation, prompt snippets, memory/context helpers, and
316
+ policy hooks.
317
+
318
+ Team mode is generated as an auditable schedule graph. OpenCode subagents can
319
+ execute graph nodes, but dependencies, retries, gates, verifier passes, and
320
+ acceptance evidence stay pipeline-owned.
321
+
300
322
  ## Generated Host Resources
301
323
 
302
- Generate native host files from the YAML config:
324
+ Generate native host files during setup:
303
325
 
304
326
  ```shell
305
- pipe install-commands --host all
327
+ pipe init
306
328
  ```
307
329
 
308
- Generated resources are derived from the three config files; they are not
309
- separate sources of truth. Host resources use exact native agents when the node
310
- runner matches the host. OpenCode also uses native subagents for cross-runner
330
+ Generated resources are derived from package-owned config; they are not separate
331
+ sources of truth. Host resources use exact native agents when the node runner
332
+ matches the host. OpenCode also uses native subagents for cross-runner
311
333
  model-backed nodes when the runner/profile provides an OpenCode-compatible
312
334
  `model` or `host_models.opencode` value. Otherwise generated instructions
313
335
  dispatch to that runner's CLI instead of inventing a host model.
@@ -316,7 +338,7 @@ The installer creates one command surface per configured entrypoint.
316
338
  | Host | Generated files | Invocation |
317
339
  | ----------- | ----------------------------------------------------------------- | ---------------------------------- |
318
340
  | Codex | `.agents/skills/<entrypoint>/SKILL.md`, `.agents/plugins/oisin-pipeline/commands/<entrypoint>.md`, `.agents/plugins/oisin-pipeline/agents/*.md`, `.codex/config.toml` | `$pipe <task>`, `$inspect <task>`, `$epic <task>`, `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
319
- | OpenCode | `.opencode/commands/<entrypoint>.md`, `.opencode/agents/*.md` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
341
+ | OpenCode | `.opencode/commands/<entrypoint>.md`, `.opencode/agents/*.md`, `.opencode/skills/*/SKILL.md`, `.opencode/plugins/*.ts`, `.opencode/opencode.json` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
320
342
  | Kimi | `.kimi/commands/<entrypoint>.md`, `.kimi/agents/*.yaml` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
321
343
  | Pi | `.pi/prompts/<entrypoint>.md` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
322
344
 
@@ -336,8 +358,8 @@ runners:
336
358
 
337
359
  ## Runtime Guarantees
338
360
 
339
- - `pipe run` fails without `.pipeline/pipeline.yaml`,
340
- `.pipeline/profiles.yaml`, and `.pipeline/runners.yaml`.
361
+ - `pipe run` loads package-owned `@oisincoveney/pipeline` config even when the
362
+ repository has no repo-local `.pipeline` config files.
341
363
  - Multi-agent workflows execute as separate agent boundaries; nodes are not
342
364
  merged into one prompt.
343
365
  - Native subagent strategy is preferred when the selected runner can represent
@@ -0,0 +1,18 @@
1
+ interface PipelineCompactionOutput {
2
+ context: string[];
3
+ }
4
+
5
+ export const PipelineGoalContext = async () => ({
6
+ "experimental.session.compacting": (
7
+ _input: unknown,
8
+ output: PipelineCompactionOutput
9
+ ) => {
10
+ output.context.push(
11
+ [
12
+ "## Pipeline Goal Context",
13
+ "Preserve the current task, schedule node, failed gates, verifier evidence, acceptance evidence, changed files, and exact next requirement.",
14
+ "Do not mark the goal complete without deterministic verifier and acceptance evidence.",
15
+ ].join("\n")
16
+ );
17
+ },
18
+ });
@@ -0,0 +1,203 @@
1
+ version: 1
2
+ generated_by: "@oisincoveney/pipeline"
3
+ runtime:
4
+ default_runner: opencode
5
+ compatibility_runners: [codex]
6
+ default_stack_direct: true
7
+ state_authority: pipeline
8
+ official_dependencies:
9
+ - id: "@opencode-ai/plugin"
10
+ package: "@opencode-ai/plugin"
11
+ role: plugin type surface for package-owned OpenCode plugins
12
+ dependency_scope: package-code-when-needed
13
+ source: https://opencode.ai/docs/plugins
14
+ - id: "@opencode-ai/sdk"
15
+ package: "@opencode-ai/sdk"
16
+ role: programmatic OpenCode API access for package-owned integration code
17
+ dependency_scope: package-code-when-needed
18
+ source: https://opencode.ai/docs/ecosystem
19
+ ecosystem_code:
20
+ - id: pipeline-goal-context
21
+ name: pipeline-goal-context
22
+ role: package-owned continuation context plugin for OpenCode compaction hooks
23
+ plugin:
24
+ kind: local
25
+ source_path: defaults/opencode/plugins/pipeline-goal-context.ts
26
+ target_path: .opencode/plugins/pipeline-goal-context.ts
27
+ default_stack: true
28
+ source: https://opencode.ai/docs/plugins
29
+ - id: dcp-code
30
+ name: DCP code
31
+ role: dynamic context pruning for long OpenCode sessions
32
+ default_stack: true
33
+ source: https://github.com/Tarquinen/opencode-dynamic-context-pruning
34
+ - id: opencode-background-agents
35
+ name: opencode-background-agents
36
+ role: async delegation and background-agent context persistence patterns
37
+ default_stack: true
38
+ source: https://github.com/kdcokenny/opencode-background-agents
39
+ - id: opencode-handoff
40
+ name: opencode-handoff
41
+ role: focused continuation and handoff prompt generation
42
+ default_stack: true
43
+ source: https://github.com/joshuadavidthomas/opencode-handoff
44
+ - id: opencode-plugin-otel
45
+ name: opencode-plugin-otel
46
+ package: "@devtheops/opencode-plugin-otel"
47
+ plugin:
48
+ kind: npm
49
+ package: "@devtheops/opencode-plugin-otel@1.1.0"
50
+ role: OpenTelemetry plugin pattern for runtime observability
51
+ default_stack: true
52
+ source: https://www.npmjs.com/package/@devtheops/opencode-plugin-otel
53
+ - id: opencode-snip
54
+ name: opencode-snip
55
+ role: prompt snippet and command-discipline helper patterns
56
+ default_stack: true
57
+ source: https://www.npmjs.com/package/opencode-snip
58
+ - id: opencode-mem
59
+ name: opencode-mem
60
+ role: OpenCode memory projection for durable goal context
61
+ default_stack: true
62
+ source: https://github.com/tickernelz/opencode-mem
63
+ - id: cupcake
64
+ name: cupcake
65
+ role: OpenCode policy enforcement through tool execution hooks
66
+ default_stack: true
67
+ source: https://cupcake.eqtylab.io/getting-started/usage/opencode/
68
+ mcp_backends:
69
+ - id: pipeline-gateway
70
+ locality: project-remote
71
+ required: true
72
+ credentials: [PIPELINE_MCP_GATEWAY_AUTHORIZATION]
73
+ role: singleton MCP server exposed to generated Codex and OpenCode host config
74
+ - id: context7
75
+ name: Context7
76
+ locality: shared-remote
77
+ required: true
78
+ credentials: []
79
+ role: current library documentation and examples
80
+ - id: uidotsh
81
+ locality: shared-remote
82
+ required: true
83
+ credentials: []
84
+ role: package skill and rule resource retrieval
85
+ - id: qdrant
86
+ name: Qdrant
87
+ locality: repo-scoped-remote
88
+ required: true
89
+ credentials: [QDRANT_URL, QDRANT_API_KEY]
90
+ role: repository memory lookup and storage
91
+ - id: fallow
92
+ name: Fallow
93
+ locality: repo-local
94
+ required: false
95
+ credentials: []
96
+ role: dead-code, complexity, duplication, boundary, and runtime coverage analysis
97
+ - id: serena
98
+ name: Serena
99
+ locality: repo-local
100
+ required: true
101
+ credentials: []
102
+ role: repository-local semantic code navigation
103
+ - id: backlog
104
+ name: Backlog
105
+ locality: repo-local
106
+ required: true
107
+ credentials: []
108
+ role: task and ticket state
109
+ - id: github
110
+ name: GitHub
111
+ locality: shared-remote
112
+ required: true
113
+ credentials: [GITHUB_TOKEN]
114
+ role: repository, PR, issue, and release workflow access
115
+ - id: playwright-browser
116
+ name: Playwright/browser
117
+ locality: repo-local
118
+ required: true
119
+ credentials: []
120
+ role: browser automation and frontend verification
121
+ - id: neon
122
+ name: Neon
123
+ locality: shared-remote
124
+ required: true
125
+ credentials: [NEON_API_KEY]
126
+ role: database branch and Postgres environment operations
127
+ skills:
128
+ - id: pipe
129
+ path: .agents/skills/pipe/SKILL.md
130
+ used_by: [orchestrator]
131
+ - id: inspect
132
+ path: .agents/skills/inspect/SKILL.md
133
+ used_by: [pipeline-inspector]
134
+ - id: epic
135
+ path: .agents/skills/epic/SKILL.md
136
+ used_by: [pipeline-epic-router]
137
+ - id: execute
138
+ path: .agents/skills/execute/SKILL.md
139
+ used_by: [pipeline-code-writer]
140
+ - id: research
141
+ path: .agents/skills/research/SKILL.md
142
+ used_by: [pipeline-researcher]
143
+ - id: library-first-development
144
+ path: .agents/skills/library-first-development/SKILL.md
145
+ used_by: [pipeline-researcher, pipeline-code-writer]
146
+ - id: critique
147
+ path: .agents/skills/critique/SKILL.md
148
+ used_by: [pipeline-thermo-nuclear-reviewer]
149
+ - id: verify
150
+ path: .agents/skills/verify/SKILL.md
151
+ used_by: [pipeline-verifier]
152
+ prompts:
153
+ - id: orchestrator
154
+ source: package-default-profile
155
+ used_by: [orchestrator]
156
+ - id: researcher
157
+ source: package-default-profile
158
+ used_by: [pipeline-researcher]
159
+ - id: inspector
160
+ source: package-default-profile
161
+ used_by: [pipeline-inspector]
162
+ - id: schedule-planner
163
+ source: package-default-profile
164
+ used_by: [pipeline-schedule-planner]
165
+ - id: test-writer
166
+ source: package-default-profile
167
+ used_by: [pipeline-test-writer]
168
+ - id: code-writer
169
+ source: package-default-profile
170
+ used_by: [pipeline-code-writer]
171
+ - id: acceptance-reviewer
172
+ source: package-default-profile
173
+ used_by: [pipeline-acceptance-reviewer]
174
+ - id: verifier
175
+ source: package-default-profile
176
+ used_by: [pipeline-verifier]
177
+ host_capabilities:
178
+ agents: true
179
+ subagents: true
180
+ skills: true
181
+ plugins: true
182
+ mcp_servers: true
183
+ lsp: true
184
+ permissions: true
185
+ commands: true
186
+ project_config: true
187
+ sources:
188
+ - label: OpenCode ecosystem
189
+ url: https://opencode.ai/docs/ecosystem
190
+ - label: OpenCode plugins
191
+ url: https://opencode.ai/docs/plugins
192
+ - label: OpenCode agents
193
+ url: https://opencode.ai/docs/agents
194
+ - label: OpenCode skills
195
+ url: https://opencode.ai/docs/skills/
196
+ - label: OpenCode MCP servers
197
+ url: https://opencode.ai/docs/mcp-servers
198
+ - label: OpenCode LSP
199
+ url: https://opencode.ai/docs/lsp/
200
+ - label: awesome-opencode
201
+ url: https://github.com/awesome-opencode/awesome-opencode
202
+ - label: opencode.cafe
203
+ url: https://www.opencode.cafe/
@@ -1,7 +1,6 @@
1
1
  //#region src/commands/pipeline-command.ts
2
2
  const BUILTIN_PIPE_COMMANDS = new Set([
3
3
  "run",
4
- "pipe",
5
4
  "validate",
6
5
  "explain-plan",
7
6
  "doctor",
@@ -12,7 +11,6 @@ const BUILTIN_PIPE_COMMANDS = new Set([
12
11
  ]);
13
12
  function registerConfiguredEntrypointCommands(program, config, runEntrypoint) {
14
13
  const registered = /* @__PURE__ */ new Set();
15
- if (!config) return registered;
16
14
  const reservedCommands = new Set(program.commands.map((command) => command.name()));
17
15
  for (const [id, entrypoint] of Object.entries(config.entrypoints)) {
18
16
  if (reservedCommands.has(id)) continue;