opencode-plugin-flow 3.2.2 → 3.3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.3.0] - 2026-06-13
6
+
7
+ Audit findings must now survive refutation: a new audit rubric for the run lane, and adversarial review of findings reports
8
+
9
+ A real Flow audit session (a `goalMode: review` codebase audit, externally verified finding-by-finding) showed the gap this release closes: six of nine findings held up, and the three that did not all failed the same way — the auditor stopped at the suspicious call site without reading the mitigating path (the backend handler that already enforced one-to-one mapping, the workflow that validated before returning, the effect that already reset the stale state). Every one of those wrong findings cited real code accurately, and every gate passed, because the quality bar for audit deliverables was "findings cite code actually read" — citation accuracy, which wrong findings satisfy just fine.
10
+
11
+ The run lane gains `flow-run/references/audit-rubric.md`, which governs the findings themselves when a feature's deliverable is a findings report. Blocking-severity findings must survive the author's own refutation attempt (trace callers, cross the layer boundary, check surrounding lifecycle guards) and record a "guards checked" line naming the mitigating paths traced and why they fall short — no guards-checked line means the finding is downgraded to advisory. Hypothesized findings ("if the backend ever returns…") are capped at advisory defense-in-depth notes; the review rubric always banned hypothesizing, but that rule lived in the review lane and never reached the lane that writes audits. Reports also state the product's actual deployment model in the header and rate severity within it, so single-user desktop processes stop collecting shared-server severities.
12
+
13
+ The review lane stops citation-checking audit deliverables: `flow-review` now reviews a findings report by attempting to refute every blocking finding and recording a confirmed / refuted / uncertain verdict. A refuted finding — or a blocking finding with no guards-checked line — is a blocking finding against the report itself, so the decision is `needs_fix` and the report sheds it before shipping. The planning example for review-first decomposition raises its validation bar to match.
14
+
15
+ Skill content plus one sync registration (the new reference file is embedded and synced like the others). Bump the pin and restart twice so the re-synced skills are picked up.
16
+
17
+ Not-tested: a live end-to-end audit session under the new rubric; the rubric was validated against the verified audit transcript that motivated it (all three refuted findings fail its checks, all six confirmed ones pass).
18
+
5
19
  ## [3.2.2] - 2026-06-13
6
20
 
7
21
  Critical fix: plugin failed to load on current OpenCode hosts (unbound SDK log method)
