opencode-plugin-flow 3.3.19 → 3.3.20

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/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ the rejected alternatives, and the validation that was run — see
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.3.20] - 2026-06-14
10
+
11
+ Hide the Flow reviewer behind `/flow-review` and `/flow-auto`, keeping direct reviewer selection advisory instead of a confusing session entry point.
12
+
9
13
  ## [3.3.19] - 2026-06-14
10
14
 
11
15
  Ship deslop and UI-quality skills so cleanup and frontend work get evidence-backed rubrics without adding commands, tools, agents, or runtime state.
package/README.md CHANGED
@@ -31,7 +31,7 @@ Add Flow to the `plugin` array in your `opencode.json` (global `~/.config/openco
31
31
 
32
32
  ```json
33
33
  {
34
- "plugin": ["opencode-plugin-flow@3.3.19"]
34
+ "plugin": ["opencode-plugin-flow@3.3.20"]
35
35
  }
36
36
  ```
37
37
 
@@ -47,7 +47,7 @@ On startup the plugin syncs its global skills, commands, and review agent into O
47
47
  ~/.config/opencode/skills/flow-review/SKILL.md # review rubric
48
48
  ~/.config/opencode/skills/flow-ui-quality/SKILL.md # UX/UI quality and visual verification
49
49
  ~/.config/opencode/commands/flow-auto.md # slash command pointers
50
- ~/.config/opencode/agents/flow-reviewer.md # read-only review agent
50
+ ~/.config/opencode/agents/flow-reviewer.md # hidden read-only review subagent
51
51
  ```
52
52
 
53
53
  **Restart OpenCode once after the first install or after an update** so freshly synced skills, commands, and agents are discovered.
@@ -141,7 +141,7 @@ These eight tools are the whole registered surface — the v2 tool-name redirect
141
141
 
142
142
  ### Agents
143
143
 
144
- Flow ships one dedicated subagent: `flow-reviewer`, a read-only reviewer used for fresh-context review passes. Its read-only boundary is enforced by OpenCode's native per-agent permissions, not by prompt text. Everything else runs in your normal agent, guided by the skills.
144
+ Flow ships one dedicated hidden subagent: `flow-reviewer`, a read-only reviewer used behind `/flow-review` and Flow's review gates. Its read-only boundary is enforced by OpenCode's native per-agent permissions, not by prompt text. Start user-facing work with `/flow-auto` or `/flow-review`; everything else runs in your normal agent, guided by the skills.
145
145
 
146
146
  ## What the plugin enforces vs. what skills guide
147
147
 
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{homedir as ge}from"node:os";import{readdir as ce,readFile as de,rm as u,rmdir as le}from"node:fs/promises";import{dirname as ue,join as d,normalize as he,sep as pe}from"node:path";var M={fast:"low",balanced:"medium",deep:"high"},W={"flow-reviewer":{mode:"all",description:"Review Flow work read-only and record a reviewer decision.",prompt:"You are the Flow reviewer. Load the `flow-review` skill, review the requested work read-only, then record your decision with flow_review_record.",reasoningEffort:M.deep,permission:{edit:"deny",bash:"deny",task:{"*":"deny"},"flow_*":"deny",flow_status:"allow",flow_review_record:"allow"}}},V={"flow-plan":{description:"Create, update, or approve a Flow plan",template:"Load the `flow-plan` skill and plan: $ARGUMENTS"},"flow-run":{description:"Run one approved Flow feature",template:"Load the `flow-run` skill and execute the next approved Flow feature. $ARGUMENTS"},"flow-auto":{description:"Drive the Flow loop autonomously until completion or a real blocker",template:"Load the `flow` skill and drive the Flow loop (status, plan, run, review) until completion or a real blocker: $ARGUMENTS"},"flow-status":{description:"Inspect the active Flow session and workspace readiness",template:"Call flow_status (detailed) and report session state, readiness checks, and the suggested next step."},"flow-review":{description:"Run a read-only Flow review with a fresh context",agent:"flow-reviewer",subtask:!0,template:"Load the `flow-review` skill and review: $ARGUMENTS"}},R=["flow-doctor","flow-history","flow-reset","flow-session"];import{createHash as E}from"node:crypto";import{join as g}from"node:path";var A=g(".config","opencode","skills"),m=g(".config","opencode","commands"),I=g(".config","opencode","agents"),v=".flow-skill-version",G="SKILL.md.backup",T=g(".config","opencode","plugins","flow.js"),q=`// Managed by flow-opencode install/uninstall
2
+ import{homedir as ge}from"node:os";import{readdir as ce,readFile as de,rm as u,rmdir as le}from"node:fs/promises";import{dirname as ue,join as d,normalize as he,sep as pe}from"node:path";var M={fast:"low",balanced:"medium",deep:"high"},W={"flow-reviewer":{mode:"subagent",hidden:!0,description:"Internal read-only Flow review subagent. Use /flow-review or /flow-auto.",prompt:"You are the Flow reviewer, a hidden read-only subagent. Load `flow-review`; call flow_status first. If no active compatible Flow session exists, do advisory review only and do not call flow_review_record. After one successful/no-op flow_review_record, report the verdict and stop.",reasoningEffort:M.deep,permission:{edit:"deny",bash:"deny",task:{"*":"deny"},"flow_*":"deny",flow_status:"allow",flow_review_record:"allow"}}},V={"flow-plan":{description:"Create, update, or approve a Flow plan",template:"Load the `flow-plan` skill and plan: $ARGUMENTS"},"flow-run":{description:"Run one approved Flow feature",template:"Load the `flow-run` skill and execute the next approved Flow feature. $ARGUMENTS"},"flow-auto":{description:"Drive the Flow loop autonomously until completion or a real blocker",template:"Load the `flow` skill and drive the Flow loop (status, plan, run, review) until completion or a real blocker: $ARGUMENTS"},"flow-status":{description:"Inspect the active Flow session and workspace readiness",template:"Call flow_status (detailed) and report session state, readiness checks, and the suggested next step."},"flow-review":{description:"Run a read-only Flow review with a fresh context",agent:"flow-reviewer",subtask:!0,template:"Load the `flow-review` skill and review: $ARGUMENTS"}},R=["flow-doctor","flow-history","flow-reset","flow-session"];import{createHash as E}from"node:crypto";import{join as g}from"node:path";var A=g(".config","opencode","skills"),m=g(".config","opencode","commands"),I=g(".config","opencode","agents"),v=".flow-skill-version",G="SKILL.md.backup",T=g(".config","opencode","plugins","flow.js"),q=`// Managed by flow-opencode install/uninstall
3
3
  `,X="flow-opencode-generated-skill",L=`<!-- ${X} `,ee=new RegExp(`^<!-- ${X} name=([a-z0-9]+(?:-[a-z0-9]+)*) version=([0-9]+) hash=sha256:([a-f0-9]{64}) -->$`,"u");function h(e){return E("sha256").update(e,"utf8").digest("hex")}function y(e){let t=e.split(`
4
4
  `),i=t.flatMap((p,K)=>p.startsWith(L)?[K]:[]);if(i.length===0)return{kind:"not_generated"};if(i.length>1)return{kind:"invalid_generated",reason:"duplicate_marker"};let a=i[0];if(a===void 0)return{kind:"not_generated"};let o=t[a];if(o===void 0)return{kind:"invalid_generated",reason:"malformed_marker"};let s=o.match(ee);if(!s)return{kind:"invalid_generated",reason:"malformed_marker"};let[,n,r,c]=s;if(n===void 0||r===void 0||c===void 0)return{kind:"invalid_generated",reason:"malformed_marker"};let l=[...t.slice(0,a),...t.slice(a+1)].join(`
5
5
  `);if(h(l)!==c)return{kind:"invalid_generated",reason:"hash_mismatch"};return{kind:"valid_generated",marker:{name:n,version:r,hash:c}}}var Q="opencode-plugin-flow",P="file=",C="=sha256:";function b(e){let t=new Map;for(let i of e.split(`
@@ -9,7 +9,7 @@ import{homedir as ge}from"node:os";import{readdir as ce,readFile as de,rm as u,r
9
9
  `)}
10
10
 
11
11
  ${e.template}
12
- `}function Z(e){return`${["---",`description: ${JSON.stringify(e.description)}`,`mode: ${e.mode}`,...e.reasoningEffort?[`reasoningEffort: ${e.reasoningEffort}`]:[],...e.permission?ie(e.permission):[],"---"].join(`
12
+ `}function Z(e){return`${["---",`description: ${JSON.stringify(e.description)}`,`mode: ${e.mode}`,...e.hidden===void 0?[]:[`hidden: ${e.hidden}`],...e.reasoningEffort?[`reasoningEffort: ${e.reasoningEffort}`]:[],...e.permission?ie(e.permission):[],"---"].join(`
13
13
  `)}
14
14
 
15
15
  ${e.prompt}