package/README.md CHANGED
@@ -29,7 +29,7 @@ Add Flow to the `plugin` array in your `opencode.json` (global `~/.config/openco
29
29
 
30
30
  ```json
31
31
  {
32
- "plugin": ["opencode-plugin-flow@3.2.2"]
32
+ "plugin": ["opencode-plugin-flow@3.3.0"]
33
33
  }
34
34
  ```
35
35
 
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import{homedir as ue}from"node:os";import{readdir as ae,readFile as oe,rm as u,rmdir as se}from"node:fs/promises";import{dirname as ie,join as d,normalize as ne,sep as re}from"node:path";var $={fast:"low",balanced:"medium",deep:"high"},j={"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:$.deep,permission:{edit:"deny",bash:"deny",task:{"*":"deny"},"flow_*":"deny",flow_status:"allow",flow_review_record:"allow"}}},O={"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"}},_=["flow-doctor","flow-history","flow-reset","flow-session"];import{createHash as K}from"node:crypto";import{join as w}from"node:path";var k=w(".config","opencode","skills"),m=w(".config","opencode","commands"),x=w(".config","opencode","agents"),v=".flow-skill-version",E="SKILL.md.backup",A=w(".config","opencode","plugins","flow.js"),R=`// Managed by flow-opencode install/uninstall
3
- `,B="flow-opencode-generated-skill",M=`<!-- ${B} `,C=new RegExp(`^<!-- ${B} name=([a-z0-9]+(?:-[a-z0-9]+)*) version=([0-9]+) hash=sha256:([a-f0-9]{64}) -->$`,"u");function h(e){return K("sha256").update(e,"utf8").digest("hex")}function y(e){let t=e.split(`
4
- `),o=t.flatMap((p,Z)=>p.startsWith(M)?[Z]:[]);if(o.length===0)return{kind:"not_generated"};if(o.length>1)return{kind:"invalid_generated",reason:"duplicate_marker"};let a=o[0];if(a===void 0)return{kind:"not_generated"};let s=t[a];if(s===void 0)return{kind:"invalid_generated",reason:"malformed_marker"};let i=s.match(C);if(!i)return{kind:"invalid_generated",reason:"malformed_marker"};let[,n,r,c]=i;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
- `);if(h(l)!==c)return{kind:"invalid_generated",reason:"hash_mismatch"};return{kind:"valid_generated",marker:{name:n,version:r,hash:c}}}var z="opencode-plugin-flow",N="file=",W="=sha256:";function g(e){let t=new Map;for(let o of e.split(`
6
- `)){if(!o.startsWith(N))continue;let a=o.slice(N.length),s=a.lastIndexOf(W);if(s===-1)continue;let i=a.slice(0,s),n=a.slice(s+W.length);if(i.length>0&&/^[a-f0-9]{64}$/.test(n))t.set(i,n)}return t}function b(e,t,o){let a=new Map;for(let n of e.split(`
7
- `)){let r=n.indexOf("=");if(r===-1)continue;a.set(n.slice(0,r),n.slice(r+1))}let s=a.get("version"),i=a.get("hash");if(a.get("plugin")!==z||a.get("kind")!==t||a.get("name")!==o||!s||!i?.startsWith("sha256:"))return null;return{kind:t,name:o,version:s,hash:i.slice(7)}}function T(e){let t=new Map;for(let i of e.split(`
8
- `)){let n=i.indexOf("=");if(n===-1)continue;t.set(i.slice(0,n),i.slice(n+1))}let o=t.get("plugin"),a=t.get("version");if(o!==z||!a)return null;let s=t.get("hash");return{plugin:o,version:a,hash:s?.startsWith("sha256:")?s.slice(7):null}}import{mkdir as Ye,readFile as D,rm as F,writeFile as He}from"node:fs/promises";import{dirname as Qe,join as V,sep as Xe}from"node:path";function P(e){return`${["---",`description: ${JSON.stringify(e.description)}`,...e.agent?[`agent: ${JSON.stringify(e.agent)}`]:[],...e.subtask===void 0?[]:[`subtask: ${e.subtask}`],"---"].join(`
2
+ import{homedir as ue}from"node:os";import{readdir as ie,readFile as ae,rm as u,rmdir as se}from"node:fs/promises";import{dirname as oe,join as c,normalize as ne,sep as re}from"node:path";var J={fast:"low",balanced:"medium",deep:"high"},j={"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:J.deep,permission:{edit:"deny",bash:"deny",task:{"*":"deny"},"flow_*":"deny",flow_status:"allow",flow_review_record:"allow"}}},W={"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"}},k=["flow-doctor","flow-history","flow-reset","flow-session"];import{createHash as Z}from"node:crypto";import{join as w}from"node:path";var x=w(".config","opencode","skills"),g=w(".config","opencode","commands"),_=w(".config","opencode","agents"),v=".flow-skill-version",E="SKILL.md.backup",A=w(".config","opencode","plugins","flow.js"),R=`// Managed by flow-opencode install/uninstall
3
+ `,B="flow-opencode-generated-skill",$=`<!-- ${B} `,K=new RegExp(`^<!-- ${B} name=([a-z0-9]+(?:-[a-z0-9]+)*) version=([0-9]+) hash=sha256:([a-f0-9]{64}) -->$`,"u");function p(e){return Z("sha256").update(e,"utf8").digest("hex")}function y(e){let t=e.split(`
4
+ `),a=t.flatMap((h,Q)=>h.startsWith($)?[Q]:[]);if(a.length===0)return{kind:"not_generated"};if(a.length>1)return{kind:"invalid_generated",reason:"duplicate_marker"};let i=a[0];if(i===void 0)return{kind:"not_generated"};let s=t[i];if(s===void 0)return{kind:"invalid_generated",reason:"malformed_marker"};let o=s.match(K);if(!o)return{kind:"invalid_generated",reason:"malformed_marker"};let[,n,r,d]=o;if(n===void 0||r===void 0||d===void 0)return{kind:"invalid_generated",reason:"malformed_marker"};let l=[...t.slice(0,i),...t.slice(i+1)].join(`
5
+ `);if(p(l)!==d)return{kind:"invalid_generated",reason:"hash_mismatch"};return{kind:"valid_generated",marker:{name:n,version:r,hash:d}}}var z="opencode-plugin-flow",O="file=",N="=sha256:";function m(e){let t=new Map;for(let a of e.split(`
6
+ `)){if(!a.startsWith(O))continue;let i=a.slice(O.length),s=i.lastIndexOf(N);if(s===-1)continue;let o=i.slice(0,s),n=i.slice(s+N.length);if(o.length>0&&/^[a-f0-9]{64}$/.test(n))t.set(o,n)}return t}function b(e,t,a){let i=new Map;for(let n of e.split(`
7
+ `)){let r=n.indexOf("=");if(r===-1)continue;i.set(n.slice(0,r),n.slice(r+1))}let s=i.get("version"),o=i.get("hash");if(i.get("plugin")!==z||i.get("kind")!==t||i.get("name")!==a||!s||!o?.startsWith("sha256:"))return null;return{kind:t,name:a,version:s,hash:o.slice(7)}}function T(e){let t=new Map;for(let o of e.split(`
8
+ `)){let n=o.indexOf("=");if(n===-1)continue;t.set(o.slice(0,n),o.slice(n+1))}let a=t.get("plugin"),i=t.get("version");if(a!==z||!i)return null;let s=t.get("hash");return{plugin:a,version:i,hash:s?.startsWith("sha256:")?s.slice(7):null}}import{mkdir as He,readFile as D,rm as I,writeFile as Ce}from"node:fs/promises";import{dirname as Qe,join as V,sep as Je}from"node:path";function P(e){return`${["---",`description: ${JSON.stringify(e.description)}`,...e.agent?[`agent: ${JSON.stringify(e.agent)}`]:[],...e.subtask===void 0?[]:[`subtask: ${e.subtask}`],"---"].join(`
9
9
  `)}
10
10
 
11
11
  ${e.template}
@@ -13,7 +13,7 @@ ${e.template}
13
13
  `)}
14
14
 
15
15
  ${e.prompt}
16
- `}function G(){return new Map(Object.entries(O).map(([e,t])=>[e,P(t)]))}function Y(){return new Map(Object.entries(j).map(([e,t])=>[e,ee(t)]))}async function H(e){let t=[],o=[];for(let a of e.names){let s=V(e.root,`${a}.md`),i=V(e.root,`.${a}.flow-version`),n=await L(i),r=n===null?null:b(n,e.kind,a);if(r===null)continue;let c=await L(s);if(c!==null&&h(c)!==r.hash){o.push(s);continue}if(!e.dryRun)await F(s,{force:!0}),await F(i,{force:!0}),await F(`${s}.backup`,{force:!0});t.push(s)}return{removed:t,keptUserEdited:o}}async function L(e){try{return await D(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}function te(e){if(!e)return[];let t=["permission:"];for(let[o,a]of Object.entries(e)){if(typeof a==="string"){t.push(` ${JSON.stringify(o)}: ${JSON.stringify(a)}`);continue}if(a&&typeof a==="object"){t.push(` ${JSON.stringify(o)}:`);for(let[s,i]of Object.entries(a))t.push(` ${JSON.stringify(s)}: ${JSON.stringify(i)}`)}}return t}async function Q({homeDir:e,dryRun:t=!1,logger:o}){let a={removedSkills:[],keptUserEditedSkills:[],removedCommands:[],keptUserEditedCommands:[],removedAgents:[],keptUserEditedAgents:[],removedPreNpmPlugin:null,keptForeignPreNpmPlugin:null},s=d(e,k);for(let c of await le(s)){if(c!=="flow"&&!c.startsWith("flow-"))continue;let l=d(s,c),p=await ce(l);if(p==="foreign")continue;if(p==="user_edited"){a.keptUserEditedSkills.push(l),o?.(`Kept user-edited Flow skill at ${l}; remove it manually if it is no longer needed.`);continue}if(!t)await de(l);a.removedSkills.push(l),o?.(`${t?"Would remove":"Removed"} Flow skill at ${l}.`)}let i=await H({kind:"command",root:d(e,m),names:_,dryRun:t});for(let c of i.removed)a.removedCommands.push(c),o?.(`${t?"Would remove":"Removed"} retired Flow command at ${c}.`);for(let c of i.keptUserEdited)a.keptUserEditedCommands.push(c),o?.(`Kept user-edited Flow command at ${c}; remove it manually if it is no longer needed.`);await U({homeDir:e,dryRun:t,logger:o,kind:"command",root:d(e,m),files:G(),removed:a.removedCommands,keptUserEdited:a.keptUserEditedCommands}),await U({homeDir:e,dryRun:t,logger:o,kind:"agent",root:d(e,x),files:Y(),removed:a.removedAgents,keptUserEdited:a.keptUserEditedAgents});let n=d(e,A),r=await f(n);if(r!==null)if(r.startsWith(R)){if(!t)await u(n,{force:!0});a.removedPreNpmPlugin=n,o?.(`${t?"Would remove":"Removed"} pre-npm Flow plugin copy at ${n}.`)}else a.keptForeignPreNpmPlugin=n,o?.(`Kept ${n}: it is not managed by Flow. Remove it manually if it is a stale Flow copy.`);return o?.('Finally, remove "opencode-plugin-flow" from the plugin array in opencode.json and restart OpenCode.'),a}async function ce(e){let t=d(e,"SKILL.md"),o=await f(t),a=await f(d(e,v)),s=a===null?null:T(a);if(s!==null&&a!==null){for(let[r,c]of g(a)){if(r==="SKILL.md")continue;let l=X(e,r);if(l===null)continue;let p=await f(l);if(p!==null&&h(p)!==c)return"user_edited"}if(o===null)return"pristine";if(s.hash!==null&&h(o)===s.hash)return"pristine";return y(o).kind==="valid_generated"?"pristine":"user_edited"}if(o===null)return"foreign";let i=y(o);if(i.kind==="valid_generated")return"pristine";if(i.kind==="invalid_generated")return"user_edited";return"foreign"}function X(e,t){let o=ne(d(e,...t.split("/")));if(o!==e&&o.startsWith(`${e}${re}`))return o;return null}async function de(e){let t=await f(d(e,v)),o=new Set;if(t!==null)for(let a of g(t).keys()){let s=X(e,a);if(s===null)continue;await u(s,{force:!0}),await u(`${s}.backup`,{force:!0});let i=ie(s);if(i!==e)o.add(i)}await u(d(e,"SKILL.md"),{force:!0}),await u(d(e,v),{force:!0}),await u(d(e,E),{force:!0});for(let a of[...o].sort((s,i)=>i.length-s.length))await I(a);await I(e)}async function I(e){try{await se(e)}catch(t){let o=t.code;if(o!=="ENOENT"&&o!=="ENOTEMPTY")throw t}}async function le(e){try{return(await ae(e,{withFileTypes:!0})).filter((o)=>o.isDirectory()).map((o)=>o.name).sort()}catch(t){if(t.code==="ENOENT")return[];throw t}}async function f(e){try{return await oe(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function U(e){for(let[t,o]of e.files){let a=d(e.root,`${t}.md`),s=d(e.root,`.${t}.flow-version`),i=await f(a),n=await f(s),r=n===null?null:b(n,e.kind,t);if(i===null&&r===null)continue;if(!(r!==null||i===o))continue;if(i!==null&&r!==null&&h(i)!==r.hash){e.keptUserEdited.push(a),e.logger?.(`Kept user-edited Flow ${e.kind} at ${a}; remove it manually if it is no longer needed.`);continue}if(!e.dryRun)await u(a,{force:!0}),await u(s,{force:!0}),await u(`${a}.backup`,{force:!0});e.removed.push(a),e.logger?.(`${e.dryRun?"Would remove":"Removed"} Flow ${e.kind} at ${a}.`)}if(!e.dryRun)await I(e.root)}var q=`opencode-plugin-flow — Flow plugin lifecycle commands
16
+ `}function G(){return new Map(Object.entries(W).map(([e,t])=>[e,P(t)]))}function U(){return new Map(Object.entries(j).map(([e,t])=>[e,ee(t)]))}async function Y(e){let t=[],a=[];for(let i of e.names){let s=V(e.root,`${i}.md`),o=V(e.root,`.${i}.flow-version`),n=await L(o),r=n===null?null:b(n,e.kind,i);if(r===null)continue;let d=await L(s);if(d!==null&&p(d)!==r.hash){a.push(s);continue}if(!e.dryRun)await I(s,{force:!0}),await I(o,{force:!0}),await I(`${s}.backup`,{force:!0});t.push(s)}return{removed:t,keptUserEdited:a}}async function L(e){try{return await D(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}function te(e){if(!e)return[];let t=["permission:"];for(let[a,i]of Object.entries(e)){if(typeof i==="string"){t.push(` ${JSON.stringify(a)}: ${JSON.stringify(i)}`);continue}if(i&&typeof i==="object"){t.push(` ${JSON.stringify(a)}:`);for(let[s,o]of Object.entries(i))t.push(` ${JSON.stringify(s)}: ${JSON.stringify(o)}`)}}return t}async function H({homeDir:e,dryRun:t=!1,logger:a}){let i={removedSkills:[],keptUserEditedSkills:[],removedCommands:[],keptUserEditedCommands:[],removedAgents:[],keptUserEditedAgents:[],removedPreNpmPlugin:null,keptForeignPreNpmPlugin:null},s=c(e,x);for(let d of await le(s)){if(d!=="flow"&&!d.startsWith("flow-"))continue;let l=c(s,d),h=await de(l);if(h==="foreign")continue;if(h==="user_edited"){i.keptUserEditedSkills.push(l),a?.(`Kept user-edited Flow skill at ${l}; remove it manually if it is no longer needed.`);continue}if(!t)await ce(l);i.removedSkills.push(l),a?.(`${t?"Would remove":"Removed"} Flow skill at ${l}.`)}let o=await Y({kind:"command",root:c(e,g),names:k,dryRun:t});for(let d of o.removed)i.removedCommands.push(d),a?.(`${t?"Would remove":"Removed"} retired Flow command at ${d}.`);for(let d of o.keptUserEdited)i.keptUserEditedCommands.push(d),a?.(`Kept user-edited Flow command at ${d}; remove it manually if it is no longer needed.`);await X({homeDir:e,dryRun:t,logger:a,kind:"command",root:c(e,g),files:G(),removed:i.removedCommands,keptUserEdited:i.keptUserEditedCommands}),await X({homeDir:e,dryRun:t,logger:a,kind:"agent",root:c(e,_),files:U(),removed:i.removedAgents,keptUserEdited:i.keptUserEditedAgents});let n=c(e,A),r=await f(n);if(r!==null)if(r.startsWith(R)){if(!t)await u(n,{force:!0});i.removedPreNpmPlugin=n,a?.(`${t?"Would remove":"Removed"} pre-npm Flow plugin copy at ${n}.`)}else i.keptForeignPreNpmPlugin=n,a?.(`Kept ${n}: it is not managed by Flow. Remove it manually if it is a stale Flow copy.`);return a?.('Finally, remove "opencode-plugin-flow" from the plugin array in opencode.json and restart OpenCode.'),i}async function de(e){let t=c(e,"SKILL.md"),a=await f(t),i=await f(c(e,v)),s=i===null?null:T(i);if(s!==null&&i!==null){for(let[r,d]of m(i)){if(r==="SKILL.md")continue;let l=C(e,r);if(l===null)continue;let h=await f(l);if(h!==null&&p(h)!==d)return"user_edited"}if(a===null)return"pristine";if(s.hash!==null&&p(a)===s.hash)return"pristine";return y(a).kind==="valid_generated"?"pristine":"user_edited"}if(a===null)return"foreign";let o=y(a);if(o.kind==="valid_generated")return"pristine";if(o.kind==="invalid_generated")return"user_edited";return"foreign"}function C(e,t){let a=ne(c(e,...t.split("/")));if(a!==e&&a.startsWith(`${e}${re}`))return a;return null}async function ce(e){let t=await f(c(e,v)),a=new Set;if(t!==null)for(let i of m(t).keys()){let s=C(e,i);if(s===null)continue;await u(s,{force:!0}),await u(`${s}.backup`,{force:!0});let o=oe(s);if(o!==e)a.add(o)}await u(c(e,"SKILL.md"),{force:!0}),await u(c(e,v),{force:!0}),await u(c(e,E),{force:!0});for(let i of[...a].sort((s,o)=>o.length-s.length))await F(i);await F(e)}async function F(e){try{await se(e)}catch(t){let a=t.code;if(a!=="ENOENT"&&a!=="ENOTEMPTY")throw t}}async function le(e){try{return(await ie(e,{withFileTypes:!0})).filter((a)=>a.isDirectory()).map((a)=>a.name).sort()}catch(t){if(t.code==="ENOENT")return[];throw t}}async function f(e){try{return await ae(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function X(e){for(let[t,a]of e.files){let i=c(e.root,`${t}.md`),s=c(e.root,`.${t}.flow-version`),o=await f(i),n=await f(s),r=n===null?null:b(n,e.kind,t);if(o===null&&r===null)continue;if(!(r!==null||o===a))continue;if(o!==null&&r!==null&&p(o)!==r.hash){e.keptUserEdited.push(i),e.logger?.(`Kept user-edited Flow ${e.kind} at ${i}; remove it manually if it is no longer needed.`);continue}if(!e.dryRun)await u(i,{force:!0}),await u(s,{force:!0}),await u(`${i}.backup`,{force:!0});e.removed.push(i),e.logger?.(`${e.dryRun?"Would remove":"Removed"} Flow ${e.kind} at ${i}.`)}if(!e.dryRun)await F(e.root)}var q=`opencode-plugin-flow — Flow plugin lifecycle commands
17
17
 
18
18
  Usage:
19
19
  bunx opencode-plugin-flow uninstall [--dry-run]
@@ -26,10 +26,10 @@ Commands:
26
26
 
27
27
  Options:
28
28
  --dry-run Show what would be removed without deleting anything
29
- --help Show this message`;function J(e){process.stdout.write(`${e}
29
+ --help Show this message`;function M(e){process.stdout.write(`${e}
30
30
  `)}function S(e){process.stderr.write(`${e}
31
- `)}async function pe(e){let t=[...e];if(t.length===0||t.includes("--help")||t.includes("-h"))return J(q),0;let o=t.shift();if(o!=="uninstall")return S(`Unknown command: ${o}
31
+ `)}async function he(e){let t=[...e];if(t.length===0||t.includes("--help")||t.includes("-h"))return M(q),0;let a=t.shift();if(a!=="uninstall")return S(`Unknown command: ${a}
32
32
 
33
- ${q}`),1;let a=!1;for(let s of t){if(s==="--dry-run"){a=!0;continue}return S(`Unknown argument: ${s}
33
+ ${q}`),1;let i=!1;for(let s of t){if(s==="--dry-run"){i=!0;continue}return S(`Unknown argument: ${s}
34
34
 
35
- ${q}`),1}return await Q({homeDir:process.env.HOME??ue(),dryRun:a,logger:J}),0}try{process.exitCode=await pe(process.argv.slice(2))}catch(e){S(e instanceof Error?e.message:String(e)),process.exitCode=1}
35
+ ${q}`),1}return await H({homeDir:process.env.HOME??ue(),dryRun:i,logger:M}),0}try{process.exitCode=await he(process.argv.slice(2))}catch(e){S(e instanceof Error?e.message:String(e)),process.exitCode=1}