@jawache/flow 0.1.1 → 0.1.2

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/dist/flow.mjs CHANGED
@@ -1,39 +1,39 @@
1
1
  #!/usr/bin/env node
2
- import{existsSync as Ni,readFileSync as _i}from"node:fs";import{registerHooks as Fi,stripTypeScriptTypes as Gi}from"node:module";import{fileURLToPath as Ii,pathToFileURL as Bi}from"node:url";import{dirname as Di,join as Li,resolve as Kn}from"node:path";var me="0.1.1";function ne(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ye(e){let n=[],t="",r=()=>{t!==""&&n.push({kind:"literal",text:t}),t=""};for(let o=0;o<e.length;o++){let s=e[o];if(s==="*")r(),e[o+1]==="*"?(n.push({kind:"globstar"}),o++,e[o+1]==="/"&&o++):n.push({kind:"star"});else if(s==="?")r(),n.push({kind:"single"});else if(s==="{"){let i=e.indexOf("}",o);if(i===-1){t+=s;continue}r(),n.push({kind:"options",options:e.slice(o+1,i).split(",")}),o=i}else t+=s??""}return r(),n}function Qe(e){switch(e.kind){case"literal":return ne(e.text);case"star":return"[^/]*";case"globstar":return".*";case"single":return"[^/]";case"options":return`(${e.options.map(ne).join("|")})`}}function Qr(e){return new RegExp(`^${Ye(e).map(Qe).join("")}$`)}function Zr(e,n){return Qr(n).test(e)}function j(e,n){return(n||[]).some(t=>Zr(e,t))}function Xr(e){let n=e.includes("/")?e.slice(0,e.lastIndexOf("/")):".",t=e.slice(e.lastIndexOf("/")+1),r=t.lastIndexOf("."),o=r>0?t.slice(0,r):t,s=n==="."?o:`${n}/${o}`;return{dir:n,base:t,name:o,path:s}}function Ze(e,n){let t=Xr(n);return e.replace(/\{(dir|base|name|path)\}/g,(r,o)=>t[o])}var et={write:["edit"],command:["edit","commit"],commit:["commit"],delete:["delete"],"turn-end":["turn"]},eo=Object.keys(et),no=["session","touch","command","turn-end"];function to(e){let n=[];for(let t of e)for(let r of et[t])n.includes(r)||n.push(r);return n}function en(e){return eo.includes(e)}function nn(e){return no.includes(e)}var tn=["write","delete","commit","touch"];function ro(e){return tn.includes(e)}var nt=[...tn,"command"];function oo(e,n){return e==="breadcrumb"?nt.includes(n):ro(n)}var so=Symbol.for("flow.category");function Xe(e,n){if(!(typeof e!="object"||e===null))return e[n]}function rn(e){return Xe(e,so)===!0}var Ee={ok:()=>({ok:!0}),fail:e=>e===void 0?{ok:!1}:{ok:!1,detail:e}};function Ce(e,n,t){return{moment:e,...n,exec:r=>t.exec(r),fs:t.fs,git:t.git,ok:Ee.ok,fail:Ee.fail}}var tt=Symbol.for("flow.settings");function N(e){return n=>{let t=e(n);return Object.defineProperty(t,tt,{value:n,enumerable:!1,configurable:!0}),t}}function io(e){return e===void 0?void 0:e[tt]}function ao(e){return e?(e.pass?.length??0)+(e.block?.length??0)>0:!1}function Oe(e,n,t){let r=e.exec??{},o=e.fs??{};return{exec:s=>{let i=Object.hasOwn(r,s)?s:Object.keys(r).find(d=>s.includes(d)),a=i===void 0?void 0:r[i];return a===void 0?(t.push({kind:"exec",asked:s}),Promise.resolve({stdout:"",stderr:"",code:0})):Promise.resolve({stdout:a.stdout??"",stderr:a.stderr??"",code:a.code??0})},fs:{exists:s=>Promise.resolve(Object.hasOwn(o,s)),read:s=>{let i=o[s];return i===void 0?(t.push({kind:"read",asked:s}),Promise.resolve("")):Promise.resolve(i)}},git:{diff:()=>Promise.resolve(e.gitDiff??""),stagedFiles:()=>Promise.resolve([...n??e.staged??[]])}}}function q(e,n){return!(e.on&&!j(n,e.on)||e.ignore&&j(n,e.ignore))}var lo=["at","for","on","ignore","check","message","disabled","test","description"],co=["at","for","on","ignore","text","file","disabled","description"];function uo(e){let n=Xe(Xe(e,"spec"),"kind");return n==="guardrail"||n==="breadcrumb"}function Xn(e,n,t){let r={};for(let o of Object.keys(e))r[o]=t?.[o]??"pack";for(let o of Object.keys(n))r[o]="override";return{spec:{...e,...n},source:r}}function te(e){return[`flow: the config will not load \u2014 ${e.length} refusal${e.length===1?"":"s"}.`,...e.map(n=>` ${n.code}: ${n.detail}`)].join(`
3
- `)}function ue(e){let n=[],t=[],r=new Map;for(let o of e.bindings){if(o.kind!=="pack")continue;if(!o.pack||o.pack.name===""){n.push({code:"not-a-pack",entry:"",detail:"A `pack(\u2026)` line was given a value that no `definePack` ever made. Import the pack's default export, not one of its entries."});continue}let{name:s,build:i,takesParams:a}=o.pack;if(a&&!o.hasParams){n.push({code:"missing-parameter",entry:s,detail:`The pack \`${s}\` declares parameters and was bound without any \u2014 write \`pack(${s}, { \u2026 })\`. Which fields it needs is stated by its factory's type.`});continue}for(let{key:d,spec:l}of rt(i(o.params))){let c={id:`${s}.${d}`,pack:s,key:d,...Xn(l,{})};if(r.get(c.id)){n.push({code:"duplicate-id",entry:c.id,detail:`Two entries claim the id \`${c.id}\`. An id is its property name inside its pack, so this is one pack bound twice, or two packs sharing a name.`});continue}r.set(c.id,c),t.push(c)}}for(let o of e.bindings){if(o.kind!=="override")continue;let s=`${o.ref.pack}.${o.ref.id}`,i=r.get(s);if(!i){n.push({code:"unknown-entry",entry:s,detail:`\`override(${s})\` names an entry no bound pack has. Bind the pack it lives in, or correct the reference.`});continue}let a=Xn(i.spec,o.spoken,i.source);i.spec=a.spec,i.source=a.source}for(let o of t)n.push(...fo(o));return n.length>0?{ok:!1,refusals:n}:{ok:!0,entries:t.map(o=>({id:o.id,pack:o.pack,key:o.key,spec:o.spec,source:o.source,categories:(o.spec.for??[]).map(s=>s.name),phases:o.spec.kind==="guardrail"?to(o.spec.at??[]):[],settings:o.spec.kind==="guardrail"?io(o.spec.check):void 0}))}}function rt(e,n=[]){let t=[];for(let[r,o]of Object.entries(e))uo(o)?t.push({key:[...n,r].join("."),spec:o.spec}):typeof o=="object"&&o!==null&&t.push(...rt(o,[...n,r]));return t}function fo(e){let{id:n,spec:t}=e,r=[],o=(g,m)=>r.push({code:g,entry:n,detail:m}),s=t.kind==="guardrail"?lo:co,i=Object.keys(t).filter(g=>g!=="kind"&&!s.includes(g));i.length>0&&o("unknown-key",`\`${n}\` carries ${i.map(g=>`\`${g}\``).join(", ")}, which the ${t.kind} grammar does not have. It is closed: ${s.join(" \xB7 ")}.`);let a=t.at??[],d=t.kind==="guardrail"?en:nn,l=a.filter(g=>!d(g));if(l.length>0&&o("unknown-moment",`\`${n}\` fires at ${l.map(g=>`\`${g}\``).join(", ")}, which is not a moment a ${t.kind} has a rail for.`),(t.for??[]).some(g=>!rn(g))&&o("undeclared-category",`\`${n}\` is scoped with \`.for(\u2026)\` to something \`defineCategory\` never made. A category is a value with its recognizer aboard \u2014 import the one you mean.`),t.disabled)return r;let u=[];return a.length===0&&u.push(".at(\u2026)"),t.kind==="guardrail"?(t.check||u.push(".check(\u2026)"),t.message===void 0&&u.push(".message(\u2026)")):t.text===void 0&&t.file===void 0&&u.push(".text(\u2026) or .file(\u2026)"),u.length>0&&o("missing-mandatory",`\`${n}\` never said ${u.join(" and ")}. Nothing in this grammar defaults \u2014 an absent key is absent, not a fallback.`),((t.on?.length??0)>0||(t.ignore?.length??0)>0)&&a.length>0&&!a.some(g=>oo(t.kind,g))&&o("dead-scope",`\`${n}\` narrows by path but fires only at ${a.map(g=>`\`${g}\``).join(", ")}, which name no subject to narrow \u2014 its \`on\`/\`ignore\` would be read by nothing. Drop the scope, or add a moment that carries one (${(t.kind==="breadcrumb"?nt:tn).join(" \xB7 ")}).`),t.kind==="guardrail"&&!ao(t.test)&&o("no-cases",`\`${n}\` carries no cases. A rule declares what must pass it and what it must block (\`.test({ pass, block })\`) \u2014 a fence whose block-case was never written is a fence nothing proves is alive.`),r}var fe=class extends Error{refusals;constructor(n){super(te(n)),this.name="FlowConfigError",this.refusals=n}};function ot(e){if(e.ok)return e.entries;throw new fe(e.refusals)}function J(e,n,t=" \xB7 "){return n.length===0?e.ok():e.fail(n.join(t))}function oe(e){return e.file??{path:"",content:""}}function go(e,n){let t=e.split(`
4
- `),r=[];for(let o of n){let s=new RegExp(o);t.forEach((i,a)=>{s.test(i)&&r.push({pattern:o,line:a+1})})}return r}var na=N(e=>n=>{let t=go(oe(n).content,e.ban);return J(n,t.map(r=>`line ${r.line}: matches /${r.pattern}/`))}),ta=N(e=>n=>{let t=n.command??"",r=e.ban.filter(o=>new RegExp(o).test(t));return J(n,r.map(o=>`matches banned /${o}/`))});var ra=["You are recording prose through a shell command, and a backtick inside a DOUBLE-quoted argument is not Markdown \u2014 the shell RUNS it and splices its output into your text before the command ever sees it.","On an append-only record there is no undo: no amend, no redact. And once the binary has argv the splice has already happened, so this is the only moment it can be caught.","Fix: SINGLE-quote the argument (backticks are literal there), or feed the prose on stdin with a QUOTED heredoc \u2014 `git commit -F -` plus `<<'EOF'`, which this rule treats as safe.","ALREADY single-quoted and still blocked? Then your PROSE carries an unbalanced double quote before the backtick, and the matcher cannot tell that quote from a real open argument. Nothing would splice \u2014 this one is the rule's cost, not your mistake. Balance the quote, drop it, or use the heredoc; do not go back to double quotes to make it pass."].join(`
5
- `),oa=N(e=>async n=>{let{path:t}=oe(n);return e.existingOnly===!0?n.moment!=="delete"&&!await n.fs.exists(t)?n.ok():n.fail(`'${t}' is append-only \u2014 an existing file here is history and may not be edited or deleted (adding a new one is fine)`):n.fail(`'${t}' is a protected path (do not edit directly)`)}),sa=N(e=>async n=>{let t=Ze(e.sibling,oe(n).path);return await n.fs.exists(t)?n.ok():n.fail(`required sibling missing: ${t}`)}),po=/\.(ts|tsx|mts|cts|js|mjs|cjs|jsx)$/;function yo(e,n){let t=e.replace(/\\/g,"/"),r=n.root.replace(/^\/+|\/+$/g,"")+"/",o=t.indexOf(r);if(o===-1)return{ok:!0};let s=t.slice(o+r.length);if(n.folders?.length){let c=s.split("/")[0]??"",u=c.replace(/\.[^.]+$/,"");if(c!==""&&!n.folders.includes(c)&&!n.folders.includes(u))return{ok:!1,tier:"folder",found:c}}if(!n.allow.length)return{ok:!0};let i=po.exec(t);if(!i)return{ok:!0};if(t.endsWith(".d.ts"))return{ok:!0};if(!s.includes("/"))return{ok:!0};let d=s.slice(s.lastIndexOf("/")+1).slice(0,-i[0].length);return(d.endsWith(".test")?d.slice(0,-5)!==(n.thinking??""):!n.allow.includes(d))?{ok:!1,tier:"filename"}:{ok:!0}}function mo(e,n,t){return e.ok?"":e.tier==="folder"?`'${e.found}' is not one of the names ${t.root}/ may hold: ${t.folders?.join(" \xB7 ")??""} (found ${n})`:`non-canonical file in a ${t.root} feature folder: ${n} (allowed: ${t.allow.join(" \xB7 ")}${t.thinking===void 0?"":` \u2014 only ${t.thinking} may carry a .test sibling`})`}var ia=N(e=>n=>{let{path:t}=oe(n),r=yo(t,e);return r.ok?n.ok():n.fail(mo(r,t,e))});function ho(e,n){let t=e;for(let r of(n??"").split(".").filter(Boolean)){if(t==null||typeof t!="object"||!(r in t))return{found:!1};t=t[r]}return{found:!0,value:t}}function ko(e,n){let t=[],{path:r}=n,o=ho(e,r);if(!o.found)return n.required===!0&&t.push(`"${r}" is missing (required)`),t;let s=o.value;if(n.keysPrefixedWith!==void 0){if(!s||typeof s!="object")return t;for(let i of Object.keys(s))i.startsWith(n.keysPrefixedWith)||t.push(`"${r}.${i}" must be prefixed "${n.keysPrefixedWith}"`)}return"equals"in n&&JSON.stringify(s)!==JSON.stringify(n.equals)&&t.push(`"${r}" must equal ${JSON.stringify(n.equals)} (is ${JSON.stringify(s)})`),n.matches!==void 0&&!new RegExp(n.matches).test(String(s))&&t.push(`"${r}" (${JSON.stringify(s)}) must match /${n.matches}/`),t}function bo(e,n){let t;try{t=JSON.parse(e)}catch{return[]}return n.flatMap(r=>ko(t,r))}var aa=N(e=>n=>J(n,bo(oe(n).content,e.assert)));function wo(e,n){return e.filter(t=>!new RegExp(`\\b${ne(t)}\\b`).test(n))}async function xo(e){let{parse:n,Lang:t}=await import("@ast-grep/napi"),r=n(t.Tsx,e).root(),o=new Set;for(let s of["export function $N($$$) { $$$ }","export class $N { $$$ }","export const $N = $V"])for(let i of r.findAll(s)){let a=i.getMatch("N");a&&o.add(a.text())}return[...o]}var da=N(e=>async n=>{let{path:t,content:r}=oe(n),o=Ze(e.sibling,t);if(!await n.fs.exists(o))return n.fail(`sibling test not found: ${o}`);let s=await n.fs.read(o),i=wo(await xo(r),s);return J(n,i.map(a=>`exported '${a}' is never referenced in ${o}`))});async function at(e){return e.staged?e.staged:e.git.stagedFiles()}function So(e,n){let t=[];for(let r of n)e.some(o=>j(o,r.if))&&(e.some(o=>j(o,r.thenAny))||t.push(`${r.if.join(", ")} changed but none of [${r.thenAny.join(", ")}] did in the same commit`));return t}var la=N(e=>async n=>J(n,So(await at(n),e.groups))),Ae=new Set([";","&&","||","|","&","|&",`
6
- `]),Ro=new Set(["-C","-c","--git-dir","--work-tree","--namespace","--exec-path","--config-env"]);function $o(e,n){for(let t=n;t<e.length;t++){if(e[t]==="\\"){t++;continue}if(e[t]==='"')return t}return-1}function Me(e){let n=e,t=[],r="",o=!1,s=0,i=()=>{o&&t.push(r),r="",o=!1};for(;s<n.length;){let a=n[s];if(a==="'"||a==='"'){let d=a==="'"?n.indexOf("'",s+1):$o(n,s+1);if(d===-1)return null;r+=a==='"'?n.slice(s+1,d).replace(/\\(["\\$`])/g,"$1"):n.slice(s+1,d),o=!0,s=d+1}else if(a==="\\"&&s+1<n.length)r+=n[s+1],o=!0,s+=2;else if(a===`
2
+ import{existsSync as Li,readFileSync as Wi}from"node:fs";import{registerHooks as Hi,stripTypeScriptTypes as Ui}from"node:module";import{fileURLToPath as Ki,pathToFileURL as Vi}from"node:url";import{dirname as qi,join as Ji,resolve as Vn}from"node:path";var me="0.1.2";function ne(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function et(e){return e.startsWith("^")||e.includes("(?")||e.includes("|")||e.endsWith("$")}function Qe(e){let n=[],t="",r=()=>{t!==""&&n.push({kind:"literal",text:t}),t=""};for(let o=0;o<e.length;o++){let s=e[o];if(s==="*")r(),e[o+1]==="*"?(n.push({kind:"globstar"}),o++,e[o+1]==="/"&&o++):n.push({kind:"star"});else if(s==="?")r(),n.push({kind:"single"});else if(s==="{"){let i=e.indexOf("}",o);if(i===-1){t+=s;continue}r(),n.push({kind:"options",options:e.slice(o+1,i).split(",")}),o=i}else t+=s??""}return r(),n}function Ze(e){switch(e.kind){case"literal":return ne(e.text);case"star":return"[^/]*";case"globstar":return".*";case"single":return"[^/]";case"options":return`(${e.options.map(ne).join("|")})`}}function to(e){return new RegExp(`^${Qe(e).map(Ze).join("")}$`)}function ro(e,n){return to(n).test(e)}function M(e,n){return(n||[]).some(t=>ro(e,t))}function oo(e){let n=e.includes("/")?e.slice(0,e.lastIndexOf("/")):".",t=e.slice(e.lastIndexOf("/")+1),r=t.lastIndexOf("."),o=r>0?t.slice(0,r):t,s=n==="."?o:`${n}/${o}`;return{dir:n,base:t,name:o,path:s}}function Xe(e,n){let t=oo(n);return e.replace(/\{(dir|base|name|path)\}/g,(r,o)=>t[o])}var tt={write:["edit"],command:["edit","commit"],commit:["commit"],delete:["delete"],"turn-end":["turn"]},so=Object.keys(tt),io=["session","touch","command","turn-end"];function ao(e){let n=[];for(let t of e)for(let r of tt[t])n.includes(r)||n.push(r);return n}function nn(e){return so.includes(e)}function tn(e){return io.includes(e)}var rn=["write","delete","commit","touch"];function lo(e){return rn.includes(e)}var rt=[...rn,"command"];function co(e,n){return e==="breadcrumb"?rt.includes(n):lo(n)}var uo=Symbol.for("flow.category");function en(e,n){if(!(typeof e!="object"||e===null))return e[n]}function on(e){return en(e,uo)===!0}var Ee={ok:()=>({ok:!0}),fail:e=>e===void 0?{ok:!1}:{ok:!1,detail:e}};function Ce(e,n,t){return{moment:e,...n,exec:r=>t.exec(r),fs:t.fs,git:t.git,ok:Ee.ok,fail:Ee.fail}}var ot=Symbol.for("flow.settings"),st=Symbol.for("flow.faults");function it(e,n){return n.length>0&&Object.defineProperty(e,st,{value:n,enumerable:!1,configurable:!0}),e}function fo(e){if(e===void 0)return[];let n=e[st];return Array.isArray(n)?n:[]}function N(e){return n=>{let t=e(n);return Object.defineProperty(t,ot,{value:n,enumerable:!1,configurable:!0}),t}}function go(e){return e===void 0?void 0:e[ot]}function po(e){return e?(e.pass?.length??0)+(e.block?.length??0)>0:!1}function Oe(e,n,t){let r=e.exec??{},o=e.fs??{};return{exec:s=>{let i=Object.hasOwn(r,s)?s:Object.keys(r).find(d=>s.includes(d)),a=i===void 0?void 0:r[i];return a===void 0?(t.push({kind:"exec",asked:s}),Promise.resolve({stdout:"",stderr:"",code:0})):Promise.resolve({stdout:a.stdout??"",stderr:a.stderr??"",code:a.code??0})},fs:{exists:s=>Promise.resolve(Object.hasOwn(o,s)),read:s=>{let i=o[s];return i===void 0?(t.push({kind:"read",asked:s}),Promise.resolve("")):Promise.resolve(i)}},git:{diff:()=>Promise.resolve(e.gitDiff??""),stagedFiles:()=>Promise.resolve([...n??e.staged??[]])}}}function q(e,n){return!(e.on&&!M(n,e.on)||e.ignore&&M(n,e.ignore))}var yo=["at","for","on","ignore","check","message","disabled","test","description"],mo=["at","for","on","ignore","text","file","disabled","description"];function ho(e){let n=en(en(e,"spec"),"kind");return n==="guardrail"||n==="breadcrumb"}function nt(e,n,t){let r={};for(let o of Object.keys(e))r[o]=t?.[o]??"pack";for(let o of Object.keys(n))r[o]="override";return{spec:{...e,...n},source:r}}function te(e){return[`flow: the config will not load \u2014 ${e.length} refusal${e.length===1?"":"s"}.`,...e.map(n=>` ${n.code}: ${n.detail}`)].join(`
3
+ `)}function ue(e){let n=[],t=[],r=new Map;for(let o of e.bindings){if(o.kind!=="pack")continue;if(!o.pack||o.pack.name===""){n.push({code:"not-a-pack",entry:"",detail:"A `pack(\u2026)` line was given a value that no `definePack` ever made. Import the pack's default export, not one of its entries."});continue}let{name:s,build:i,takesParams:a}=o.pack;if(a&&!o.hasParams){n.push({code:"missing-parameter",entry:s,detail:`The pack \`${s}\` declares parameters and was bound without any \u2014 write \`pack(${s}, { \u2026 })\`. Which fields it needs is stated by its factory's type.`});continue}for(let{key:d,spec:l}of at(i(o.params))){let c={id:`${s}.${d}`,pack:s,key:d,...nt(l,{})};if(r.get(c.id)){n.push({code:"duplicate-id",entry:c.id,detail:`Two entries claim the id \`${c.id}\`. An id is its property name inside its pack, so this is one pack bound twice, or two packs sharing a name.`});continue}r.set(c.id,c),t.push(c)}}for(let o of e.bindings){if(o.kind!=="override")continue;let s=`${o.ref.pack}.${o.ref.id}`,i=r.get(s);if(!i){n.push({code:"unknown-entry",entry:s,detail:`\`override(${s})\` names an entry no bound pack has. Bind the pack it lives in, or correct the reference.`});continue}let a=nt(i.spec,o.spoken,i.source);i.spec=a.spec,i.source=a.source}for(let o of t)n.push(...ko(o));return n.length>0?{ok:!1,refusals:n}:{ok:!0,entries:t.map(o=>({id:o.id,pack:o.pack,key:o.key,spec:o.spec,source:o.source,categories:(o.spec.for??[]).map(s=>s.name),phases:o.spec.kind==="guardrail"?ao(o.spec.at??[]):[],settings:o.spec.kind==="guardrail"?go(o.spec.check):void 0}))}}function at(e,n=[]){let t=[];for(let[r,o]of Object.entries(e))ho(o)?t.push({key:[...n,r].join("."),spec:o.spec}):typeof o=="object"&&o!==null&&t.push(...at(o,[...n,r]));return t}function ko(e){let{id:n,spec:t}=e,r=[],o=(g,m)=>r.push({code:g,entry:n,detail:m}),s=t.kind==="guardrail"?yo:mo,i=Object.keys(t).filter(g=>g!=="kind"&&!s.includes(g));i.length>0&&o("unknown-key",`\`${n}\` carries ${i.map(g=>`\`${g}\``).join(", ")}, which the ${t.kind} grammar does not have. It is closed: ${s.join(" \xB7 ")}.`);let a=t.at??[],d=t.kind==="guardrail"?nn:tn,l=a.filter(g=>!d(g));if(l.length>0&&o("unknown-moment",`\`${n}\` fires at ${l.map(g=>`\`${g}\``).join(", ")}, which is not a moment a ${t.kind} has a rail for.`),(t.for??[]).some(g=>!on(g))&&o("undeclared-category",`\`${n}\` is scoped with \`.for(\u2026)\` to something \`defineCategory\` never made. A category is a value with its recognizer aboard \u2014 import the one you mean.`),t.disabled)return r;let u=[];a.length===0&&u.push(".at(\u2026)"),t.kind==="guardrail"?(t.check||u.push(".check(\u2026)"),t.message===void 0&&u.push(".message(\u2026)")):t.text===void 0&&t.file===void 0&&u.push(".text(\u2026) or .file(\u2026)"),u.length>0&&o("missing-mandatory",`\`${n}\` never said ${u.join(" and ")}. Nothing in this grammar defaults \u2014 an absent key is absent, not a fallback.`),((t.on?.length??0)>0||(t.ignore?.length??0)>0)&&a.length>0&&!a.some(g=>co(t.kind,g))&&o("dead-scope",`\`${n}\` narrows by path but fires only at ${a.map(g=>`\`${g}\``).join(", ")}, which name no subject to narrow \u2014 its \`on\`/\`ignore\` would be read by nothing. Drop the scope, or add a moment that carries one (${(t.kind==="breadcrumb"?rt:rn).join(" \xB7 ")}).`),t.kind==="guardrail"&&!po(t.test)&&o("no-cases",`\`${n}\` carries no cases. A rule declares what must pass it and what it must block (\`.test({ pass, block })\`) \u2014 a fence whose block-case was never written is a fence nothing proves is alive.`);for(let g of fo(t.kind==="guardrail"?t.check:void 0))o("bad-check-options",`\`${n}\` ${g}`);return r}var fe=class extends Error{refusals;constructor(n){super(te(n)),this.name="FlowConfigError",this.refusals=n}};function dt(e){if(e.ok)return e.entries;throw new fe(e.refusals)}function J(e,n,t=" \xB7 "){return n.length===0?e.ok():e.fail(n.join(t))}function oe(e){return e.file??{path:"",content:""}}function bo(e,n){let t=e.split(`
4
+ `),r=[];for(let o of n){let s=new RegExp(o);t.forEach((i,a)=>{s.test(i)&&r.push({pattern:o,line:a+1})})}return r}var da=N(e=>n=>{let t=bo(oe(n).content,e.ban);return J(n,t.map(r=>`line ${r.line}: matches /${r.pattern}/`))}),la=N(e=>n=>{let t=n.command??"",r=e.ban.filter(o=>new RegExp(o).test(t));return J(n,r.map(o=>`matches banned /${o}/`))});var ca=["You are recording prose through a shell command, and a backtick inside a DOUBLE-quoted argument is not Markdown \u2014 the shell RUNS it and splices its output into your text before the command ever sees it.","On an append-only record there is no undo: no amend, no redact. And once the binary has argv the splice has already happened, so this is the only moment it can be caught.","Fix: SINGLE-quote the argument (backticks are literal there), or feed the prose on stdin with a QUOTED heredoc \u2014 `git commit -F -` plus `<<'EOF'`, which this rule treats as safe.","ALREADY single-quoted and still blocked? Then your PROSE carries an unbalanced double quote before the backtick, and the matcher cannot tell that quote from a real open argument. Nothing would splice \u2014 this one is the rule's cost, not your mistake. Balance the quote, drop it, or use the heredoc; do not go back to double quotes to make it pass."].join(`
5
+ `),ua=N(e=>async n=>{let{path:t}=oe(n);return e.existingOnly===!0?n.moment!=="delete"&&!await n.fs.exists(t)?n.ok():n.fail(`'${t}' is append-only \u2014 an existing file here is history and may not be edited or deleted (adding a new one is fine)`):n.fail(`'${t}' is a protected path (do not edit directly)`)}),fa=N(e=>async n=>{let t=Xe(e.sibling,oe(n).path);return await n.fs.exists(t)?n.ok():n.fail(`required sibling missing: ${t}`)}),wo=/\.(ts|tsx|mts|cts|js|mjs|cjs|jsx)$/;function xo(e,n){let t=e.replace(/\\/g,"/"),r=n.root.replace(/^\/+|\/+$/g,"")+"/",o=t.indexOf(r);if(o===-1)return{ok:!0};let s=t.slice(o+r.length);if(n.folders?.length){let c=s.split("/")[0]??"",u=c.replace(/\.[^.]+$/,"");if(c!==""&&!n.folders.includes(c)&&!n.folders.includes(u))return{ok:!1,tier:"folder",found:c}}if(!n.allow.length)return{ok:!0};let i=wo.exec(t);if(!i)return{ok:!0};if(t.endsWith(".d.ts"))return{ok:!0};if(!s.includes("/"))return{ok:!0};let d=s.slice(s.lastIndexOf("/")+1).slice(0,-i[0].length);return(d.endsWith(".test")?d.slice(0,-5)!==(n.thinking??""):!n.allow.includes(d))?{ok:!1,tier:"filename"}:{ok:!0}}function So(e,n,t){return e.ok?"":e.tier==="folder"?`'${e.found}' is not one of the names ${t.root}/ may hold: ${t.folders?.join(" \xB7 ")??""} (found ${n})`:`non-canonical file in a ${t.root} feature folder: ${n} (allowed: ${t.allow.join(" \xB7 ")}${t.thinking===void 0?"":` \u2014 only ${t.thinking} may carry a .test sibling`})`}var ga=N(e=>n=>{let{path:t}=oe(n),r=xo(t,e);return r.ok?n.ok():n.fail(So(r,t,e))});function Ro(e,n){let t=e;for(let r of(n??"").split(".").filter(Boolean)){if(t==null||typeof t!="object"||!(r in t))return{found:!1};t=t[r]}return{found:!0,value:t}}function $o(e,n){let t=[],{path:r}=n,o=Ro(e,r);if(!o.found)return n.required===!0&&t.push(`"${r}" is missing (required)`),t;let s=o.value;if(n.keysPrefixedWith!==void 0){if(!s||typeof s!="object")return t;for(let i of Object.keys(s))i.startsWith(n.keysPrefixedWith)||t.push(`"${r}.${i}" must be prefixed "${n.keysPrefixedWith}"`)}return"equals"in n&&JSON.stringify(s)!==JSON.stringify(n.equals)&&t.push(`"${r}" must equal ${JSON.stringify(n.equals)} (is ${JSON.stringify(s)})`),n.matches!==void 0&&!new RegExp(n.matches).test(String(s))&&t.push(`"${r}" (${JSON.stringify(s)}) must match /${n.matches}/`),t}function vo(e,n){let t;try{t=JSON.parse(e)}catch{return[]}return n.flatMap(r=>$o(t,r))}var pa=N(e=>n=>J(n,vo(oe(n).content,e.assert)));function Eo(e,n){return e.filter(t=>!new RegExp(`\\b${ne(t)}\\b`).test(n))}async function Co(e){let{parse:n,Lang:t}=await import("@ast-grep/napi"),r=n(t.Tsx,e).root(),o=new Set;for(let s of["export function $N($$$) { $$$ }","export class $N { $$$ }","export const $N = $V"])for(let i of r.findAll(s)){let a=i.getMatch("N");a&&o.add(a.text())}return[...o]}var ya=N(e=>async n=>{let{path:t,content:r}=oe(n),o=Xe(e.sibling,t);if(!await n.fs.exists(o))return n.fail(`sibling test not found: ${o}`);let s=await n.fs.read(o),i=Eo(await Co(r),s);return J(n,i.map(a=>`exported '${a}' is never referenced in ${o}`))});async function ft(e){return e.staged?e.staged:e.git.stagedFiles()}function Oo(e,n){let t=[];for(let r of n)e.some(o=>M(o,r.if))&&(e.some(o=>M(o,r.thenAny))||t.push(`${r.if.join(", ")} changed but none of [${r.thenAny.join(", ")}] did in the same commit`));return t}var ma=N(e=>async n=>J(n,Oo(await ft(n),e.groups))),Ae=new Set([";","&&","||","|","&","|&",`
6
+ `]),Po=new Set(["-C","-c","--git-dir","--work-tree","--namespace","--exec-path","--config-env"]);function To(e,n){for(let t=n;t<e.length;t++){if(e[t]==="\\"){t++;continue}if(e[t]==='"')return t}return-1}function je(e){let n=e,t=[],r="",o=!1,s=0,i=()=>{o&&t.push(r),r="",o=!1};for(;s<n.length;){let a=n[s];if(a==="'"||a==='"'){let d=a==="'"?n.indexOf("'",s+1):To(n,s+1);if(d===-1)return null;r+=a==='"'?n.slice(s+1,d).replace(/\\(["\\$`])/g,"$1"):n.slice(s+1,d),o=!0,s=d+1}else if(a==="\\"&&s+1<n.length)r+=n[s+1],o=!0,s+=2;else if(a===`
7
7
  `)i(),t.push(`
8
- `),s++;else if(/\s/.test(a))i(),s++;else if(a===";"||a==="|"||a==="&"){i();let d=n.slice(s,s+2);d==="&&"||d==="||"||d==="|&"?(t.push(d),s+=2):(t.push(a),s++)}else r+=a,o=!0,s++}return i(),t}function dt(e){let n=Me(e);if(!n)return null;let t=[],r=0,o=!0;for(;r<n.length;){let s=n[r];if(Ae.has(s)){o=!0,r++;continue}if(o&&s==="git"){let i=[],a=r+1;for(;a<n.length&&!Ae.has(n[a]);)i.push(n[a++]);let d=0;for(;d<i.length;){let l=i[d];if(Ro.has(l))d+=2;else if(l.startsWith("-"))d+=1;else break}t.push({globals:i.slice(0,d),subcommand:i[d]??null,args:i.slice(d+1)}),r=a,o=!1;continue}o=!1,r++}return t}function vo(e){let n=/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/.exec(e);if(!n)return null;let t=n[2],o=e.slice(n.index+n[0].length).split(`
8
+ `),s++;else if(/\s/.test(a))i(),s++;else if(a===";"||a==="|"||a==="&"){i();let d=n.slice(s,s+2);d==="&&"||d==="||"||d==="|&"?(t.push(d),s+=2):(t.push(a),s++)}else r+=a,o=!0,s++}return i(),t}function gt(e){let n=je(e);if(!n)return null;let t=[],r=0,o=!0;for(;r<n.length;){let s=n[r];if(Ae.has(s)){o=!0,r++;continue}if(o&&s==="git"){let i=[],a=r+1;for(;a<n.length&&!Ae.has(n[a]);)i.push(n[a++]);let d=0;for(;d<i.length;){let l=i[d];if(Po.has(l))d+=2;else if(l.startsWith("-"))d+=1;else break}t.push({globals:i.slice(0,d),subcommand:i[d]??null,args:i.slice(d+1)}),r=a,o=!1;continue}o=!1,r++}return t}function Ao(e){let n=/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/.exec(e);if(!n)return null;let t=n[2],o=e.slice(n.index+n[0].length).split(`
9
9
  `).slice(1),s=o.findIndex(a=>a.trim()===t);if(s===-1)return null;let i=o.slice(0,s).join(`
10
- `).trim();return i===""?null:i}function Eo(e){let n=dt(e);if(!n)return null;let t=n.find(o=>o.subcommand==="commit");if(!t)return null;let r=[];for(let o=0;o<t.args.length;o++){let s=t.args[o];if(s==="-m"||s==="--message"){let i=t.args[o+1];if(i===void 0)break;r.push(i),o++;continue}s.startsWith("-m")&&s!=="-m"?r.push(s.slice(2)):s.startsWith("--message=")&&r.push(s.slice(10))}return r.length?r.join(`
10
+ `).trim();return i===""?null:i}function jo(e){let n=gt(e);if(!n)return null;let t=n.find(o=>o.subcommand==="commit");if(!t)return null;let r=[];for(let o=0;o<t.args.length;o++){let s=t.args[o];if(s==="-m"||s==="--message"){let i=t.args[o+1];if(i===void 0)break;r.push(i),o++;continue}s.startsWith("-m")&&s!=="-m"?r.push(s.slice(2)):s.startsWith("--message=")&&r.push(s.slice(10))}return r.length?r.join(`
11
11
 
12
- `):vo(e)}function re(e){return`'${e.replace(/'/g,"'\\''")}'`}function Co(e){let n=[],t=Me(e),r=t?.[1];t?.[0]==="cd"&&r!==void 0&&!r.startsWith("-")&&!Ae.has(r)&&Ae.has(t[2]??"")&&n.push("-C",re(r));let o=dt(e)?.[0];if(!o)return n.join(" ");for(let s=0;s<o.globals.length-1;s++)o.globals[s]==="-C"&&n.push("-C",re(o.globals[s+1]));return n.join(" ")}function Oo(e,n){return new RegExp(`^[ \\t]*${ne(n)}[ \\t]*:`,"im").test(e)}function Po(e,n,t=[]){let r=new Set(t),o=new Set;for(let s of e.split(`
13
- `)){if(!s.startsWith("+")||s.startsWith("+++"))continue;let i=s.slice(1);for(let a of n){let d=new RegExp(a,"g"),l;for(;(l=d.exec(i))!==null;)l[1]!==void 0&&!r.has(l[1])&&o.add(l[1]),l[0]===""&&d.lastIndex++}}return[...o]}function To(e){let{message:n,state:t,whenChanged:r,whenAdded:o,except:s,namesAdded:i,token:a}=e,d=new Set(t.added),l=[];for(let c of t.changed)s&&j(c,s)||(d.has(c)&&o&&j(c,o)?l.push(`\`${c}\` (new)`):r&&j(c,r)&&l.push(`\`${c}\` (changed)`));for(let{name:c,file:u}of i??[])l.push(`\`${c}\` (added in ${u})`);return l.length?Oo(n,a)?[]:[`${l.join(" \xB7 ")} \u2014 and this commit's message records no reason. Put \`${a}: <why>\` on a line of its own in the message; the act is fine, doing it silently is not.`]:[]}function on(e){return e.split(`
14
- `).map(n=>n.trim()).filter(Boolean)}var ca=N(e=>async n=>{let t=Eo(n.command??"");if(t==null)return n.ok();let r=`git ${Co(n.command??"")}`.trimEnd(),o={changed:[],added:[]};if(e.whenChanged||e.whenAdded){let[a,d,l]=await Promise.all([n.exec(`${r} diff HEAD --name-only`),n.exec(`${r} diff HEAD --name-only --diff-filter=A`),n.exec(`${r} ls-files --others --exclude-standard`)]);if(a.code!==0||d.code!==0||l.code!==0)return n.ok();let c=on(l.stdout);o={changed:[...new Set([...on(a.stdout),...c])],added:[...on(d.stdout),...c]}}let s=[];for(let a of e.diffAdds??[]){let d=await n.exec(`${r} diff HEAD -- ${re(a.file)}`);if(d.code!==0)return n.ok();for(let l of Po(d.stdout,a.patterns,a.known??[]))s.push({name:l,file:a.file})}let i=To({message:t,state:o,whenChanged:e.whenChanged,whenAdded:e.whenAdded,except:e.except,namesAdded:s,token:e.token});return J(n,i)});function Ao(e,n,t){if(t===""||n.length===0)return!1;let r=-1,o=-1;return e.forEach((s,i)=>{s.did==="edit"&&j(s.path,n)&&(r=i),s.did==="run"&&s.command.includes(t)&&(o=i)}),r>=0&&r>o}var ua=N(e=>n=>n.turn&&Ao(n.turn,e.edited,e.mustRun)?n.fail(`edited ${e.edited.join(", ")} this turn but never ran \`${e.mustRun}\` afterwards`):n.ok());function Mo(e,n){let t=n??[];return!t.length||!e.length?!1:!e.some(r=>j(r,t))}function lt(e,n=8){let t=e.trim().split(`
12
+ `):Ao(e)}function re(e){return`'${e.replace(/'/g,"'\\''")}'`}function Mo(e){let n=[],t=je(e),r=t?.[1];t?.[0]==="cd"&&r!==void 0&&!r.startsWith("-")&&!Ae.has(r)&&Ae.has(t[2]??"")&&n.push("-C",re(r));let o=gt(e)?.[0];if(!o)return n.join(" ");for(let s=0;s<o.globals.length-1;s++)o.globals[s]==="-C"&&n.push("-C",re(o.globals[s+1]));return n.join(" ")}function No(e,n){return new RegExp(`^[ \\t]*${ne(n)}[ \\t]*:`,"im").test(e)}function Go(e,n,t=[]){let r=new Set(t),o=new Set;for(let s of e.split(`
13
+ `)){if(!s.startsWith("+")||s.startsWith("+++"))continue;let i=s.slice(1);for(let a of n){let d=new RegExp(a,"g"),l;for(;(l=d.exec(i))!==null;)l[1]!==void 0&&!r.has(l[1])&&o.add(l[1]),l[0]===""&&d.lastIndex++}}return[...o]}function _o(e){let{message:n,state:t,whenChanged:r,whenAdded:o,except:s,namesAdded:i,token:a}=e,d=new Set(t.added),l=[];for(let c of t.changed)s&&M(c,s)||(d.has(c)&&o&&M(c,o)?l.push(`\`${c}\` (new)`):r&&M(c,r)&&l.push(`\`${c}\` (changed)`));for(let{name:c,file:u}of i??[])l.push(`\`${c}\` (added in ${u})`);return l.length?No(n,a)?[]:[`${l.join(" \xB7 ")} \u2014 and this commit's message records no reason. Put \`${a}: <why>\` on a line of its own in the message; the act is fine, doing it silently is not.`]:[]}function sn(e){return e.split(`
14
+ `).map(n=>n.trim()).filter(Boolean)}var ha=N(e=>async n=>{let t=jo(n.command??"");if(t==null)return n.ok();let r=`git ${Mo(n.command??"")}`.trimEnd(),o={changed:[],added:[]};if(e.whenChanged||e.whenAdded){let[a,d,l]=await Promise.all([n.exec(`${r} diff HEAD --name-only`),n.exec(`${r} diff HEAD --name-only --diff-filter=A`),n.exec(`${r} ls-files --others --exclude-standard`)]);if(a.code!==0||d.code!==0||l.code!==0)return n.ok();let c=sn(l.stdout);o={changed:[...new Set([...sn(a.stdout),...c])],added:[...sn(d.stdout),...c]}}let s=[];for(let a of e.diffAdds??[]){let d=await n.exec(`${r} diff HEAD -- ${re(a.file)}`);if(d.code!==0)return n.ok();for(let l of Go(d.stdout,a.patterns,a.known??[]))s.push({name:l,file:a.file})}let i=_o({message:t,state:o,whenChanged:e.whenChanged,whenAdded:e.whenAdded,except:e.except,namesAdded:s,token:e.token});return J(n,i)});function Fo(e,n,t){if(t===""||n.length===0)return!1;let r=-1,o=-1;return e.forEach((s,i)=>{s.did==="edit"&&M(s.path,n)&&(r=i),s.did==="run"&&s.command.includes(t)&&(o=i)}),r>=0&&r>o}var ka=N(e=>n=>n.turn&&Fo(n.turn,e.edited,e.mustRun)?n.fail(`edited ${e.edited.join(", ")} this turn but never ran \`${e.mustRun}\` afterwards`):n.ok());function Io(e,n){let t=n??[];return!t.length||!e.length?!1:!e.some(r=>M(r,t))}function pt(e,n=8){let t=e.trim().split(`
15
15
  `).filter(Boolean),r=t.filter(o=>/\b(fail|failed|error|not ok|assert|expected|cannot|undefined)\b/i.test(o)||/[✖✗✘]/.test(o));return(r.length?r:t.slice(-6)).slice(0,n).join(`
16
- `)}var fa=N(e=>async n=>{let t=await at(n);if(Mo(t,e.changed))return n.ok();let r=e.run.includes("{files}");if(r&&t.length===0)return n.ok();let o=r?e.run.replace("{files}",t.map(re).join(" ")):e.run,s=await n.exec(o);return s.code===0?n.ok():n.fail(`\`${o}\` failed (exit ${s.code}):
17
- ${lt(s.stderr||s.stdout)}`)});function Te(e){let n=Ye(e),t=n[n.length-1]?.kind==="globstar";return`^${(t?n.slice(0,-1):n).map(Qe).join("")}${t?"":"$"}`}function jo(e){return e==="node:*"?{core:!0}:e.startsWith("node:")?{path:`^${ne(e)}$`}:e.includes("/")||e.includes("*")||e.includes(".")?{path:Te(e)}:{path:`node_modules/${ne(e)}(/|$)`}}function Pe(e,n){let t=[],r=!1;for(let s of e)for(let i of n[s]??[]){let a=jo(i);a.core?r=!0:a.path&&t.push(a.path)}let o={};return t.length&&(o.path=t),r&&(o.dependencyTypes=["core"]),o}function No(e){let n=e.layers,t=[],r=[],o=(e.except??[]).includes("type-only"),s=a=>o?{...a,dependencyTypesNot:["type-only"]}:a;for(let[a,d]of Object.entries(e.only??{})){let c={pathNot:Pe(d,n).path??[]};t.push({name:`${a}-only`,severity:"error",comment:`${a} may import only: ${d.join(", ")} \u2014 an unlisted import blocks here (add it to a layer, or keep it out).`,from:Pe([a],n),to:s(c)})}for(let a of e.forbid??[])if(a==="circular")t.push({name:"no-circular",severity:"error",comment:"no dependency cycles",from:{pathNot:"node_modules"},to:{circular:!0}});else if(a==="orphans")t.push({name:"no-orphans",severity:"warn",comment:"unreferenced module",from:{orphan:!0,pathNot:"node_modules|\\.d\\.ts$"},to:{}});else if(a.cyclesBetween!==void 0){let d=a.cyclesBetween,l=(n[d]??[])[0]??"",c=Te(l).replace(/\$$/,"").replace(/\[\^\/\]\*$/,"([^/]+)");t.push({name:`no-cycles-between-${d}`,severity:"error",comment:a.why??`${d} must not import sideways`,from:{path:`${c}/`},to:s({path:`${c.replace(/\(\[\^\/\]\+\)/,"[^/]+")}/`,pathNot:"$1/"})})}else if(a.from!==void 0&&a.to!==void 0){let d={...Pe([a.to],n)};a.transitive===!0&&(d.reachable=!0),t.push({name:`no-${a.from}-to-${a.to}${a.transitive===!0?"-transitive":""}`,severity:"error",comment:a.why??`${a.from} must not import ${a.to}`,from:Pe([a.from],n),to:s(d)})}for(let a of e.require??[])r.push({name:`must-import-${a.import}`,severity:"error",comment:a.why??`modules in ${a.in} must import ${a.import}`,module:{path:Te(a.in)},to:{path:Te(a.import)}});for(let a of e.warn??[])a==="sdp"&&t.push({name:"sdp",severity:"warn",comment:"depends on a more-unstable module (Stable Dependencies Principle)",from:{},to:{moreUnstable:!0}});let i={enhancedResolveOptions:{extensions:[".js",".jsx",".ts",".tsx",".mjs",".cjs",".json"]},doNotFollow:{path:"node_modules"},tsPreCompilationDeps:!1,...e.options??{}};return{forbidden:t,required:r,options:i}}var st="FLOW_DEPCRUISE_CONFIG";function _o(e){let n=JSON.stringify(No(e));return["d=$(mktemp -d)",`cat > "$d/dc.json" <<'${st}'`,n,st,`npx --no-install depcruise --config "$d/dc.json" --output-type json ${re(e.scan)}`,"rc=$?",'rm -rf "$d"',"exit $rc"].join(`
18
- `)}function Fo(e){let n;try{n=JSON.parse(e.stdout||"")}catch{return e.code===0?[]:[`depcruise failed (exit ${e.code}): ${lt(e.stderr||e.stdout,3)}`]}return(n.summary?.violations??[]).map(t=>{let r=t.rule?.name??"fence",o=t.comment??t.rule?.comment??"";return`${r}: ${t.from} \u2192 ${t.to}${o?` \u2014 ${o}`:""}`})}var ga=N(e=>async n=>J(n,Fo(await n.exec(_o(e))),`
19
- `)),ct={html:"Html",css:"Css",javascript:"JavaScript",js:"JavaScript",typescript:"TypeScript",ts:"TypeScript",tsx:"Tsx",jsx:"Tsx"},Go=Object.keys(ct),sn=new Set,it=Symbol.for("flow.grammars");function ut(){let e=globalThis,n=e[it];if(n!==void 0)return n;let t={declared:[],present:()=>!1};return e[it]=t,t}function an(e,n){return`\`${e}\`: no library at ${n}. A grammar is a BUILD ARTEFACT \u2014 machine-specific, never committed \u2014 so this is the ordinary state of a fresh clone. Build it (the repo that declares a grammar carries the recipe that builds it), or every ast-grep rule on that language refuses rather than passing quietly.`}function ft(e,n=()=>!1){let t=ut();t.declared=e,t.present=n}async function Io(e){let{Lang:n,registerDynamicLanguage:t}=await import("@ast-grep/napi"),r=ct[e];if(r!==void 0)return{ok:!0,lang:n[r]};if(sn.has(e))return{ok:!0,lang:e};let{declared:o,present:s}=ut(),i=o.find(a=>a.name===e);if(i!==void 0)return s(i.libraryPath)?(t({[e]:{libraryPath:i.libraryPath,extensions:[...i.extensions],...i.languageSymbol===void 0?{}:{languageSymbol:i.languageSymbol}}}),sn.add(e),{ok:!0,lang:e}):{ok:!1,detail:an(e,i.libraryPath)};try{let a=await import(`@ast-grep/lang-${e}`);return t({[e]:a.default??a}),sn.add(e),{ok:!0,lang:e}}catch{return{ok:!1,detail:`unknown ast-grep grammar: '${e}'. Built in: ${Go.join(", ")}. Anything else is either a published package \u2014 \`npm i -D @ast-grep/lang-${e}\` \u2014 or a grammar you build yourself and declare in flow.config.ts's \`grammars\` setting.`}}}async function Bo(e,n,t){let r=await Io(t);if(!r.ok)return r;let{parse:o}=await import("@ast-grep/napi");return{ok:!0,hits:o(r.lang,e).root().findAll({rule:n}).map(i=>`${i.range().start.line+1}: ${i.text()}`)}}var pa=N(e=>async n=>{let t=await Bo(oe(n).content,e.rule,e.language);return t.ok?J(n,t.hits):n.fail(t.detail)}),Do={command:["command"],write:["write","delete"],commit:["commit"],"turn-end":["turn-end"]};function gt(e){if(typeof e=="string")return{dialect:"command",facts:{command:e},world:{}};let n=e.world??{};return"command"in e?{dialect:"command",facts:{command:e.command},world:n}:"path"in e?{dialect:"write",facts:{file:{path:e.path,content:e.content}},world:n}:"staged"in e?{dialect:"commit",facts:{staged:e.staged},world:n}:{dialect:"turn-end",facts:{turn:e.actions},world:n}}function Lo(e,n){let{world:t,facts:r}=gt(e);return{world:Oe(t,r.staged,n),facts:r}}async function Wo(e,n,t,r){let{world:o,facts:s}=Lo(t,r);return(n==="commit"?await Ho(e,s,o):[s]).map(a=>Ce(n,a,o))}async function Ho(e,n,t){let r=n.staged??[];if(!e.spec.on)return[n];let o=[];for(let s of r)q(e.spec,s)&&await t.fs.exists(s)&&o.push({file:{path:s,content:await t.fs.read(s)},staged:r});return o}async function Uo(e,n,t,r,o){let{dialect:s}=gt(t),i=e.spec.kind==="guardrail"?e.spec.at??[]:[],a=i.find(m=>Do[s].includes(m)),d={entry:e.id,expect:r,index:o};if(a===void 0)return{...d,ok:!1,detail:`this case speaks the ${s} dialect, and the entry fires at ${i.length?i.join(", "):"no moment at all"} \u2014 nothing here would ever be handed one`};let l=[],c,u={ok:!0};try{let m=[];for(let w of await Wo(e,a,t,l))m.push(await n(w));u=m.find(w=>!w.ok)??{ok:!0},c=!u.ok}catch(m){return{...d,ok:!1,detail:`the check threw: ${m.message}`}}if(l.length)return{...d,ok:!1,detail:Ko(l)};let p=r==="block";if(c===p)return{...d,ok:!0,detail:""};if(p)return{...d,ok:!1,detail:"expected a block and the check passed it \u2014 the rule does not catch what it says it catches"};let g=u.ok||u.detail===void 0?"":`: ${u.detail}`;return{...d,ok:!1,detail:`expected a pass and the check blocked it${g}`}}function Ko(e){return e.map(n=>n.kind==="exec"?`the check ran \`${n.asked}\` and the case records no answer \u2014 add it under \`world.exec\``:`the check read \`${n.asked}\` and the case records no content \u2014 add it under \`world.fs\``).join(" \xB7 ")}async function pt(e){let n=[];for(let t of e){let{spec:r}=t;if(r.kind!=="guardrail"||r.disabled||!r.check)continue;let o=r.check,s=r.test??{};for(let[i,a]of[["pass",s.pass],["block",s.block]])for(let[d,l]of(a??[]).entries())n.push(await Uo(t,o,l,i,d))}return n}import{spawnSync as Xs}from"node:child_process";import{existsSync as Bn,readFileSync as Ve,statSync as ei}from"node:fs";import{isAbsolute as Mr,join as Re,resolve as jr}from"node:path";import{pathToFileURL as ni}from"node:url";import{join as W}from"node:path";function kt(e){let n=[];for(let t of e)for(let r of t.spec.for??[])rn(r)&&!n.some(o=>o.name===r.name)&&n.push(r);return n}function bt(e,n,t){if(e)return{wearing:e,faults:[],fresh:!1};let r=[],o=[];for(let s of t)try{s.classify(n)&&r.push(s.name)}catch(i){o.push({category:s.name,error:i.message})}return{wearing:r,faults:o,fresh:!0}}function ln(e,n){return e.disabled?!1:(e.at??[]).includes(n)}function wt(e,n){return e.categories.length===0?!0:e.categories.some(t=>n.includes(t))}function he(e,n){return(e.on?.length??0)>0&&q(e,n)}function je(e){return e.filter(n=>n.disabled===null&&(n.on?.length??0)>0)}async function Vo(e,n,t){let{spec:r}=e;if(n.moment==="commit"){let o=n.staged??[];if(!r.on)return[{name:null,facts:{staged:o}}];let s=[];for(let i of o)q(r,i)&&await t.fs.exists(i)&&s.push({name:i,facts:{file:{path:i,content:await t.fs.read(i)},staged:o}});return s}if(n.moment==="write"||n.moment==="delete"){let o=n.file;return!o||!q(r,o.path)?[]:[{name:o.path,facts:{file:o}}]}if(n.moment==="command"){let o=n.command??"";return[{name:o,facts:{command:o}}]}return[{name:null,facts:{turn:n.turn??[]}}]}var dn=["session","first-touch","drift","fault"],qo={effects:[],tallies:[]};function se(e){return{do:"block",entry:null,message:e,subject:null,detail:""}}async function Ne({load:e,event:n,world:t,faults:r=[],off:o=!1}){if(o)return qo;if(!e.ok)return{effects:[se(te(e.refusals))],tallies:[]};if(r.length>0)return{effects:r.map(a=>se(`flow: the category \`${a.category}\` could not classify this session, so a rule scoped to it cannot be trusted either way \u2014 ${a.error}`)),tallies:[]};let s=[],i=[];for(let a of e.entries){if(a.spec.kind!=="guardrail"||!ln(a.spec,n.moment))continue;if(!wt(a,n.wearing)){i.push({id:a.id,evaluated:0,hits:0,silenced:1});continue}let d=a.spec.check;if(!d){s.push(se(`flow: \`${a.id}\` fires at ${n.moment} and carries no check. A rail that cannot ask a question is not a rail that passes.`));continue}let l=0,c=0;for(let u of await Vo(a,n,t)){l+=1;let p=await Jo(d,Ce(n.moment,u.facts,t));p.ok||(c+=1,s.push({do:"block",entry:a.id,message:a.spec.message??"",subject:u.name,detail:p.detail??""}))}i.push({id:a.id,evaluated:l,hits:c,silenced:0})}return{effects:s,tallies:i}}async function Jo(e,n){try{return await e(n)}catch(t){return Ee.fail(`the check threw: ${t.message}`)}}var zo=2e5;function Yo(e){return e.driftTokens??zo}function cn({load:e,event:n,marks:t,settings:r,off:o=!1}){if(o)return{notices:[],marks:t};if(!e.ok)return{notices:[{do:"notice",entry:null,text:te(e.refusals),file:void 0,cause:"fault"}],marks:t};let s=[],i={...t},a=Yo(r);for(let d of e.entries){if(d.spec.kind!=="breadcrumb"||!ln(d.spec,n.moment)||!wt(d,n.wearing)||n.path!==void 0&&!q(d.spec,n.path)||n.command!==void 0&&!q(d.spec,n.command))continue;let l=i[d.id],c=n.moment==="session"?"session":l===void 0?"first-touch":"drift";l!==void 0&&(c!=="drift"||n.tokens-l<a)||(s.push({do:"notice",entry:d.id,text:d.spec.text,file:d.spec.file,cause:c}),i[d.id]=n.tokens)}return{notices:s,marks:i}}function un(e,n){let t=new Set(n.filter(o=>ln(o.spec,"session")).map(o=>o.id)),r={};for(let[o,s]of Object.entries(e))t.has(o)&&(r[o]=s);return r}function xt(e){let t=[e.entry===null?e.message:`\u2717 ${e.entry}${e.subject?` \xB7 ${e.subject}`:""}`];return e.entry!==null&&e.message&&t.push(` ${e.message}`),e.detail&&t.push(...e.detail.split(`
16
+ `)}var ba=N(e=>async n=>{let t=await ft(n);if(Io(t,e.changed))return n.ok();let r=e.run.includes("{files}");if(r&&t.length===0)return n.ok();let o=r?e.run.replace("{files}",t.map(re).join(" ")):e.run,s=await n.exec(o);return s.code===0?n.ok():n.fail(`\`${o}\` failed (exit ${s.code}):
17
+ ${pt(s.stderr||s.stdout)}`)});function Te(e){let n=Qe(e),t=n[n.length-1]?.kind==="globstar";return`^${(t?n.slice(0,-1):n).map(Ze).join("")}${t?"":"$"}`}function lt(e){return e==="node:*"?{core:!0}:e.startsWith("node:")?{path:`^${ne(e)}$`}:e.includes("/")||e.includes("*")||e.includes(".")?{path:Te(e)}:{path:`node_modules/${ne(e)}(/|$)`}}function Me(e){return e===void 0?{path:[],not:[]}:Array.isArray(e)?{path:e,not:[]}:{path:e.path,not:e.not??[]}}function Pe(e,n){let t=[],r=[],o=!1;for(let i of e){let{path:a,not:d}=Me(n[i]);for(let l of a){let c=lt(l);c.core?o=!0:c.path&&t.push(c.path)}for(let l of d){let c=lt(l);c.path&&r.push(c.path)}}let s={};return t.length&&(s.path=t),r.length&&(s.pathNot=r),o&&(s.dependencyTypes=["core"]),s}function Bo(e){let n=e.layers,t=[],r=[],o=(e.except??[]).includes("type-only"),s=a=>o?{...a,dependencyTypesNot:["type-only"]}:a;for(let[a,d]of Object.entries(e.only??{})){let c={pathNot:Pe(d,n).path??[]};t.push({name:`${a}-only`,severity:"error",comment:`${a} may import only: ${d.join(", ")} \u2014 an unlisted import blocks here (add it to a layer, or keep it out).`,from:Pe([a],n),to:s(c)})}for(let a of e.forbid??[])if(a==="circular")t.push({name:"no-circular",severity:"error",comment:"no dependency cycles",from:{pathNot:"node_modules"},to:{circular:!0}});else if(a==="orphans")t.push({name:"no-orphans",severity:"warn",comment:"unreferenced module",from:{orphan:!0,pathNot:"node_modules|\\.d\\.ts$"},to:{}});else if(a.cyclesBetween!==void 0){let d=a.cyclesBetween,l=Me(n[d]).path[0]??"",c=Te(l).replace(/\$$/,"").replace(/\[\^\/\]\*$/,"([^/]+)");t.push({name:`no-cycles-between-${d}`,severity:"error",comment:a.why??`${d} must not import sideways`,from:{path:`${c}/`},to:s({path:`${c.replace(/\(\[\^\/\]\+\)/,"[^/]+")}/`,pathNot:"$1/"})})}else if(a.from!==void 0&&a.to!==void 0){let d={...Pe([a.to],n)};a.transitive===!0&&(d.reachable=!0),t.push({name:`no-${a.from}-to-${a.to}${a.transitive===!0?"-transitive":""}`,severity:"error",comment:a.why??`${a.from} must not import ${a.to}`,from:Pe([a.from],n),to:s(d)})}for(let a of e.require??[])r.push({name:`must-import-${a.import}`,severity:"error",comment:a.why??`modules in ${a.in} must import ${a.import}`,module:{path:Te(a.in)},to:{path:Te(a.import)}});for(let a of e.warn??[])a==="sdp"&&t.push({name:"sdp",severity:"warn",comment:"depends on a more-unstable module (Stable Dependencies Principle)",from:{},to:{moreUnstable:!0}});let i={enhancedResolveOptions:{extensions:[".js",".jsx",".ts",".tsx",".mjs",".cjs",".json"]},doNotFollow:{path:"node_modules"},tsPreCompilationDeps:!1,...e.options??{}};return{forbidden:t,required:r,options:i}}var ct="FLOW_DEPCRUISE_CONFIG";function Do(e){let n=JSON.stringify(Bo(e));return["d=$(mktemp -d)",`cat > "$d/dc.json" <<'${ct}'`,n,ct,`npx --no-install depcruise --config "$d/dc.json" --output-type json ${re(e.scan)}`,"rc=$?",'rm -rf "$d"',"exit $rc"].join(`
18
+ `)}function Lo(e){let n;try{n=JSON.parse(e.stdout||"")}catch{return e.code===0?[]:[`depcruise failed (exit ${e.code}): ${pt(e.stderr||e.stdout,3)}`]}return(n.summary?.violations??[]).map(t=>{let r=t.rule?.name??"fence",o=t.comment??t.rule?.comment??"";return`${r}: ${t.from} \u2192 ${t.to}${o?` \u2014 ${o}`:""}`})}function Wo(e){let n=[];for(let[t,r]of Object.entries(e)){let{path:o,not:s}=Me(r);s.includes("node:*")&&n.push(`binds a depcruise layer \`${t}\` whose \`not\` list excludes \`node:*\`. A builtin is matched as a dependency TYPE, not a path, and the only exclusion available says "not a core module at all" \u2014 wider than this layer means. Say the layer's globs without it, or forbid the edge you actually mean.`);for(let i of[...o,...s])et(i)&&n.push(`binds a depcruise layer \`${t}\` whose entry is a regular expression, not a glob: \`${i}\`. Layers are GLOBS here \u2014 \`src/pages/**\`, \`src/lib/auth/**\` \u2014 and a regex is escaped into a literal, so the fence would load, report armed and match nothing. For a layer with holes in it, say \`{ path: ["src/pages/**"], not: ["src/pages/api/**"] }\` rather than a lookahead.`)}return n}function Ho(e){let n=[];for(let[t,r]of Object.entries(e.only??{}))for(let o of r)Me(e.layers[o]).not.length>0&&n.push(`binds a depcruise \`only\` for \`${t}\` naming the layer \`${o}\`, which has a \`not\` list. An allowlist is compiled by inverting the layers it names, and that inversion reads \`path\` alone \u2014 so \`${o}\`'s exclusions would be silently dropped and the allowlist would be wider than it reads. Give \`${o}\` plain globs, or say the exclusion as a \`forbid\` edge.`);return n}var wa=N(e=>it(async t=>J(t,Lo(await t.exec(Do(e))),`
19
+ `),[...Wo(e.layers),...Ho(e)])),yt={html:"Html",css:"Css",javascript:"JavaScript",js:"JavaScript",typescript:"TypeScript",ts:"TypeScript",tsx:"Tsx",jsx:"Tsx"},Uo=Object.keys(yt),an=new Set,ut=Symbol.for("flow.grammars");function mt(){let e=globalThis,n=e[ut];if(n!==void 0)return n;let t={declared:[],present:()=>!1};return e[ut]=t,t}function dn(e,n){return`\`${e}\`: no library at ${n}. A grammar is a BUILD ARTEFACT \u2014 machine-specific, never committed \u2014 so this is the ordinary state of a fresh clone. Build it (the repo that declares a grammar carries the recipe that builds it), or every ast-grep rule on that language refuses rather than passing quietly.`}function ht(e,n=()=>!1){let t=mt();t.declared=e,t.present=n}async function Ko(e){let{Lang:n,registerDynamicLanguage:t}=await import("@ast-grep/napi"),r=yt[e];if(r!==void 0)return{ok:!0,lang:n[r]};if(an.has(e))return{ok:!0,lang:e};let{declared:o,present:s}=mt(),i=o.find(a=>a.name===e);if(i!==void 0)return s(i.libraryPath)?(t({[e]:{libraryPath:i.libraryPath,extensions:[...i.extensions],...i.languageSymbol===void 0?{}:{languageSymbol:i.languageSymbol}}}),an.add(e),{ok:!0,lang:e}):{ok:!1,detail:dn(e,i.libraryPath)};try{let a=await import(`@ast-grep/lang-${e}`);return t({[e]:a.default??a}),an.add(e),{ok:!0,lang:e}}catch{return{ok:!1,detail:`unknown ast-grep grammar: '${e}'. Built in: ${Uo.join(", ")}. Anything else is either a published package \u2014 \`npm i -D @ast-grep/lang-${e}\` \u2014 or a grammar you build yourself and declare in flow.config.ts's \`grammars\` setting.`}}}async function Vo(e,n,t){let r=await Ko(t);if(!r.ok)return r;let{parse:o}=await import("@ast-grep/napi");return{ok:!0,hits:o(r.lang,e).root().findAll({rule:n}).map(i=>`${i.range().start.line+1}: ${i.text()}`)}}var xa=N(e=>async n=>{let t=await Vo(oe(n).content,e.rule,e.language);return t.ok?J(n,t.hits):n.fail(t.detail)}),qo={command:["command"],write:["write","delete"],commit:["commit"],"turn-end":["turn-end"]};function kt(e){if(typeof e=="string")return{dialect:"command",facts:{command:e},world:{}};let n=e.world??{};return"command"in e?{dialect:"command",facts:{command:e.command},world:n}:"path"in e?{dialect:"write",facts:{file:{path:e.path,content:e.content}},world:n}:"staged"in e?{dialect:"commit",facts:{staged:e.staged},world:n}:{dialect:"turn-end",facts:{turn:e.actions},world:n}}function Jo(e,n){let{world:t,facts:r}=kt(e);return{world:Oe(t,r.staged,n),facts:r}}async function zo(e,n,t,r){let{world:o,facts:s}=Jo(t,r);return(n==="commit"?await Yo(e,s,o):[s]).map(a=>Ce(n,a,o))}async function Yo(e,n,t){let r=n.staged??[];if(!e.spec.on)return[n];let o=[];for(let s of r)q(e.spec,s)&&await t.fs.exists(s)&&o.push({file:{path:s,content:await t.fs.read(s)},staged:r});return o}async function Qo(e,n,t,r,o){let{dialect:s}=kt(t),i=e.spec.kind==="guardrail"?e.spec.at??[]:[],a=i.find(m=>qo[s].includes(m)),d={entry:e.id,expect:r,index:o};if(a===void 0)return{...d,ok:!1,detail:`this case speaks the ${s} dialect, and the entry fires at ${i.length?i.join(", "):"no moment at all"} \u2014 nothing here would ever be handed one`};let l=[],c,u={ok:!0};try{let m=[];for(let w of await zo(e,a,t,l))m.push(await n(w));u=m.find(w=>!w.ok)??{ok:!0},c=!u.ok}catch(m){return{...d,ok:!1,detail:`the check threw: ${m.message}`}}if(l.length)return{...d,ok:!1,detail:Zo(l)};let p=r==="block";if(c===p)return{...d,ok:!0,detail:""};if(p)return{...d,ok:!1,detail:"expected a block and the check passed it \u2014 the rule does not catch what it says it catches"};let g=u.ok||u.detail===void 0?"":`: ${u.detail}`;return{...d,ok:!1,detail:`expected a pass and the check blocked it${g}`}}function Zo(e){return e.map(n=>n.kind==="exec"?`the check ran \`${n.asked}\` and the case records no answer \u2014 add it under \`world.exec\``:`the check read \`${n.asked}\` and the case records no content \u2014 add it under \`world.fs\``).join(" \xB7 ")}async function bt(e){let n=[];for(let t of e){let{spec:r}=t;if(r.kind!=="guardrail"||r.disabled||!r.check)continue;let o=r.check,s=r.test??{};for(let[i,a]of[["pass",s.pass],["block",s.block]])for(let[d,l]of(a??[]).entries())n.push(await Qo(t,o,l,i,d))}return n}import{spawnSync as ii}from"node:child_process";import{existsSync as Dn,readFileSync as qe,statSync as ai}from"node:fs";import{isAbsolute as Fr,join as Re,resolve as Ir}from"node:path";import{pathToFileURL as di}from"node:url";import{join as W}from"node:path";function Rt(e){let n=[];for(let t of e)for(let r of t.spec.for??[])on(r)&&!n.some(o=>o.name===r.name)&&n.push(r);return n}function $t(e,n,t){if(e)return{wearing:e,faults:[],fresh:!1};let r=[],o=[];for(let s of t)try{s.classify(n)&&r.push(s.name)}catch(i){o.push({category:s.name,error:i.message})}return{wearing:r,faults:o,fresh:!0}}function cn(e,n){return e.disabled?!1:(e.at??[]).includes(n)}function vt(e,n){return e.categories.length===0?!0:e.categories.some(t=>n.includes(t))}function he(e,n){return(e.on?.length??0)>0&&q(e,n)}function Ne(e){return e.filter(n=>n.disabled===null&&(n.on?.length??0)>0)}async function Xo(e,n,t){let{spec:r}=e;if(n.moment==="commit"){let o=n.staged??[];if(!r.on)return[{name:null,facts:{staged:o}}];let s=[];for(let i of o)q(r,i)&&await t.fs.exists(i)&&s.push({name:i,facts:{file:{path:i,content:await t.fs.read(i)},staged:o}});return s}if(n.moment==="write"||n.moment==="delete"){let o=n.file;return!o||!q(r,o.path)?[]:[{name:o.path,facts:{file:o}}]}if(n.moment==="command"){let o=n.command??"";return[{name:o,facts:{command:o}}]}return[{name:null,facts:{turn:n.turn??[]}}]}var ln=["session","first-touch","drift","fault"],es={effects:[],tallies:[]};function se(e){return{do:"block",entry:null,message:e,subject:null,detail:""}}async function Ge({load:e,event:n,world:t,faults:r=[],off:o=!1}){if(o)return es;if(!e.ok)return{effects:[se(te(e.refusals))],tallies:[]};if(r.length>0)return{effects:r.map(a=>se(`flow: the category \`${a.category}\` could not classify this session, so a rule scoped to it cannot be trusted either way \u2014 ${a.error}`)),tallies:[]};let s=[],i=[];for(let a of e.entries){if(a.spec.kind!=="guardrail"||!cn(a.spec,n.moment))continue;if(!vt(a,n.wearing)){i.push({id:a.id,evaluated:0,hits:0,silenced:1});continue}let d=a.spec.check;if(!d){s.push(se(`flow: \`${a.id}\` fires at ${n.moment} and carries no check. A rail that cannot ask a question is not a rail that passes.`));continue}let l=0,c=0;for(let u of await Xo(a,n,t)){l+=1;let p=await ns(d,Ce(n.moment,u.facts,t));p.ok||(c+=1,s.push({do:"block",entry:a.id,message:a.spec.message??"",subject:u.name,detail:p.detail??""}))}i.push({id:a.id,evaluated:l,hits:c,silenced:0})}return{effects:s,tallies:i}}async function ns(e,n){try{return await e(n)}catch(t){return Ee.fail(`the check threw: ${t.message}`)}}var ts=2e5;function rs(e){return e.driftTokens??ts}function un({load:e,event:n,marks:t,settings:r,off:o=!1}){if(o)return{notices:[],marks:t};if(!e.ok)return{notices:[{do:"notice",entry:null,text:te(e.refusals),file:void 0,cause:"fault"}],marks:t};let s=[],i={...t},a=rs(r);for(let d of e.entries){if(d.spec.kind!=="breadcrumb"||!cn(d.spec,n.moment)||!vt(d,n.wearing)||n.path!==void 0&&!q(d.spec,n.path)||n.command!==void 0&&!q(d.spec,n.command))continue;let l=i[d.id],c=n.moment==="session"?"session":l===void 0?"first-touch":"drift";l!==void 0&&(c!=="drift"||n.tokens-l<a)||(s.push({do:"notice",entry:d.id,text:d.spec.text,file:d.spec.file,cause:c}),i[d.id]=n.tokens)}return{notices:s,marks:i}}function fn(e,n){let t=new Set(n.filter(o=>cn(o.spec,"session")).map(o=>o.id)),r={};for(let[o,s]of Object.entries(e))t.has(o)&&(r[o]=s);return r}function Et(e){let t=[e.entry===null?e.message:`\u2717 ${e.entry}${e.subject?` \xB7 ${e.subject}`:""}`];return e.entry!==null&&e.message&&t.push(` ${e.message}`),e.detail&&t.push(...e.detail.split(`
20
20
  `).map(r=>` ${r}`)),t.join(`
21
- `)}var z=".flow",St=`# flow's own state \u2014 telemetry and session marks, never committed.
21
+ `)}var z=".flow",Ct=`# flow's own state \u2014 telemetry and session marks, never committed.
22
22
  *
23
- `,Qo=1;function B(e){return W(e,z)}function ie(e){return(e||"nosession").replace(/[^A-Za-z0-9_-]/g,"-")}function fn(e,n){return W(B(e),"log",`${ie(n)}.jsonl`)}function gn(e,n,t){return W(B(e),"state",`${ie(n)}-${ie(t)}.json`)}function pn(e){if(e==null||e.trim()==="")return{marks:{}};let n;try{n=JSON.parse(e)}catch{return{marks:{}}}if(typeof n!="object"||n===null)return{marks:{}};let t=n,r=Array.isArray(t.categories)&&t.categories.every(s=>typeof s=="string")?t.categories:void 0,o={};if(typeof t.marks=="object"&&t.marks!==null)for(let[s,i]of Object.entries(t.marks))typeof i=="number"&&Number.isFinite(i)&&(o[s]=i);return r===void 0?{marks:o}:{categories:r,marks:o}}function yn(e,n){return W(B(e),n?`.session-${ie(n)}`:".session")}function Rt(e){return W(B(e),"off")}function $t(e){return W(B(e),"record")}function vt(e,n){return W(B(e),"replay",`${ie(n)}.jsonl`)}function _e(e){return W(B(e),"read")}function Et(e,n){return W(_e(e),ie(n))}var Zo=14400*1e3;function Ct(e,n,t,r=Zo){let o={session:n,agent:null};if(!e||typeof e.session!="string"||!e.session)return o;let s=Date.parse(String(e.ts));return!Number.isFinite(s)||Math.abs(t-s)>r?o:{session:e.session,agent:typeof e.agent=="string"&&e.agent?e.agent:null}}function Ot(e){let n=e.split(`
24
- `);for(let t=n.length-1;t>=0;t--){let r=n[t];if(!(!r||!r.trim()))try{let o=JSON.parse(r).seq;if(typeof o=="number"&&Number.isFinite(o)&&o>=0)return Math.floor(o)+1}catch{continue}}return 1}function Pt(e,n,t,r){return{kind:"meta",v:Qo,session:ie(e),started:r,branch:n,worktree:t}}function ge(e,n,t){let r=[{kind:"run",moment:e,subjects:t,rules:n.tallies}];for(let o of n.effects)o.do==="block"?r.push({kind:"guardrail",moment:e,id:o.entry,subject:o.subject,out:"deny",message:o.message,detail:o.detail}):r.push({kind:"breadcrumb",moment:e,id:o.entry,cause:o.cause});return r}function Fe(e){return e.map(n=>{let t=n.spec,r=t.kind==="guardrail"?t.message??null:t.text??t.file??null;return{kind:t.kind,id:n.id,pack:n.pack,at:[...t.at??[]],on:t.on,ignore:t.ignore,for:[...n.categories],description:t.description??null,says:r,disabled:t.disabled?t.disabled.reason??"":null}})}var yt=864e5;var Xo=()=>({median:null,buckets:{0:0,"1-5":0,"6-19":0,"20+":0},noEdit:0});function es(e){return e<=0?"0":e<=5?"1-5":e<=19?"6-19":"20+"}function ns(e){if(e.length===0)return null;let n=[...e].sort((r,o)=>r-o),t=Math.floor(n.length/2);return n.length%2?n[t]:(n[t-1]+n[t])/2}function mt(e,n){let t={0:0,"1-5":0,"6-19":0,"20+":0};for(let r of e)t[es(r)]+=1;return{median:ns(e),buckets:t,noEdit:n}}var ht=e=>e.includes("/")?e.slice(0,e.lastIndexOf("/")):".";function Ge(e){return e!==""&&!e.startsWith("/")&&!e.startsWith("..")}function A(e,n){let t=e[n];return typeof t=="string"&&t!==""?t:null}function mn(e){return A(e,"subject")??A(e,"path")??A(e,"command")}function ts(e){return e.kind==="tool"&&e.edit===!0&&mn(e)!==null&&A(e,"path")!==null}function Tt({sessions:e,entries:n,nowMs:t,minSessions:r=15,minDays:o=30}){let s=n.filter(f=>f.disabled===null),i=new Map(s.map(f=>[f.id,f])),a=je(n),d=new Map,l=new Map,c={},u={},p={},g=[],m=f=>{let k=d.get(f);return k===void 0&&(k={count:0,byCause:Object.fromEntries(dn.map(F=>[F,0])),last:null,samples:[],noEdit:0},d.set(f,k)),k},w=f=>{let k=l.get(f);return k===void 0&&(k={runs:0,evaluated:0,hits:0,silenced:0,sessions:new Set,lastBlock:null,lastHit:null,repeats:0},l.set(f,k)),k},$=0,h=0;for(let{session:f,rows:k}of e){let F=[],ce=[],X=new Set,ee=0;for(let E of k){let _=A(E,"ts");if(_!==null&&g.push(_),E.kind==="tool"){ee+=1,h+=1;let R=A(E,"path");if(R===null||!Ge(R)||(c[R]=(c[R]??0)+1,!ts(E)))continue;u[R]=(u[R]??0)+1,F.push({at:ee,path:R}),a.some(v=>he(v,R))||(p[R]=(p[R]??0)+1);continue}if(E.kind==="compaction"){X.clear();continue}if(E.kind==="breadcrumb"){let R=A(E,"id");if(R===null)continue;let v=m(R);v.count+=1;let M=A(E,"cause");M!==null&&dn.includes(M)&&(v.byCause[M]+=1),_!==null&&(v.last===null||_>v.last)&&(v.last=_),A(E,"moment")==="touch"&&(i.get(R)?.on?.length??0)>0&&ce.push({id:R,at:ee});continue}if(E.kind==="run"){let R=E.rules??[];for(let v of R){if(typeof v?.id!="string")continue;let M=w(v.id);M.runs+=1,M.evaluated+=v.evaluated??0,M.silenced+=v.silenced??0,M.sessions.add(f)}continue}if(E.kind==="guardrail"&&E.out==="deny"){let R=A(E,"id");if(R===null)continue;let v=w(R);v.hits+=1,$+=1;let M=mn(E);v.lastBlock={ts:_,subject:M},_!==null&&(v.lastHit===null||_>v.lastHit)&&(v.lastHit=_);let Zn=`${R} ${M??""}`;X.has(Zn)?v.repeats+=1:X.add(Zn)}}for(let E of ce){let _=i.get(E.id),R=_===void 0?void 0:F.find(M=>M.at>=E.at&&he(_,M.path)),v=m(E.id);R===void 0?v.noEdit+=1:v.samples.push(R.at-E.at)}}let T=[...g].sort(),y=T[0]??null,O=T[T.length-1]??null,C=e.filter(f=>f.session!=="commit"&&f.rows.length>0).length,b=y!==null&&O!==null?Math.round((Date.parse(O)-Date.parse(y))/yt):0,x=C>=r||b>=o,I=new Set;for(let f of s)f.kind==="breadcrumb"&&(d.get(f.id)?.count??0)>0&&I.add(f.pack);let V=s.filter(f=>f.kind==="breadcrumb").map(f=>{let k=d.get(f.id);return{id:f.id,pack:f.pack,shown:k?.count??0,byCause:k?.byCause??Object.fromEntries(dn.map(F=>[F,0])),lead:k===void 0?Xo():mt(k.samples,k.noEdit),last:k?.last??null,dead:x&&(f.on?.length??0)>0&&(k?.count??0)===0&&I.has(f.pack)}}),ve=s.filter(f=>f.kind==="guardrail").map(f=>{let k=l.get(f.id),F=k?.runs??0,ce=k?.evaluated??0;return{id:f.id,pack:f.pack,runs:F,evaluated:ce,hits:k?.hits??0,silenced:k?.silenced??0,lastBlock:k?.lastBlock??null,repeats:k?.repeats??0,dead:x&&(f.on?.length??0)>0&&F>0&&ce===0}}),Z=new Map;for(let[f,k]of Object.entries(p))Z.set(ht(f),(Z.get(ht(f))??0)+k);let Jn=[...Z.entries()].map(([f,k])=>({area:f,edits:k})).sort((f,k)=>k.edits-f.edits||f.area.localeCompare(k.area)),zn=[],Yn=[],Qn=[];for(let f of s){let k=l.get(f.id),F=d.get(f.id);if((k?.evaluated??0)+(F?.count??0)===0){(x?zn:Yn).push(f.id);continue}let X=k?.lastHit??null;if(X===null)continue;let ee=Math.round((t-Date.parse(X))/yt);x&&Number.isFinite(ee)&&ee>o&&Qn.push({id:f.id,lastHit:X,daysSince:ee})}let Jr=[...d.values()].flatMap(f=>f.samples),zr=[...d.values()].reduce((f,k)=>f+k.noEdit,0),Yr=[...V,...ve].filter(f=>f.dead).map(f=>f.id).sort();return{headline:{blocks:$,lead:mt(Jr,zr),gaps:Jn,dead:Yr,retire:zn.sort(),unproven:Yn.sort(),quiet:Qn.sort((f,k)=>k.daysSince-f.daysSince)},breadcrumbs:V,guardrails:ve,gaps:Jn,span:{sessions:C,days:b,first:y,last:O,ample:x,tools:h},heat:{touches:c,edits:u,uncovered:p}}}function At({paths:e,heat:n,entries:t}){let r=new Set([...e,...Object.keys(n.touches),...Object.keys(n.edits)]),o=je(t),s=new Map,i=(a,d)=>{let l=s.get(a);return l===void 0&&(l={path:a,name:a.slice(a.lastIndexOf("/")+1),dir:d,depth:a.split("/").length-1,touches:0,edits:0,entries:[],uncovered:0},s.set(a,l)),l};for(let a of r){let d=a.split("/"),l=o.filter(g=>he(g,a)).map(g=>g.id),c=n.touches[a]??0,u=n.edits[a]??0,p=n.uncovered[a]??0;for(let g=0;g<d.length;g++){let m=d.slice(0,g+1).join("/"),w=i(m,g<d.length-1);w.touches+=c,w.edits+=u,w.uncovered+=p;for(let $ of l)w.entries.includes($)||w.entries.push($)}}for(let a of s.values())a.entries.sort();return[...s.values()].sort(rs)}function rs(e,n){let t=e.path.split("/"),r=n.path.split("/");for(let o=0;o<Math.min(t.length,r.length);o++){let s=t[o],i=r[o];if(s===i)continue;let a=o===t.length-1&&!e.dir,d=o===r.length-1&&!n.dir;return a!==d?a?1:-1:s.localeCompare(i)}return t.length-r.length}var os=["session","touch","write","delete","command","commit","turn-end"];function Ie(e,n){let t=new Map((n?.breadcrumbs??[]).map(s=>[s.id,s])),r=new Map((n?.guardrails??[]).map(s=>[s.id,s])),o=e.map(s=>({...s,record:(s.kind==="breadcrumb"?t.get(s.id):r.get(s.id))??null}));return{moments:os.map(s=>({moment:s,entries:o.filter(i=>i.at.includes(s))})).filter(s=>s.entries.length>0),totals:{breadcrumbs:o.filter(s=>s.kind==="breadcrumb").length,guardrails:o.filter(s=>s.kind==="guardrail").length,disabled:o.filter(s=>s.disabled!==null).length}}}var Mt=1;function hn(e,n=""){let t=n,r=Mt,o=[];for(let s of e.split(`
25
- `)){if(s.trim()==="")continue;let i;try{i=JSON.parse(s)}catch{continue}if(typeof i!="object"||i===null||Array.isArray(i))continue;let a=i;if(typeof a.v=="number"){r=a.v,typeof a.session=="string"&&(t=a.session);continue}(a.rail==="guard"||a.rail==="brief"||a.rail==="compaction")&&o.push(a)}return{v:r,session:t,steps:o}}function jt(e){return{v:Mt,session:e}}async function Nt({load:e,recording:n,settings:t,marks:r={}}){let o=[],s=[],i=[],a=r;for(let d of n.steps){if(d.rail==="compaction"){a=e.ok?un(a,e.entries):a;let u={kind:"compaction"};s.push(u),o.push({step:d,effects:[],rows:[u]});continue}if(d.rail==="guard"){let u=await Ne({load:e,event:{moment:d.moment,file:d.file,command:d.command,staged:d.staged,turn:d.turn,wearing:d.wearing},world:Oe(d.world??{},d.staged,i)}),p=ge(d.moment,u,d.moment==="commit"?d.staged?.length??0:1);s.push(...p),o.push({step:d,effects:u.effects,rows:p});continue}let l=cn({load:e,event:{moment:d.moment,path:d.path,command:d.command,wearing:d.wearing,tokens:d.tokens},marks:a,settings:t});a=l.marks;let c=l.notices.length===0?[]:ge(d.moment,{effects:l.notices,tallies:[]},1);s.push(...c),o.push({step:d,effects:l.notices,rows:c})}return{steps:o,rows:s,unanswered:i,marks:a}}function _t(e,n){let t=i=>i.filter(a=>a.kind==="guardrail"||a.kind==="breadcrumb").map(a=>a.kind==="guardrail"?`guardrail ${A(a,"moment")??""} ${A(a,"id")??"\u2014"} ${a.out} ${mn(a)??""}`.trim():`breadcrumb ${A(a,"moment")??""} ${A(a,"id")??"\u2014"} ${A(a,"cause")??""}`.trim()),r=t(e),o=t(n),s=[];for(let i=0;i<Math.max(r.length,o.length);i++){let a=r[i],d=o[i];a!==d&&(a!==void 0&&s.push({side:"replay",at:i,row:a}),d!==void 0&&s.push({side:"live",at:i,row:d}))}return s}function kn(e){let n={},t={},r,o;return{world:{exec:async s=>{let i=await e.exec(s);return n[s]={stdout:i.stdout,stderr:i.stderr,code:i.code},i},fs:{read:async s=>{let i=await e.fs.read(s);return t[s]=i,i},exists:async s=>{let i=await e.fs.exists(s);return i&&(t[s]??=""),i}},git:{diff:async s=>{let i=await e.git.diff(s);return r??=i,i},stagedFiles:async()=>{let s=await e.git.stagedFiles();return o=[...s],s}}},taken:()=>({...Object.keys(n).length>0?{exec:n}:{},...Object.keys(t).length>0?{fs:t}:{},...r===void 0?{}:{gitDiff:r},...o===void 0?{}:{staged:o}})}}import{appendFileSync as Ft,closeSync as ss,existsSync as ke,mkdirSync as be,openSync as is,readFileSync as Be,readSync as as,readdirSync as Gt,statSync as ds,writeFileSync as pe}from"node:fs";import{dirname as wn,join as ls}from"node:path";function ae(e){try{let n=B(e);be(n,{recursive:!0});let t=`${n}/.gitignore`;return ke(t)||pe(t,St),!0}catch{return!1}}function we(e){try{return ke(Rt(e))}catch{return!1}}function De(e,n,t){try{return pn(Be(gn(e,n,t),"utf8"))}catch{return pn(null)}}function xn(e,n,t,r){try{let o=gn(e,n,t);return ae(e),be(wn(o),{recursive:!0}),pe(o,JSON.stringify(r)),!0}catch{return!1}}function It(e,n,t,r,o){let s=De(e,n,t),i=bt(s.categories,r,o);return i.fresh&&i.faults.length===0&&xn(e,n,t,{...s,categories:i.wearing}),i}var cs=4096,bn=new Map;function us(e){let n=null;try{let t=ds(e).size,r=Math.min(t,cs);if(r<=0)return"";let o=Buffer.alloc(r);return n=is(e,"r"),as(n,o,0,r,t-r),o.toString("utf8")}catch{return""}finally{if(n!==null)try{ss(n)}catch{}}}function Sn(e,n){try{if(n.length===0)return!0;let{root:t,session:r,branch:o}=e,s=e.now??(()=>new Date),i=fn(t,r);ae(t),be(wn(i),{recursive:!0}),ke(i)||(pe(i,`${JSON.stringify(Pt(r,o,t,s().toISOString()))}
26
- `),bn.set(i,1));let a=bn.get(i)??Ot(us(i)),d="";for(let l of n)d+=`${JSON.stringify({ts:s().toISOString(),seq:a,...l})}
27
- `,a+=1;return bn.set(i,a),Ft(i,d),!0}catch{return!1}}function Rn(e){let n=[];try{let t=Be(e,"utf8");for(let r of t.split(`
28
- `))if(r.trim())try{let o=JSON.parse(r);typeof o.kind=="string"&&n.push(o)}catch{continue}}catch{}return n}function fs(e,n){return Rn(fn(e,n))}function gs(e){try{return Gt(ls(B(e),"log")).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort()}catch{return[]}}function Bt(e){return gs(e).map(n=>({session:n,rows:fs(e,n)}))}function Dt(e){try{return new Set(Gt(_e(e)).filter(n=>!n.startsWith(".")))}catch{return new Set}}function Lt(e,n){try{ae(e),be(_e(e),{recursive:!0})}catch{return 0}let t=0;for(let r of n)try{pe(Et(e,r),""),t+=1}catch{}return t}function $n(e){try{return ke($t(e))}catch{return!1}}function vn(e,n,t){try{if(t.length===0)return!0;let r=vt(e,n);return ae(e),be(wn(r),{recursive:!0}),ke(r)||pe(r,`${JSON.stringify(jt(n))}
29
- `),Ft(r,`${t.map(o=>JSON.stringify(o)).join(`
23
+ `,os=1;function B(e){return W(e,z)}function ie(e){return(e||"nosession").replace(/[^A-Za-z0-9_-]/g,"-")}function gn(e,n){return W(B(e),"log",`${ie(n)}.jsonl`)}function pn(e,n,t){return W(B(e),"state",`${ie(n)}-${ie(t)}.json`)}function yn(e){if(e==null||e.trim()==="")return{marks:{}};let n;try{n=JSON.parse(e)}catch{return{marks:{}}}if(typeof n!="object"||n===null)return{marks:{}};let t=n,r=Array.isArray(t.categories)&&t.categories.every(s=>typeof s=="string")?t.categories:void 0,o={};if(typeof t.marks=="object"&&t.marks!==null)for(let[s,i]of Object.entries(t.marks))typeof i=="number"&&Number.isFinite(i)&&(o[s]=i);return r===void 0?{marks:o}:{categories:r,marks:o}}function mn(e,n){return W(B(e),n?`.session-${ie(n)}`:".session")}function Ot(e){return W(B(e),"off")}function Pt(e){return W(B(e),"record")}function Tt(e,n){return W(B(e),"replay",`${ie(n)}.jsonl`)}function _e(e){return W(B(e),"read")}function At(e,n){return W(_e(e),ie(n))}var ss=14400*1e3;function jt(e,n,t,r=ss){let o={session:n,agent:null};if(!e||typeof e.session!="string"||!e.session)return o;let s=Date.parse(String(e.ts));return!Number.isFinite(s)||Math.abs(t-s)>r?o:{session:e.session,agent:typeof e.agent=="string"&&e.agent?e.agent:null}}function Mt(e){let n=e.split(`
24
+ `);for(let t=n.length-1;t>=0;t--){let r=n[t];if(!(!r||!r.trim()))try{let o=JSON.parse(r).seq;if(typeof o=="number"&&Number.isFinite(o)&&o>=0)return Math.floor(o)+1}catch{continue}}return 1}function Nt(e,n,t,r){return{kind:"meta",v:os,session:ie(e),started:r,branch:n,worktree:t}}function ge(e,n,t){let r=[{kind:"run",moment:e,subjects:t,rules:n.tallies}];for(let o of n.effects)o.do==="block"?r.push({kind:"guardrail",moment:e,id:o.entry,subject:o.subject,out:"deny",message:o.message,detail:o.detail}):r.push({kind:"breadcrumb",moment:e,id:o.entry,cause:o.cause});return r}function Fe(e){return e.map(n=>{let t=n.spec,r=t.kind==="guardrail"?t.message??null:t.text??t.file??null;return{kind:t.kind,id:n.id,pack:n.pack,at:[...t.at??[]],on:t.on,ignore:t.ignore,for:[...n.categories],description:t.description??null,says:r,disabled:t.disabled?t.disabled.reason??"":null}})}var wt=864e5;var is=()=>({median:null,buckets:{0:0,"1-5":0,"6-19":0,"20+":0},noEdit:0});function as(e){return e<=0?"0":e<=5?"1-5":e<=19?"6-19":"20+"}function ds(e){if(e.length===0)return null;let n=[...e].sort((r,o)=>r-o),t=Math.floor(n.length/2);return n.length%2?n[t]:(n[t-1]+n[t])/2}function xt(e,n){let t={0:0,"1-5":0,"6-19":0,"20+":0};for(let r of e)t[as(r)]+=1;return{median:ds(e),buckets:t,noEdit:n}}var St=e=>e.includes("/")?e.slice(0,e.lastIndexOf("/")):".";function Ie(e){return e!==""&&!e.startsWith("/")&&!e.startsWith("..")}function A(e,n){let t=e[n];return typeof t=="string"&&t!==""?t:null}function hn(e){return A(e,"subject")??A(e,"path")??A(e,"command")}function ls(e){return e.kind==="tool"&&e.edit===!0&&hn(e)!==null&&A(e,"path")!==null}function Gt({sessions:e,entries:n,nowMs:t,minSessions:r=15,minDays:o=30}){let s=n.filter(f=>f.disabled===null),i=new Map(s.map(f=>[f.id,f])),a=Ne(n),d=new Map,l=new Map,c={},u={},p={},g=[],m=f=>{let k=d.get(f);return k===void 0&&(k={count:0,byCause:Object.fromEntries(ln.map(_=>[_,0])),last:null,samples:[],noEdit:0},d.set(f,k)),k},w=f=>{let k=l.get(f);return k===void 0&&(k={runs:0,evaluated:0,hits:0,silenced:0,sessions:new Set,lastBlock:null,lastHit:null,repeats:0},l.set(f,k)),k},$=0,h=0;for(let{session:f,rows:k}of e){let _=[],ce=[],X=new Set,ee=0;for(let E of k){let G=A(E,"ts");if(G!==null&&g.push(G),E.kind==="tool"){ee+=1,h+=1;let R=A(E,"path");if(R===null||!Ie(R)||(c[R]=(c[R]??0)+1,!ls(E)))continue;u[R]=(u[R]??0)+1,_.push({at:ee,path:R}),a.some(v=>he(v,R))||(p[R]=(p[R]??0)+1);continue}if(E.kind==="compaction"){X.clear();continue}if(E.kind==="breadcrumb"){let R=A(E,"id");if(R===null)continue;let v=m(R);v.count+=1;let j=A(E,"cause");j!==null&&ln.includes(j)&&(v.byCause[j]+=1),G!==null&&(v.last===null||G>v.last)&&(v.last=G),A(E,"moment")==="touch"&&(i.get(R)?.on?.length??0)>0&&ce.push({id:R,at:ee});continue}if(E.kind==="run"){let R=E.rules??[];for(let v of R){if(typeof v?.id!="string")continue;let j=w(v.id);j.runs+=1,j.evaluated+=v.evaluated??0,j.silenced+=v.silenced??0,j.sessions.add(f)}continue}if(E.kind==="guardrail"&&E.out==="deny"){let R=A(E,"id");if(R===null)continue;let v=w(R);v.hits+=1,$+=1;let j=hn(E);v.lastBlock={ts:G,subject:j},G!==null&&(v.lastHit===null||G>v.lastHit)&&(v.lastHit=G);let Xn=`${R} ${j??""}`;X.has(Xn)?v.repeats+=1:X.add(Xn)}}for(let E of ce){let G=i.get(E.id),R=G===void 0?void 0:_.find(j=>j.at>=E.at&&he(G,j.path)),v=m(E.id);R===void 0?v.noEdit+=1:v.samples.push(R.at-E.at)}}let T=[...g].sort(),y=T[0]??null,O=T[T.length-1]??null,C=e.filter(f=>f.session!=="commit"&&f.rows.length>0).length,b=y!==null&&O!==null?Math.round((Date.parse(O)-Date.parse(y))/wt):0,x=C>=r||b>=o,I=new Set;for(let f of s)f.kind==="breadcrumb"&&(d.get(f.id)?.count??0)>0&&I.add(f.pack);let V=s.filter(f=>f.kind==="breadcrumb").map(f=>{let k=d.get(f.id);return{id:f.id,pack:f.pack,shown:k?.count??0,byCause:k?.byCause??Object.fromEntries(ln.map(_=>[_,0])),lead:k===void 0?is():xt(k.samples,k.noEdit),last:k?.last??null,dead:x&&(f.on?.length??0)>0&&(k?.count??0)===0&&I.has(f.pack)}}),ve=s.filter(f=>f.kind==="guardrail").map(f=>{let k=l.get(f.id),_=k?.runs??0,ce=k?.evaluated??0;return{id:f.id,pack:f.pack,runs:_,evaluated:ce,hits:k?.hits??0,silenced:k?.silenced??0,lastBlock:k?.lastBlock??null,repeats:k?.repeats??0,dead:x&&(f.on?.length??0)>0&&_>0&&ce===0}}),Z=new Map;for(let[f,k]of Object.entries(p))Z.set(St(f),(Z.get(St(f))??0)+k);let zn=[...Z.entries()].map(([f,k])=>({area:f,edits:k})).sort((f,k)=>k.edits-f.edits||f.area.localeCompare(k.area)),Yn=[],Qn=[],Zn=[];for(let f of s){let k=l.get(f.id),_=d.get(f.id);if((k?.evaluated??0)+(_?.count??0)===0){(x?Yn:Qn).push(f.id);continue}let X=k?.lastHit??null;if(X===null)continue;let ee=Math.round((t-Date.parse(X))/wt);x&&Number.isFinite(ee)&&ee>o&&Zn.push({id:f.id,lastHit:X,daysSince:ee})}let Xr=[...d.values()].flatMap(f=>f.samples),eo=[...d.values()].reduce((f,k)=>f+k.noEdit,0),no=[...V,...ve].filter(f=>f.dead).map(f=>f.id).sort();return{headline:{blocks:$,lead:xt(Xr,eo),gaps:zn,dead:no,retire:Yn.sort(),unproven:Qn.sort(),quiet:Zn.sort((f,k)=>k.daysSince-f.daysSince)},breadcrumbs:V,guardrails:ve,gaps:zn,span:{sessions:C,days:b,first:y,last:O,ample:x,tools:h},heat:{touches:c,edits:u,uncovered:p}}}function _t({paths:e,heat:n,entries:t}){let r=new Set([...e,...Object.keys(n.touches),...Object.keys(n.edits)]),o=Ne(t),s=new Map,i=(a,d)=>{let l=s.get(a);return l===void 0&&(l={path:a,name:a.slice(a.lastIndexOf("/")+1),dir:d,depth:a.split("/").length-1,touches:0,edits:0,entries:[],uncovered:0},s.set(a,l)),l};for(let a of r){let d=a.split("/"),l=o.filter(g=>he(g,a)).map(g=>g.id),c=n.touches[a]??0,u=n.edits[a]??0,p=n.uncovered[a]??0;for(let g=0;g<d.length;g++){let m=d.slice(0,g+1).join("/"),w=i(m,g<d.length-1);w.touches+=c,w.edits+=u,w.uncovered+=p;for(let $ of l)w.entries.includes($)||w.entries.push($)}}for(let a of s.values())a.entries.sort();return[...s.values()].sort(cs)}function cs(e,n){let t=e.path.split("/"),r=n.path.split("/");for(let o=0;o<Math.min(t.length,r.length);o++){let s=t[o],i=r[o];if(s===i)continue;let a=o===t.length-1&&!e.dir,d=o===r.length-1&&!n.dir;return a!==d?a?1:-1:s.localeCompare(i)}return t.length-r.length}var us=["session","touch","write","delete","command","commit","turn-end"];function Be(e,n){let t=new Map((n?.breadcrumbs??[]).map(s=>[s.id,s])),r=new Map((n?.guardrails??[]).map(s=>[s.id,s])),o=e.map(s=>({...s,record:(s.kind==="breadcrumb"?t.get(s.id):r.get(s.id))??null}));return{moments:us.map(s=>({moment:s,entries:o.filter(i=>i.at.includes(s))})).filter(s=>s.entries.length>0),totals:{breadcrumbs:o.filter(s=>s.kind==="breadcrumb").length,guardrails:o.filter(s=>s.kind==="guardrail").length,disabled:o.filter(s=>s.disabled!==null).length}}}var Ft=1;function kn(e,n=""){let t=n,r=Ft,o=[];for(let s of e.split(`
25
+ `)){if(s.trim()==="")continue;let i;try{i=JSON.parse(s)}catch{continue}if(typeof i!="object"||i===null||Array.isArray(i))continue;let a=i;if(typeof a.v=="number"){r=a.v,typeof a.session=="string"&&(t=a.session);continue}(a.rail==="guard"||a.rail==="brief"||a.rail==="compaction")&&o.push(a)}return{v:r,session:t,steps:o}}function It(e){return{v:Ft,session:e}}async function Bt({load:e,recording:n,settings:t,marks:r={}}){let o=[],s=[],i=[],a=r;for(let d of n.steps){if(d.rail==="compaction"){a=e.ok?fn(a,e.entries):a;let u={kind:"compaction"};s.push(u),o.push({step:d,effects:[],rows:[u]});continue}if(d.rail==="guard"){let u=await Ge({load:e,event:{moment:d.moment,file:d.file,command:d.command,staged:d.staged,turn:d.turn,wearing:d.wearing},world:Oe(d.world??{},d.staged,i)}),p=ge(d.moment,u,d.moment==="commit"?d.staged?.length??0:1);s.push(...p),o.push({step:d,effects:u.effects,rows:p});continue}let l=un({load:e,event:{moment:d.moment,path:d.path,command:d.command,wearing:d.wearing,tokens:d.tokens},marks:a,settings:t});a=l.marks;let c=l.notices.length===0?[]:ge(d.moment,{effects:l.notices,tallies:[]},1);s.push(...c),o.push({step:d,effects:l.notices,rows:c})}return{steps:o,rows:s,unanswered:i,marks:a}}function Dt(e,n){let t=i=>i.filter(a=>a.kind==="guardrail"||a.kind==="breadcrumb").map(a=>a.kind==="guardrail"?`guardrail ${A(a,"moment")??""} ${A(a,"id")??"\u2014"} ${a.out} ${hn(a)??""}`.trim():`breadcrumb ${A(a,"moment")??""} ${A(a,"id")??"\u2014"} ${A(a,"cause")??""}`.trim()),r=t(e),o=t(n),s=[];for(let i=0;i<Math.max(r.length,o.length);i++){let a=r[i],d=o[i];a!==d&&(a!==void 0&&s.push({side:"replay",at:i,row:a}),d!==void 0&&s.push({side:"live",at:i,row:d}))}return s}function bn(e){let n={},t={},r,o;return{world:{exec:async s=>{let i=await e.exec(s);return n[s]={stdout:i.stdout,stderr:i.stderr,code:i.code},i},fs:{read:async s=>{let i=await e.fs.read(s);return t[s]=i,i},exists:async s=>{let i=await e.fs.exists(s);return i&&(t[s]??=""),i}},git:{diff:async s=>{let i=await e.git.diff(s);return r??=i,i},stagedFiles:async()=>{let s=await e.git.stagedFiles();return o=[...s],s}}},taken:()=>({...Object.keys(n).length>0?{exec:n}:{},...Object.keys(t).length>0?{fs:t}:{},...r===void 0?{}:{gitDiff:r},...o===void 0?{}:{staged:o}})}}import{appendFileSync as Lt,closeSync as fs,existsSync as ke,mkdirSync as be,openSync as gs,readFileSync as De,readSync as ps,readdirSync as Wt,statSync as ys,writeFileSync as pe}from"node:fs";import{dirname as xn,join as ms}from"node:path";function ae(e){try{let n=B(e);be(n,{recursive:!0});let t=`${n}/.gitignore`;return ke(t)||pe(t,Ct),!0}catch{return!1}}function we(e){try{return ke(Ot(e))}catch{return!1}}function Le(e,n,t){try{return yn(De(pn(e,n,t),"utf8"))}catch{return yn(null)}}function Sn(e,n,t,r){try{let o=pn(e,n,t);return ae(e),be(xn(o),{recursive:!0}),pe(o,JSON.stringify(r)),!0}catch{return!1}}function Ht(e,n,t,r,o){let s=Le(e,n,t),i=$t(s.categories,r,o);return i.fresh&&i.faults.length===0&&Sn(e,n,t,{...s,categories:i.wearing}),i}var hs=4096,wn=new Map;function ks(e){let n=null;try{let t=ys(e).size,r=Math.min(t,hs);if(r<=0)return"";let o=Buffer.alloc(r);return n=gs(e,"r"),ps(n,o,0,r,t-r),o.toString("utf8")}catch{return""}finally{if(n!==null)try{fs(n)}catch{}}}function Rn(e,n){try{if(n.length===0)return!0;let{root:t,session:r,branch:o}=e,s=e.now??(()=>new Date),i=gn(t,r);ae(t),be(xn(i),{recursive:!0}),ke(i)||(pe(i,`${JSON.stringify(Nt(r,o,t,s().toISOString()))}
26
+ `),wn.set(i,1));let a=wn.get(i)??Mt(ks(i)),d="";for(let l of n)d+=`${JSON.stringify({ts:s().toISOString(),seq:a,...l})}
27
+ `,a+=1;return wn.set(i,a),Lt(i,d),!0}catch{return!1}}function $n(e){let n=[];try{let t=De(e,"utf8");for(let r of t.split(`
28
+ `))if(r.trim())try{let o=JSON.parse(r);typeof o.kind=="string"&&n.push(o)}catch{continue}}catch{}return n}function bs(e,n){return $n(gn(e,n))}function ws(e){try{return Wt(ms(B(e),"log")).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort()}catch{return[]}}function Ut(e){return ws(e).map(n=>({session:n,rows:bs(e,n)}))}function Kt(e){try{return new Set(Wt(_e(e)).filter(n=>!n.startsWith(".")))}catch{return new Set}}function Vt(e,n){try{ae(e),be(_e(e),{recursive:!0})}catch{return 0}let t=0;for(let r of n)try{pe(At(e,r),""),t+=1}catch{}return t}function vn(e){try{return ke(Pt(e))}catch{return!1}}function En(e,n,t){try{if(t.length===0)return!0;let r=Tt(e,n);return ae(e),be(xn(r),{recursive:!0}),ke(r)||pe(r,`${JSON.stringify(It(n))}
29
+ `),Lt(r,`${t.map(o=>JSON.stringify(o)).join(`
30
30
  `)}
31
- `),!0}catch{return!1}}function Wt(e){let n=e.slice(e.lastIndexOf("/")+1).replace(/\.jsonl$/,"");try{return hn(Be(e,"utf8"),n)}catch{return hn("",n)}}function Ht(e,n,t,r,o=new Date){try{return ae(e),pe(yn(e,r),`${JSON.stringify({session:n,agent:t,ts:o.toISOString()})}
32
- `),!0}catch{return!1}}function Ut(e,n,t=Date.now()){let r=null;try{r=JSON.parse(Be(yn(e,n),"utf8"))}catch{}return Ct(r,"commit",t)}var P="flow.config.ts";function ps(e){let n=[];for(let[,,t]of e.matchAll(/\b(?:from|import)\s*\(?\s*(['"])([^'"\n]+)\1/g)){if(t===void 0||!t.startsWith("."))continue;let r=t.replace(/^\.\//,"");r===""||r.split("/").includes("..")||n.includes(r)||n.push(r)}return n}function Cn(e){let n=[P];for(let t of ps(e??"")){n.includes(t)||n.push(t);let r=t.includes("/")?`${t.slice(0,t.lastIndexOf("/"))}/**`:null;r!==null&&!n.includes(r)&&n.push(r)}return n}var On=["session-start","pre-tool-use","post-tool-use","stop","notification"];function Pn(e){return On.includes(e)}var Vt={"session-start":"SessionStart","pre-tool-use":"PreToolUse","post-tool-use":"PostToolUse",stop:"Stop",notification:"Notification"},We={guard:["write","delete","command","commit","turn-end"],brief:["session","touch","command"]};function S(e){return typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):""}function H(e,n){return n&&e.startsWith(`${n}/`)?e.slice(n.length+1):e}function Kt(e,{old_string:n="",new_string:t="",replace_all:r=!1}){if(n==="")return t;if(r)return e.split(n).join(t);let o=e.indexOf(n);return o===-1?null:e.slice(0,o)+t+e.slice(o+n.length)}function ys(e,n,t){let r=n.file_path;if(!r)return null;let o=H(S(r),t.root);if(e==="Write")return{path:o,content:S(n.content??"")};if(e==="Edit"){let s=Kt(t.read(o)??"",n);return s===null?null:{path:o,content:s}}if(e==="MultiEdit"){let s=t.read(o)??"";for(let i of n.edits??[])if(s=Kt(s,i),s===null)return null;return{path:o,content:s}}return null}var ms=[{words:["rm"],renames:!1},{words:["git","rm"],renames:!1},{words:["mv"],renames:!0},{words:["git","mv"],renames:!0}],hs=new Set([";","&&","||","|","&","|&",`
33
- `]);function ks(e){let n=Me(e);if(n===null)return[];let t=[],r=[],o=()=>{let s=r;r=[];for(let i of ms){if(!i.words.every((d,l)=>s[l]===d))continue;let a=s.slice(i.words.length).filter(d=>!d.startsWith("-"));t.push(...i.renames?a.length>=2?a.slice(0,-1):[]:a);return}};for(let s of n)hs.has(s)?o():r.push(s);return o(),t}function Tn(e,n,t){switch(e){case"session-start":return[{rail:"brief",moment:"session"}];case"pre-tool-use":{let r=S(n.tool_name),o=n.tool_input??{};if(!r)return[];if(r==="Bash"){let i=S(o.command);if(!i)return[];let a=[{rail:"guard",moment:"command",command:i},{rail:"brief",moment:"command",command:i}];for(let d of ks(i)){let l=H(d,t.root),c=t.read(l);c!==null&&a.push({rail:"guard",moment:"delete",file:{path:l,content:c}})}return a}let s=ys(r,o,t);return s===null?[]:[{rail:"guard",moment:"write",file:s}]}case"post-tool-use":{let r=bs(n,t.root);return r===null?[]:[{rail:"brief",moment:"touch",path:r}]}case"stop":return n.stop_hook_active===!0?[]:[{rail:"guard",moment:"turn-end",turn:t.turn?.()??[]}];case"notification":return[]}}function bs(e,n){let t=e.tool_input??{},r=t.file_path??t.notebook_path??t.path??t.glob;return r?H(S(r),n):null}var D={stdout:"",stderr:"",exitCode:0},ws={write:{head:"flow \u2014 blocked before the write landed",tail:"Adjust the change so it passes, then retry."},delete:{head:"flow \u2014 blocked before the delete",tail:"Keep the file, or change the rule that protects it."},command:{head:"flow \u2014 command blocked before it ran",tail:"Adjust the command, then retry."},commit:{head:"flow \u2014 commit blocked",tail:"Fix the above, then commit again."},"turn-end":{head:"flow \u2014 turn held open",tail:"Do the above, then end your turn."}};function xs(e,n){return e.rail!=="guard"||e.moment!=="write"&&e.moment!=="delete"?!1:e.file!==void 0&&j(e.file.path,n)}function qt(e,n,t){let r=e.filter(o=>o.rail==="guard");return{refused:r.filter(o=>o.moment!=="turn-end"&&!xs(o,n)).map(o=>({moment:o.moment,block:se(t)})),shown:e.filter(o=>o.rail==="brief").map(()=>({entry:null,cause:"fault",body:t})),told:r.some(o=>o.moment==="turn-end")?t:null}}function Jt(e){return e.refusals.length>0?2:e.green?0:1}function Ss(e){return e.filter(n=>n.body.trim()!=="").map(n=>`# breadcrumb: ${n.entry??"flow"} (${n.cause})
31
+ `),!0}catch{return!1}}function qt(e){let n=e.slice(e.lastIndexOf("/")+1).replace(/\.jsonl$/,"");try{return kn(De(e,"utf8"),n)}catch{return kn("",n)}}function Jt(e,n,t,r,o=new Date){try{return ae(e),pe(mn(e,r),`${JSON.stringify({session:n,agent:t,ts:o.toISOString()})}
32
+ `),!0}catch{return!1}}function zt(e,n,t=Date.now()){let r=null;try{r=JSON.parse(De(mn(e,n),"utf8"))}catch{}return jt(r,"commit",t)}var P="flow.config.ts";function xs(e){let n=[];for(let[,,t]of e.matchAll(/\b(?:from|import)\s*\(?\s*(['"])([^'"\n]+)\1/g)){if(t===void 0||!t.startsWith("."))continue;let r=t.replace(/^\.\//,"");r===""||r.split("/").includes("..")||n.includes(r)||n.push(r)}return n}function On(e){let n=[P];for(let t of xs(e??"")){n.includes(t)||n.push(t);let r=t.includes("/")?`${t.slice(0,t.lastIndexOf("/"))}/**`:null;r!==null&&!n.includes(r)&&n.push(r)}return n}var Pn=["session-start","pre-tool-use","post-tool-use","stop","notification"];function Tn(e){return Pn.includes(e)}var Qt={"session-start":"SessionStart","pre-tool-use":"PreToolUse","post-tool-use":"PostToolUse",stop:"Stop",notification:"Notification"},He={guard:["write","delete","command","commit","turn-end"],brief:["session","touch","command"]};function S(e){return typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):""}function H(e,n){return n&&e.startsWith(`${n}/`)?e.slice(n.length+1):e}function Yt(e,{old_string:n="",new_string:t="",replace_all:r=!1}){if(n==="")return t;if(r)return e.split(n).join(t);let o=e.indexOf(n);return o===-1?null:e.slice(0,o)+t+e.slice(o+n.length)}function Ss(e,n,t){let r=n.file_path;if(!r)return null;let o=H(S(r),t.root);if(e==="Write")return{path:o,content:S(n.content??"")};if(e==="Edit"){let s=Yt(t.read(o)??"",n);return s===null?null:{path:o,content:s}}if(e==="MultiEdit"){let s=t.read(o)??"";for(let i of n.edits??[])if(s=Yt(s,i),s===null)return null;return{path:o,content:s}}return null}var Rs=[{words:["rm"],renames:!1},{words:["git","rm"],renames:!1},{words:["mv"],renames:!0},{words:["git","mv"],renames:!0}],$s=new Set([";","&&","||","|","&","|&",`
33
+ `]);function vs(e){let n=je(e);if(n===null)return[];let t=[],r=[],o=()=>{let s=r;r=[];for(let i of Rs){if(!i.words.every((d,l)=>s[l]===d))continue;let a=s.slice(i.words.length).filter(d=>!d.startsWith("-"));t.push(...i.renames?a.length>=2?a.slice(0,-1):[]:a);return}};for(let s of n)$s.has(s)?o():r.push(s);return o(),t}function An(e,n,t){switch(e){case"session-start":return[{rail:"brief",moment:"session"}];case"pre-tool-use":{let r=S(n.tool_name),o=n.tool_input??{};if(!r)return[];if(r==="Bash"){let i=S(o.command);if(!i)return[];let a=[{rail:"guard",moment:"command",command:i},{rail:"brief",moment:"command",command:i}];for(let d of vs(i)){let l=H(d,t.root),c=t.read(l);c!==null&&a.push({rail:"guard",moment:"delete",file:{path:l,content:c}})}return a}let s=Ss(r,o,t);return s===null?[]:[{rail:"guard",moment:"write",file:s}]}case"post-tool-use":{let r=Es(n,t.root);return r===null?[]:[{rail:"brief",moment:"touch",path:r}]}case"stop":return n.stop_hook_active===!0?[]:[{rail:"guard",moment:"turn-end",turn:t.turn?.()??[]}];case"notification":return[]}}function Es(e,n){let t=e.tool_input??{},r=t.file_path??t.notebook_path??t.path??t.glob;return r?H(S(r),n):null}var D={stdout:"",stderr:"",exitCode:0},Cs={write:{head:"flow \u2014 blocked before the write landed",tail:"Adjust the change so it passes, then retry."},delete:{head:"flow \u2014 blocked before the delete",tail:"Keep the file, or change the rule that protects it."},command:{head:"flow \u2014 command blocked before it ran",tail:"Adjust the command, then retry."},commit:{head:"flow \u2014 commit blocked",tail:"Fix the above, then commit again."},"turn-end":{head:"flow \u2014 turn held open",tail:"Do the above, then end your turn."}};function Os(e,n){return e.rail!=="guard"||e.moment!=="write"&&e.moment!=="delete"?!1:e.file!==void 0&&M(e.file.path,n)}function Zt(e,n,t){let r=e.filter(o=>o.rail==="guard");return{refused:r.filter(o=>o.moment!=="turn-end"&&!Os(o,n)).map(o=>({moment:o.moment,block:se(t)})),shown:e.filter(o=>o.rail==="brief").map(()=>({entry:null,cause:"fault",body:t})),told:r.some(o=>o.moment==="turn-end")?t:null}}function Xt(e){return e.refusals.length>0?2:e.green?0:1}function Ps(e){return e.filter(n=>n.body.trim()!=="").map(n=>`# breadcrumb: ${n.entry??"flow"} (${n.cause})
34
34
  ${n.body}`).join(`
35
35
 
36
- `)}function An(e,n){let t=He(n.refused);if(t!==null)return t;let r=Ss(n.shown);return r===""?D:{stdout:Rs(e,r),stderr:"",exitCode:0}}function He(e){let n=e[0];if(n===void 0)return null;let t=ws[n.moment],r=e.map(o=>xt(o.block)).join(`
36
+ `)}function jn(e,n){let t=Ue(n.refused);if(t!==null)return t;let r=Ps(n.shown);return r===""?D:{stdout:Ts(e,r),stderr:"",exitCode:0}}function Ue(e){let n=e[0];if(n===void 0)return null;let t=Cs[n.moment],r=e.map(o=>Et(o.block)).join(`
37
37
 
38
38
  `);return{stdout:"",stderr:`
39
39
  ${t.head}:
@@ -41,12 +41,12 @@ ${t.head}:
41
41
  ${r}
42
42
 
43
43
  ${t.tail}
44
- `,exitCode:2}}function Rs(e,n){return JSON.stringify({hookSpecificOutput:{hookEventName:Vt[e],additionalContext:n}})}function zt(e,n,t){let r=n==="unreadable"?`could not READ its payload from stdin (${t})`:`could not PARSE its payload (${t})`;return`[flow hook ${e}] the guard ${r}.`}function Mn(e,n=0){let t=jn(e);if(t===null)return null;let r=S(t.timestamp);return{kind:S(t.type),record:t,line:n,ts:r===""?null:r}}function jn(e){if(e===null||e.trim()==="")return null;let n;try{n=JSON.parse(e)}catch{return null}return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:null}function Ue(e){let n=[],t=e.split(`
45
- `);for(let r=0;r<t.length;r++){let o=Mn(t[r],r+1);o!==null&&n.push(o)}return n}function $s(e){return(e?.input_tokens??0)+(e?.cache_read_input_tokens??0)+(e?.cache_creation_input_tokens??0)}function Yt(e){let n=e.split(`
46
- `);for(let t=n.length-1;t>=0;t--){let r=Mn(n[t])?.record.message;if(r?.usage)return $s(r.usage)}return 0}var Nn=new Set(["Edit","Write","MultiEdit","NotebookEdit"]),vs=["<system-reminder>","<command-name>","<command-message>","<local-command","<user-prompt-submit-hook","Caveat:","Result of calling","This session is being continued","[Request interrupted","DO NOT respond","<budget:","tool_use_id"];function Es(e){let n=e.trimStart();return vs.some(t=>n.startsWith(t))||n.slice(0,40).includes("<system-reminder>")}function _n(e){if(e.kind!=="user"||e.record.isMeta===!0)return null;let n=e.record.message?.content;return typeof n!="string"||Es(n)?null:n}function Qt(e,n=""){let t=Ue(e),r=0;for(let s=t.length-1;s>=0;s--)if(_n(t[s])!==null){r=s;break}let o=[];for(let s of t.slice(r)){let i=s.record.message?.content;if(Array.isArray(i))for(let a of i){let d=a;if(!d||d.type!=="tool_use")continue;let l=S(d.name),c=d.input??{},u=c.file_path??c.notebook_path;Nn.has(l)&&u?o.push({did:"edit",path:H(S(u),n)}):l==="Bash"&&c.command&&o.push({did:"run",command:S(c.command)})}}return o}function Cs(e,n=8e3){for(let t of e.split(`
47
- `)){let r=Mn(t),o=r===null?null:_n(r);if(o!==null)return o.slice(0,n)}return""}function Zt(e){let n=e.trim();return/^ref:\s*refs\/heads\/(.+)$/.exec(n)?.[1]??(n===""?null:n.slice(0,12))}function Xt(e){return e.endsWith(".jsonl")?`${e.slice(0,-6)}.meta.json`:null}function er(e){let n=typeof e.payload.agent_id=="string"&&e.payload.agent_id!=="",t=jn(e.sidecar),r=typeof t?.agentType=="string"?t.agentType:void 0,o=typeof t?.description=="string"?t.description:void 0;return{head:e.transcript===null?"":Cs(e.transcript),subagent:n||t!==null,...r===void 0?{}:{agentType:r},...o===void 0?{}:{description:o}}}var Os=["file_path","notebook_path"];function nr(e,n=""){let t=S(e.tool_name);if(!t)return null;let r=e.tool_input??{};for(let s of Os)if(r[s])return{kind:"tool",tool:t,path:H(S(r[s]),n),edit:Nn.has(t)};if(t==="Bash"&&r.command)return{kind:"tool",tool:t,command:S(r.command)};if(!r.pattern)return{kind:"tool",tool:t};let o=r.path?{scope:H(S(r.path),n)}:{};return{kind:"tool",tool:t,pattern:S(r.pattern),...o}}var Ps=["GIT_DIR","GIT_INDEX_FILE","GIT_WORK_TREE","GIT_PREFIX","GIT_OBJECT_DIRECTORY","GIT_COMMON_DIR","GIT_INDEX_VERSION","GIT_QUARANTINE_PATH","GIT_QUARANTINE_ID"];function tr(e){let n=new Set(Ps);return Object.fromEntries(Object.entries(e).filter(([t])=>!n.has(t)))}function rr(e){return e.replace(/[^a-zA-Z0-9]/g,"-")}function or(e){let n=new Set(e),t=[],r=[],o=[];for(let s of e){let i=s.split("/");if(i.length===1&&s.endsWith(".jsonl")){t.push({path:s,meta:null,session:s.slice(0,-6),agent:null});continue}if(i.length===3&&i[1]==="subagents"&&s.endsWith(".jsonl")){let a=`${s.slice(0,-6)}.meta.json`;r.push({path:s,meta:n.has(a)?a:null,session:i[0]??"",agent:(i[2]??"").slice(0,-6)});continue}i.length===3&&i[1]==="subagents"&&s.endsWith(".meta.json")||o.push(s)}return{transcripts:[...t,...r],ignored:o}}function sr(e){let n=jn(e);if(n===null)return null;let t=r=>typeof n[r]=="string"&&n[r]!==""?n[r]:null;return{agentType:t("agentType"),description:t("description"),toolUseId:t("toolUseId"),model:t("model"),spawnDepth:typeof n.spawnDepth=="number"?n.spawnDepth:null}}function ir(e){let n=null,t=null,r=null;for(let o of Ue(e))if(n??=S(o.record.cwd)||null,t??=S(o.record.gitBranch)||null,r??=o.ts,n!==null&&t!==null&&r!==null)break;return{cwd:n,branch:t,started:r}}var Ts="Agent";function ar(e){let n=new Map;for(let t of Ue(e)){if(t.kind!=="assistant")continue;let r=t.record.message?.content;if(Array.isArray(r))for(let o of r){let s=o;if(!s||s.type!=="tool_use"||s.name!==Ts)continue;let i=S(s.id);if(i==="")continue;let a=s.input??{};n.set(i,{toolUseId:i,asked:S(a.subagent_type)||null,description:S(a.description)||null,ts:t.ts,line:t.line})}}return n}var As=/\x1b\[[0-9;]*m/g;function dr(e){return S(e).replace(As,"")}function de(e,n=140){let t=dr(e).replace(/\s+/g," ").trim();return t.length>n?`${t.slice(0,n-1)}\u2026`:t}function lr(e,n=""){let t=[];for(let r of Ue(e)){let o=r.record.message?.content;if(r.kind==="user"){let s=_n(r);if(s!==null){t.push({line:r.line,kind:"prompt",text:s});continue}if(!Array.isArray(o))continue;for(let i of o){let a=i;!a||a.type!=="tool_result"||t.push({line:r.line,kind:"result",id:S(a.tool_use_id),content:Ms(a.content),failed:a.is_error===!0})}continue}if(!(r.kind!=="assistant"||!Array.isArray(o)))for(let s of o){let i=s;if(!i||i.type!=="tool_use")continue;let a=i.input??{};t.push({line:r.line,kind:"use",ts:r.ts,id:S(i.id),name:S(i.name),input:a,path:H(S(a.file_path??a.notebook_path),n)})}}return t}function Ms(e){return typeof e=="string"?e:Array.isArray(e)?e.map(n=>n.text??"").join(`
48
- `):e===void 0?"":JSON.stringify(e)}var js=new RegExp([String.raw`\b(actually|hold on|nope|revert|undo|instead|hmm)\b`,String.raw`\b(wait|no)[,!.](\s|$)`,String.raw`\b(stop|don'?t|do not)\s`,String.raw`\bthat'?s (wrong|not right|not what|not)\b`,String.raw`\byou (broke|shouldn'?t|missed|forgot|didn'?t)\b`,String.raw`\bwhy (did|are) you\b`,String.raw`\b(rather than|let'?s not)\b`].join("|"),"i");function Ns(e){return js.test(e)}var _s=new Set(["set","node","npx","just","cd","export","echo","then","fi","do","done","if","for","while","source"]);function Fs(e){if(e.startsWith("["))return!1;let n=e.indexOf(":");if(n<0)return!1;let t=e.slice(0,n).trim();return t!==""&&/^[@A-Za-z_][\w-]*(\s|$)/.test(t)&&!t.includes("=")}function cr(e){let n=new Set,t=!1;for(let r of e.split(`
49
- `)){if(r.trim()==="")continue;let o=/^\s/.test(r),s=r.trim();if(!s.startsWith("#")){if(!o){t=Fs(s);continue}if(t)for(let i of s.split(/&&|\|\||\||;/)){let a=i.trim().split(/\s+/),d=(a[0]??"").replace(/^@/,""),l=d==="npx"?a[1]??"":d;l===""||!/^[A-Za-z]/.test(l)||l.includes("/")||_s.has(l)||n.add(l)}}}return[...n]}function Gs(e,n){let t=dr(e);if(/<<-?\s*['"]?\w/.test(t))return{recipes:[],bypasses:[],commits:!1};let r=[];for(let s of t.matchAll(/(?:^|\n|;|\||&&|\()\s*just\s+([a-z][\w-]*)/g))r.push(s[1]);let o=[];for(let s of n){let i=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`(?:^|\\n|;|\\||&&|\\(|node_modules/\\.bin/|npx\\s+)\\s*(?:\\./)?${i}\\b`),d=new RegExp(`just\\s+\\S*\\b${i}\\b`);a.test(t)&&!d.test(t)&&o.push(s)}return{recipes:r,bypasses:o,commits:/\bgit\s+commit\b/.test(t)}}var Is=5,Bs=3;function ur(e,n=[]){let t=0,r=0,o=0,s={},i={},a={},d=[],l=[],c=[],u=[],p=[],g={},m=null,w=0,$=0,h=0,T=()=>{h>=Is&&m!==null&&u.push({path:m,count:h,from:w,to:$})};for(let y of e){if(y.kind==="prompt"){d.push({line:y.line,text:de(y.text,120)}),Ns(y.text)&&l.push({line:y.line,text:de(y.text,140)});continue}if(y.kind!=="use")continue;if(Nn.has(y.name)){y.name==="Write"?r+=1:t+=1;let x=Ge(y.path);x&&y.path===m?(h+=1,$=y.line):(T(),m=x?y.path:null,w=y.line,$=y.line,h=x?1:0),x&&(a[y.path]=(a[y.path]??0)+1);continue}if(y.name==="Read"){Ge(y.path)&&(a[y.path]=(a[y.path]??0)+1);continue}if(y.name!=="Bash")continue;let O=S(y.input.command),C=Gs(O,n);for(let x of C.recipes)s[x]=(s[x]??0)+1;for(let x of C.bypasses)i[x]=(i[x]??0)+1,c.push({line:y.line,tool:x,text:de(O,120)});C.commits&&(o+=1);let b=de(O,400);(g[b]??=[]).push(y.line)}T();for(let[y,O]of Object.entries(g))O.length>=Bs&&p.push({command:y,count:O.length,lines:O});return{stats:{edits:t,writes:r,commits:o,recipes:s,bypasses:i},prompts:d,corrections:l,bypassSites:c,loops:u,retries:p,touched:a}}function fr(e){let n=(l,c)=>l.map(u=>({...u,session:c})),t={},r={},o={},s={prompts:[],corrections:[],bypassSites:[],loops:[],retries:[]},i=0,a=0,d=0;for(let{session:l,read:c}of e){s.prompts.push(...n(c.prompts,l)),s.corrections.push(...n(c.corrections,l)),s.bypassSites.push(...n(c.bypassSites,l)),s.loops.push(...n(c.loops,l)),s.retries.push(...n(c.retries,l)),i+=c.stats.edits,a+=c.stats.writes,d+=c.stats.commits;for(let[u,p]of Object.entries(c.stats.recipes))t[u]=(t[u]??0)+p;for(let[u,p]of Object.entries(c.stats.bypasses))r[u]=(r[u]??0)+p;for(let[u,p]of Object.entries(c.touched))o[u]=(o[u]??0)+p}return{stats:{edits:i,writes:a,commits:d,recipes:t,bypasses:r},...s,touched:o}}var Ds=[".claude/settings.json",".claude/settings.local.json",".claude/agents/**"];function gr(e){return[...Cn(e),...Ds]}function Ls(e,n){return e!==""&&j(e,n.flatMap(t=>[t,`**/${t}`]))}function pr(e,n,t){let r=e.filter(i=>i.kind==="guardrail"&&i.out==="deny"&&typeof i.ts=="string").map(i=>({entry:typeof i.id=="string"?i.id:null,ts:i.ts})),o=n.filter(i=>i.kind==="use").filter(i=>(i.name==="Edit"||i.name==="Write")&&i.ts!==null&&Ls(i.path,t)).sort((i,a)=>i.ts.localeCompare(a.ts)),s=[];for(let i of r){let a=o.find(d=>d.ts>i.ts);a!==void 0&&s.push({entry:i.entry,line:a.line,path:a.path,gapSeconds:Math.round((Date.parse(a.ts)-Date.parse(i.ts))/1e3)})}return s}function Le(e){let n=Date.parse(String(e.started));return Number.isFinite(n)?n:e.mtimeMs}function yr(e,n,t={}){let{limit:r=null,all:o=!1,largest:s=!1,since:i=null}=t,a=e.filter(m=>!n.has(m.id)),d=(m,w)=>Le(w)-Le(m)||m.id.localeCompare(w.id),l=(m,w)=>w.bytes-m.bytes||d(m,w),c=[...a].sort(s?l:d),u=[],p=c;if(i!==null){p=c.filter(m=>Le(m)>=i);for(let m of c)Le(m)<i&&u.push({id:m.id,reason:"since"})}let g=p;if(!o&&r!==null&&r>=0&&p.length>r){g=p.slice(0,r);for(let m of p.slice(r))u.push({id:m.id,reason:"limit"})}return{analyse:g,excluded:u,counts:{backlog:a.length,analysed:g.length,excluded:u.length}}}function mr({armed:e,rows:n,withRecord:t,analysed:r}){if(!e)return{blocked:'the record is NOT ARMED \u2014 no stream has ever been written here, so there are no numbers. This is not "nothing happened".',warn:[]};let o=[];return r>0&&t===0?o.push("none of the conversations read has a stream of its own \u2014 the hooks did not record for them, so everything below is narrative only."):n===0&&o.push("the record is armed and holds no events for what was read."),{blocked:null,warn:o}}function hr(e){let{session:n,agent:t,meta:r,spawns:o}=e,s=r?.toolUseId===void 0||r.toolUseId===null?void 0:o.get(r.toolUseId);return{session:n,agent:t,agentType:r?.agentType??null,description:r?.description??s?.description??null,model:r?.model??null,asked:s?.asked??null,at:s?.ts??null,line:s?.line??null}}function kr(e,n){let t=je(n);return Object.entries(e).filter(([r])=>!t.some(o=>he(o,r))).map(([r,o])=>({path:r,touches:o})).sort((r,o)=>o.touches-r.touches||r.path.localeCompare(o.path))}var xe=5;function br(e){let n=[];e.health.blocked!==null&&n.push(`\u2717 ${e.health.blocked}`);for(let l of e.health.warn)n.push(`\u26A0 ${l}`);let{span:t,headline:r}=e.metrics;n.push(`flow facts \u2014 ${e.coverage.analysed} of ${e.selection.counts.backlog} unread conversations \xB7 ${e.coverage.withRecord} with a record \xB7 `+(e.store.exists?e.store.dir:`no store at ${e.store.dir}`),` recorded ${t.tools.toLocaleString()} tool calls \xB7 ${t.sessions} chats \xB7 ${t.days}d`+(t.ample?"":" (too thin to call anything dead)"),` blocks ${r.blocks}`," lead "+(r.lead.median===null?"nothing measurable yet":`median ${r.lead.median} tool calls`));for(let l of r.gaps.slice(0,xe))n.push(` gap ${l.area} \u2014 ${l.edits} edit${l.edits===1?"":"s"}, nothing watches it`);r.dead.length>0&&n.push(` dead ${r.dead.join(" \xB7 ")}`),r.retire.length>0&&n.push(` retire ${r.retire.join(" \xB7 ")} \u2014 bound, never once reached`),r.quiet.length>0&&n.push(` quiet ${r.quiet.map(l=>`${l.id} (${l.daysSince}d)`).join(" \xB7 ")}`);let{stats:o,corrections:s,loops:i,retries:a,bypassSites:d}=e.narrative;n.push(` session ${o.edits} edits \xB7 ${o.writes} writes \xB7 ${o.commits} commits \xB7 ${s.length} corrections \xB7 ${i.length} edit loops \xB7 ${a.length} retries \xB7 ${d.length} bypasses`);for(let l of e.uncovered.slice(0,xe))n.push(` unwatched ${l.path} \u2014 touched ${l.touches}\xD7, no entry reaches it`);for(let l of e.actors.slice(0,xe))n.push(` actor ${l.agentType??"unknown"}${l.asked!==null&&l.asked!==l.agentType?` (spawned as ${l.asked})`:""}`+(l.description===null?"":` \u2014 ${l.description}`));e.actors.length>xe&&n.push(` \u2026and ${e.actors.length-xe} more`);for(let l of e.weakened)n.push(` \u26A0 the guard was edited after ${l.entry??"a block"} refused \u2014 ${l.path}:L${l.line}, ${l.gapSeconds}s later`);return e.marked!==null&&n.push(` marked ${e.marked} conversation(s) read`),n}var Ws=24;function wr(e){if(!e.startsWith("file://"))return!1;let n=e.split(/[?#]/)[0]??e;return!n.endsWith(".ts")||n.endsWith(".d.ts")?!1:!n.includes("/node_modules/")}function Ke(e,n,t){return/Unexpected token|Unknown file extension|strip|SyntaxError/i.test(n)?`flow: ${e} could not be loaded as TypeScript. flow needs Node >= ${Ws}, where type stripping is on by default; this is node ${t}. (${n})`:`flow: ${e} could not be loaded \u2014 ${n}`}var Hs=[{hook:"session-start",matcher:"startup|resume|clear|compact"},{hook:"pre-tool-use",matcher:"*"},{hook:"post-tool-use",matcher:"Read|Glob|Grep|Edit|Write|Bash"},{hook:"stop"}],xr=Hs.map(({hook:e,matcher:n})=>({event:Vt[e],command:`flow hook ${e}`,...n===void 0?{}:{matcher:n}}));function Us(e){let n=/(^|[\s"'/\\])(?:flow|flow\.mjs)["']?\s+hook\s+([a-z-]+)\s*$/.exec(e.trim());return n?.[2]!==void 0&&Pn(n[2])}function Sr(e){let n=e&&typeof e=="object"?e:{},t=n.hooks&&typeof n.hooks=="object"?n.hooks:{},r={};for(let[o,s]of Object.entries(t))Array.isArray(s)&&(r[o]=s);return r}function Rr(e){let n=[];for(let[t,r]of Object.entries(Sr(e)))r.some(s=>{let i=s?.hooks;return Array.isArray(i)?i.some(a=>{let d=a?.command;return typeof d=="string"&&Us(d)}):!1})&&n.push(t);return n}function Ks(e){let n=e&&typeof e=="object"?e:{},t=new Set(Rr(e)),r=xr.filter(i=>!t.has(i.event));if(r.length===0)return{settings:n,added:[]};let o=Sr(e),s={...n.hooks};for(let i of r)s[i.event]=[...o[i.event]??[],{...i.matcher===void 0?{}:{matcher:i.matcher},hooks:[{type:"command",command:i.command}]}];return{settings:{...n,hooks:s},added:r.map(i=>i.event)}}var Y=".githooks",Q=`${Y}/pre-commit`,Fn=`git config core.hooksPath ${Y}`,$r="add `flow commit $(git diff --cached --name-only)` to it",Vs=`#!/bin/sh
44
+ `,exitCode:2}}function Ts(e,n){return JSON.stringify({hookSpecificOutput:{hookEventName:Qt[e],additionalContext:n}})}function er(e,n,t){let r=n==="unreadable"?`could not READ its payload from stdin (${t})`:`could not PARSE its payload (${t})`;return`[flow hook ${e}] the guard ${r}.`}function Mn(e,n=0){let t=Nn(e);if(t===null)return null;let r=S(t.timestamp);return{kind:S(t.type),record:t,line:n,ts:r===""?null:r}}function Nn(e){if(e===null||e.trim()==="")return null;let n;try{n=JSON.parse(e)}catch{return null}return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:null}function Ke(e){let n=[],t=e.split(`
45
+ `);for(let r=0;r<t.length;r++){let o=Mn(t[r],r+1);o!==null&&n.push(o)}return n}function As(e){return(e?.input_tokens??0)+(e?.cache_read_input_tokens??0)+(e?.cache_creation_input_tokens??0)}function nr(e){let n=e.split(`
46
+ `);for(let t=n.length-1;t>=0;t--){let r=Mn(n[t])?.record.message;if(r?.usage)return As(r.usage)}return 0}var Gn=new Set(["Edit","Write","MultiEdit","NotebookEdit"]),js=["<system-reminder>","<command-name>","<command-message>","<local-command","<user-prompt-submit-hook","Caveat:","Result of calling","This session is being continued","[Request interrupted","DO NOT respond","<budget:","tool_use_id"];function Ms(e){let n=e.trimStart();return js.some(t=>n.startsWith(t))||n.slice(0,40).includes("<system-reminder>")}function _n(e){if(e.kind!=="user"||e.record.isMeta===!0)return null;let n=e.record.message?.content;return typeof n!="string"||Ms(n)?null:n}function tr(e,n=""){let t=Ke(e),r=0;for(let s=t.length-1;s>=0;s--)if(_n(t[s])!==null){r=s;break}let o=[];for(let s of t.slice(r)){let i=s.record.message?.content;if(Array.isArray(i))for(let a of i){let d=a;if(!d||d.type!=="tool_use")continue;let l=S(d.name),c=d.input??{},u=c.file_path??c.notebook_path;Gn.has(l)&&u?o.push({did:"edit",path:H(S(u),n)}):l==="Bash"&&c.command&&o.push({did:"run",command:S(c.command)})}}return o}function Ns(e,n=8e3){for(let t of e.split(`
47
+ `)){let r=Mn(t),o=r===null?null:_n(r);if(o!==null)return o.slice(0,n)}return""}function rr(e){let n=e.trim();return/^ref:\s*refs\/heads\/(.+)$/.exec(n)?.[1]??(n===""?null:n.slice(0,12))}function or(e){return e.endsWith(".jsonl")?`${e.slice(0,-6)}.meta.json`:null}function sr(e){let n=typeof e.payload.agent_id=="string"&&e.payload.agent_id!=="",t=Nn(e.sidecar),r=typeof t?.agentType=="string"?t.agentType:void 0,o=typeof t?.description=="string"?t.description:void 0;return{head:e.transcript===null?"":Ns(e.transcript),subagent:n||t!==null,...r===void 0?{}:{agentType:r},...o===void 0?{}:{description:o}}}var Gs=["file_path","notebook_path"];function ir(e,n=""){let t=S(e.tool_name);if(!t)return null;let r=e.tool_input??{};for(let s of Gs)if(r[s])return{kind:"tool",tool:t,path:H(S(r[s]),n),edit:Gn.has(t)};if(t==="Bash"&&r.command)return{kind:"tool",tool:t,command:S(r.command)};if(!r.pattern)return{kind:"tool",tool:t};let o=r.path?{scope:H(S(r.path),n)}:{};return{kind:"tool",tool:t,pattern:S(r.pattern),...o}}var _s=["GIT_DIR","GIT_INDEX_FILE","GIT_WORK_TREE","GIT_PREFIX","GIT_OBJECT_DIRECTORY","GIT_COMMON_DIR","GIT_INDEX_VERSION","GIT_QUARANTINE_PATH","GIT_QUARANTINE_ID"];function ar(e){let n=new Set(_s);return Object.fromEntries(Object.entries(e).filter(([t])=>!n.has(t)))}function dr(e){return e.replace(/[^a-zA-Z0-9]/g,"-")}function lr(e){let n=new Set(e),t=[],r=[],o=[];for(let s of e){let i=s.split("/");if(i.length===1&&s.endsWith(".jsonl")){t.push({path:s,meta:null,session:s.slice(0,-6),agent:null});continue}if(i.length===3&&i[1]==="subagents"&&s.endsWith(".jsonl")){let a=`${s.slice(0,-6)}.meta.json`;r.push({path:s,meta:n.has(a)?a:null,session:i[0]??"",agent:(i[2]??"").slice(0,-6)});continue}i.length===3&&i[1]==="subagents"&&s.endsWith(".meta.json")||o.push(s)}return{transcripts:[...t,...r],ignored:o}}function cr(e){let n=Nn(e);if(n===null)return null;let t=r=>typeof n[r]=="string"&&n[r]!==""?n[r]:null;return{agentType:t("agentType"),description:t("description"),toolUseId:t("toolUseId"),model:t("model"),spawnDepth:typeof n.spawnDepth=="number"?n.spawnDepth:null}}function ur(e){let n=null,t=null,r=null;for(let o of Ke(e))if(n??=S(o.record.cwd)||null,t??=S(o.record.gitBranch)||null,r??=o.ts,n!==null&&t!==null&&r!==null)break;return{cwd:n,branch:t,started:r}}var Fs="Agent";function fr(e){let n=new Map;for(let t of Ke(e)){if(t.kind!=="assistant")continue;let r=t.record.message?.content;if(Array.isArray(r))for(let o of r){let s=o;if(!s||s.type!=="tool_use"||s.name!==Fs)continue;let i=S(s.id);if(i==="")continue;let a=s.input??{};n.set(i,{toolUseId:i,asked:S(a.subagent_type)||null,description:S(a.description)||null,ts:t.ts,line:t.line})}}return n}var Is=/\x1b\[[0-9;]*m/g;function gr(e){return S(e).replace(Is,"")}function de(e,n=140){let t=gr(e).replace(/\s+/g," ").trim();return t.length>n?`${t.slice(0,n-1)}\u2026`:t}function pr(e,n=""){let t=[];for(let r of Ke(e)){let o=r.record.message?.content;if(r.kind==="user"){let s=_n(r);if(s!==null){t.push({line:r.line,kind:"prompt",text:s});continue}if(!Array.isArray(o))continue;for(let i of o){let a=i;!a||a.type!=="tool_result"||t.push({line:r.line,kind:"result",id:S(a.tool_use_id),content:Bs(a.content),failed:a.is_error===!0})}continue}if(!(r.kind!=="assistant"||!Array.isArray(o)))for(let s of o){let i=s;if(!i||i.type!=="tool_use")continue;let a=i.input??{};t.push({line:r.line,kind:"use",ts:r.ts,id:S(i.id),name:S(i.name),input:a,path:H(S(a.file_path??a.notebook_path),n)})}}return t}function Bs(e){return typeof e=="string"?e:Array.isArray(e)?e.map(n=>n.text??"").join(`
48
+ `):e===void 0?"":JSON.stringify(e)}var Ds=new RegExp([String.raw`\b(actually|hold on|nope|revert|undo|instead|hmm)\b`,String.raw`\b(wait|no)[,!.](\s|$)`,String.raw`\b(stop|don'?t|do not)\s`,String.raw`\bthat'?s (wrong|not right|not what|not)\b`,String.raw`\byou (broke|shouldn'?t|missed|forgot|didn'?t)\b`,String.raw`\bwhy (did|are) you\b`,String.raw`\b(rather than|let'?s not)\b`].join("|"),"i");function Ls(e){return Ds.test(e)}var Ws=new Set(["set","node","npx","just","cd","export","echo","then","fi","do","done","if","for","while","source"]);function Hs(e){if(e.startsWith("["))return!1;let n=e.indexOf(":");if(n<0)return!1;let t=e.slice(0,n).trim();return t!==""&&/^[@A-Za-z_][\w-]*(\s|$)/.test(t)&&!t.includes("=")}function yr(e){let n=new Set,t=!1;for(let r of e.split(`
49
+ `)){if(r.trim()==="")continue;let o=/^\s/.test(r),s=r.trim();if(!s.startsWith("#")){if(!o){t=Hs(s);continue}if(t)for(let i of s.split(/&&|\|\||\||;/)){let a=i.trim().split(/\s+/),d=(a[0]??"").replace(/^@/,""),l=d==="npx"?a[1]??"":d;l===""||!/^[A-Za-z]/.test(l)||l.includes("/")||Ws.has(l)||n.add(l)}}}return[...n]}function Us(e,n){let t=gr(e);if(/<<-?\s*['"]?\w/.test(t))return{recipes:[],bypasses:[],commits:!1};let r=[];for(let s of t.matchAll(/(?:^|\n|;|\||&&|\()\s*just\s+([a-z][\w-]*)/g))r.push(s[1]);let o=[];for(let s of n){let i=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`(?:^|\\n|;|\\||&&|\\(|node_modules/\\.bin/|npx\\s+)\\s*(?:\\./)?${i}\\b`),d=new RegExp(`just\\s+\\S*\\b${i}\\b`);a.test(t)&&!d.test(t)&&o.push(s)}return{recipes:r,bypasses:o,commits:/\bgit\s+commit\b/.test(t)}}var Ks=5,Vs=3;function mr(e,n=[]){let t=0,r=0,o=0,s={},i={},a={},d=[],l=[],c=[],u=[],p=[],g={},m=null,w=0,$=0,h=0,T=()=>{h>=Ks&&m!==null&&u.push({path:m,count:h,from:w,to:$})};for(let y of e){if(y.kind==="prompt"){d.push({line:y.line,text:de(y.text,120)}),Ls(y.text)&&l.push({line:y.line,text:de(y.text,140)});continue}if(y.kind!=="use")continue;if(Gn.has(y.name)){y.name==="Write"?r+=1:t+=1;let x=Ie(y.path);x&&y.path===m?(h+=1,$=y.line):(T(),m=x?y.path:null,w=y.line,$=y.line,h=x?1:0),x&&(a[y.path]=(a[y.path]??0)+1);continue}if(y.name==="Read"){Ie(y.path)&&(a[y.path]=(a[y.path]??0)+1);continue}if(y.name!=="Bash")continue;let O=S(y.input.command),C=Us(O,n);for(let x of C.recipes)s[x]=(s[x]??0)+1;for(let x of C.bypasses)i[x]=(i[x]??0)+1,c.push({line:y.line,tool:x,text:de(O,120)});C.commits&&(o+=1);let b=de(O,400);(g[b]??=[]).push(y.line)}T();for(let[y,O]of Object.entries(g))O.length>=Vs&&p.push({command:y,count:O.length,lines:O});return{stats:{edits:t,writes:r,commits:o,recipes:s,bypasses:i},prompts:d,corrections:l,bypassSites:c,loops:u,retries:p,touched:a}}function hr(e){let n=(l,c)=>l.map(u=>({...u,session:c})),t={},r={},o={},s={prompts:[],corrections:[],bypassSites:[],loops:[],retries:[]},i=0,a=0,d=0;for(let{session:l,read:c}of e){s.prompts.push(...n(c.prompts,l)),s.corrections.push(...n(c.corrections,l)),s.bypassSites.push(...n(c.bypassSites,l)),s.loops.push(...n(c.loops,l)),s.retries.push(...n(c.retries,l)),i+=c.stats.edits,a+=c.stats.writes,d+=c.stats.commits;for(let[u,p]of Object.entries(c.stats.recipes))t[u]=(t[u]??0)+p;for(let[u,p]of Object.entries(c.stats.bypasses))r[u]=(r[u]??0)+p;for(let[u,p]of Object.entries(c.touched))o[u]=(o[u]??0)+p}return{stats:{edits:i,writes:a,commits:d,recipes:t,bypasses:r},...s,touched:o}}var qs=[".claude/settings.json",".claude/settings.local.json",".claude/agents/**"];function kr(e){return[...On(e),...qs]}function Js(e,n){return e!==""&&M(e,n.flatMap(t=>[t,`**/${t}`]))}function br(e,n,t){let r=e.filter(i=>i.kind==="guardrail"&&i.out==="deny"&&typeof i.ts=="string").map(i=>({entry:typeof i.id=="string"?i.id:null,ts:i.ts})),o=n.filter(i=>i.kind==="use").filter(i=>(i.name==="Edit"||i.name==="Write")&&i.ts!==null&&Js(i.path,t)).sort((i,a)=>i.ts.localeCompare(a.ts)),s=[];for(let i of r){let a=o.find(d=>d.ts>i.ts);a!==void 0&&s.push({entry:i.entry,line:a.line,path:a.path,gapSeconds:Math.round((Date.parse(a.ts)-Date.parse(i.ts))/1e3)})}return s}function We(e){let n=Date.parse(String(e.started));return Number.isFinite(n)?n:e.mtimeMs}function wr(e,n,t={}){let{limit:r=null,all:o=!1,largest:s=!1,since:i=null}=t,a=e.filter(m=>!n.has(m.id)),d=(m,w)=>We(w)-We(m)||m.id.localeCompare(w.id),l=(m,w)=>w.bytes-m.bytes||d(m,w),c=[...a].sort(s?l:d),u=[],p=c;if(i!==null){p=c.filter(m=>We(m)>=i);for(let m of c)We(m)<i&&u.push({id:m.id,reason:"since"})}let g=p;if(!o&&r!==null&&r>=0&&p.length>r){g=p.slice(0,r);for(let m of p.slice(r))u.push({id:m.id,reason:"limit"})}return{analyse:g,excluded:u,counts:{backlog:a.length,analysed:g.length,excluded:u.length}}}function xr({armed:e,rows:n,withRecord:t,analysed:r}){if(!e)return{blocked:'the record is NOT ARMED \u2014 no stream has ever been written here, so there are no numbers. This is not "nothing happened".',warn:[]};let o=[];return r>0&&t===0?o.push("none of the conversations read has a stream of its own \u2014 the hooks did not record for them, so everything below is narrative only."):n===0&&o.push("the record is armed and holds no events for what was read."),{blocked:null,warn:o}}function Sr(e){let{session:n,agent:t,meta:r,spawns:o}=e,s=r?.toolUseId===void 0||r.toolUseId===null?void 0:o.get(r.toolUseId);return{session:n,agent:t,agentType:r?.agentType??null,description:r?.description??s?.description??null,model:r?.model??null,asked:s?.asked??null,at:s?.ts??null,line:s?.line??null}}function Rr(e,n){let t=Ne(n);return Object.entries(e).filter(([r])=>!t.some(o=>he(o,r))).map(([r,o])=>({path:r,touches:o})).sort((r,o)=>o.touches-r.touches||r.path.localeCompare(o.path))}var xe=5;function $r(e){let n=[];e.health.blocked!==null&&n.push(`\u2717 ${e.health.blocked}`);for(let l of e.health.warn)n.push(`\u26A0 ${l}`);let{span:t,headline:r}=e.metrics;n.push(`flow facts \u2014 ${e.coverage.analysed} of ${e.selection.counts.backlog} unread conversations \xB7 ${e.coverage.withRecord} with a record \xB7 `+(e.store.exists?e.store.dir:`no store at ${e.store.dir}`),` recorded ${t.tools.toLocaleString()} tool calls \xB7 ${t.sessions} chats \xB7 ${t.days}d`+(t.ample?"":" (too thin to call anything dead)"),` blocks ${r.blocks}`," lead "+(r.lead.median===null?"nothing measurable yet":`median ${r.lead.median} tool calls`));for(let l of r.gaps.slice(0,xe))n.push(` gap ${l.area} \u2014 ${l.edits} edit${l.edits===1?"":"s"}, nothing watches it`);r.dead.length>0&&n.push(` dead ${r.dead.join(" \xB7 ")}`),r.retire.length>0&&n.push(` retire ${r.retire.join(" \xB7 ")} \u2014 bound, never once reached`),r.quiet.length>0&&n.push(` quiet ${r.quiet.map(l=>`${l.id} (${l.daysSince}d)`).join(" \xB7 ")}`);let{stats:o,corrections:s,loops:i,retries:a,bypassSites:d}=e.narrative;n.push(` session ${o.edits} edits \xB7 ${o.writes} writes \xB7 ${o.commits} commits \xB7 ${s.length} corrections \xB7 ${i.length} edit loops \xB7 ${a.length} retries \xB7 ${d.length} bypasses`);for(let l of e.uncovered.slice(0,xe))n.push(` unwatched ${l.path} \u2014 touched ${l.touches}\xD7, no entry reaches it`);for(let l of e.actors.slice(0,xe))n.push(` actor ${l.agentType??"unknown"}${l.asked!==null&&l.asked!==l.agentType?` (spawned as ${l.asked})`:""}`+(l.description===null?"":` \u2014 ${l.description}`));e.actors.length>xe&&n.push(` \u2026and ${e.actors.length-xe} more`);for(let l of e.weakened)n.push(` \u26A0 the guard was edited after ${l.entry??"a block"} refused \u2014 ${l.path}:L${l.line}, ${l.gapSeconds}s later`);return e.marked!==null&&n.push(` marked ${e.marked} conversation(s) read`),n}var zs=24;function vr(e){if(!e.startsWith("file://"))return!1;let n=e.split(/[?#]/)[0]??e;return!n.endsWith(".ts")||n.endsWith(".d.ts")?!1:!n.includes("/node_modules/")}function Ve(e,n,t){return/Unexpected token|Unknown file extension|strip|SyntaxError/i.test(n)?`flow: ${e} could not be loaded as TypeScript. flow needs Node >= ${zs}, where type stripping is on by default; this is node ${t}. (${n})`:`flow: ${e} could not be loaded \u2014 ${n}`}var Ys=[{hook:"session-start",matcher:"startup|resume|clear|compact"},{hook:"pre-tool-use",matcher:"*"},{hook:"post-tool-use",matcher:"Read|Glob|Grep|Edit|Write|Bash"},{hook:"stop"}],Er=Ys.map(({hook:e,matcher:n})=>({event:Qt[e],command:`flow hook ${e}`,...n===void 0?{}:{matcher:n}}));function Qs(e){let n=/(^|[\s"'/\\])(?:flow|flow\.mjs)["']?\s+hook\s+([a-z-]+)\s*$/.exec(e.trim());return n?.[2]!==void 0&&Tn(n[2])}function Cr(e){let n=e&&typeof e=="object"?e:{},t=n.hooks&&typeof n.hooks=="object"?n.hooks:{},r={};for(let[o,s]of Object.entries(t))Array.isArray(s)&&(r[o]=s);return r}function Or(e){let n=[];for(let[t,r]of Object.entries(Cr(e)))r.some(s=>{let i=s?.hooks;return Array.isArray(i)?i.some(a=>{let d=a?.command;return typeof d=="string"&&Qs(d)}):!1})&&n.push(t);return n}function Zs(e){let n=e&&typeof e=="object"?e:{},t=new Set(Or(e)),r=Er.filter(i=>!t.has(i.event));if(r.length===0)return{settings:n,added:[]};let o=Cr(e),s={...n.hooks};for(let i of r)s[i.event]=[...o[i.event]??[],{...i.matcher===void 0?{}:{matcher:i.matcher},hooks:[{type:"command",command:i.command}]}];return{settings:{...n,hooks:s},added:r.map(i=>i.event)}}var Y=".githooks",Q=`${Y}/pre-commit`,Fn=`git config core.hooksPath ${Y}`,Pr="add `flow commit $(git diff --cached --name-only)` to it",Xs=`#!/bin/sh
50
50
  # The flow commit gate. Written by \`flow init\`; \`${Fn}\` arms it.
51
51
  #
52
52
  # Every at(commit) guardrail runs over the staged set and a block exits non-zero, which is how git
@@ -56,7 +56,7 @@ staged=$(git diff --cached --name-only --diff-filter=ACMR)
56
56
  [ -z "$staged" ] && exit 0
57
57
  # shellcheck disable=SC2086
58
58
  exec flow commit $staged
59
- `;function vr(e){return e!==null&&/(^|[\s"'/\\])flow\b[^\n]*\bcommit\b/m.test(e)}var qs=String.raw`// flow.config.ts — this repo's whole guard.
59
+ `;function Tr(e){return e!==null&&/(^|[\s"'/\\])flow\b[^\n]*\bcommit\b/m.test(e)}var ei=String.raw`// flow.config.ts — this repo's whole guard.
60
60
  //
61
61
  // A rule not reachable from this file does not run. Bind a pack with `+"`pack(x)`"+String.raw`, refine one of
62
62
  // its entries with `+"`override(x.entry)`"+String.raw`, and ask `+"`flow status`"+String.raw` what is live.
@@ -64,7 +64,7 @@ exec flow commit $staged
64
64
  import { defineConfig } from "@jawache/flow";
65
65
 
66
66
  export default defineConfig([]);
67
- `,Js=String.raw`// flow.config.ts — this repo's whole guard, and the only file that turns anything on.
67
+ `,ni=String.raw`// flow.config.ts — this repo's whole guard, and the only file that turns anything on.
68
68
  //
69
69
  // A rule not reachable from here does not run. Everything below is ordinary code: a pack is a
70
70
  // module, a check is a function of its ctx, and a category is a name with its recognizer aboard.
@@ -129,40 +129,40 @@ export default defineConfig([
129
129
  pack(flow, { packs: [] }),
130
130
  pack(demo),
131
131
  ]);
132
- `;function zs(e){return e?qs:Js}function Er(e){let n=e.settingsUnreadable?{settings:e.settings,added:[]}:Ks(e.settings);return{config:e.hasConfig?null:{path:P,body:zs(e.empty)},gate:!e.isGit||e.gateText!==null?null:{path:Q,body:Vs,mode:493},gateKept:e.isGit&&e.gateText!==null&&!vr(e.gateText),notGit:!e.isGit,flowDir:!e.hasFlowDir,link:e.resolves?null:e.packageRoot,hooksPath:e.isGit&&e.hooksPath!==Y,settings:n.added.length===0?null:{path:e.settingsPath,value:n.settings},registered:n.added,settingsUnreadable:e.settingsUnreadable?e.settingsPath:null}}function Cr(e,n){let t=[];e.config&&t.push(e.config.path),e.gate&&t.push(e.gate.path),e.flowDir&&t.push(`${z}/ \u2014 flow's own state, self-ignoring, never committed`),e.link&&t.push(`node_modules/@jawache/flow \u2192 ${e.link} (a link to the flow that is running \u2014 nothing here resolved @jawache/flow)`),e.settings&&t.push(`${e.settings.path} \u2014 ${e.registered.join(" \xB7 ")}`),e.hooksPath&&t.push(Fn);let r=t.length===0?["flow init \u2014 already set up here; nothing to do."]:["flow init \u2014 created:",...t.map(o=>` + ${o}`)];e.notGit&&r.push(" \xB7 not a git repo, so no commit gate was armed. Run `git init`, then `flow init` again."),e.gateKept&&r.push(` \xB7 kept the ${Q} already here \u2014 flow never overwrites one, so ${$r} yourself.`),e.settingsUnreadable!==null&&r.push(` \u2717 ${e.settingsUnreadable} is not valid JSON, so nothing was registered and NOTHING was written to it \u2014 every other key in that file is somebody's, and there is no safe merge into bytes nobody could parse. Fix the JSON (a trailing comma, or a // comment) and run \`flow init\` again. Until then no rail fires.`);for(let o of n)r.push(` \u2717 ${o}`);return r.push(" next: `flow status` \u2014 what is bound, and what is not wired yet."),r}function Ys(e){let n=Rr(e.settings),t=xr.filter(o=>!n.includes(o.event)).map(o=>o.event),r=vr(e.gateText);return[{id:"config",ok:e.hasConfig,detail:e.hasConfig?e.configPath:`no ${P} in ${e.root} \u2014 \`flow init\` writes one, with a demo you can read in a minute.`},{id:"commit-gate",ok:r,detail:r?`${Q} runs \`flow commit\` over the staged set`:e.gateText===null?`no ${Q} \u2014 \`flow init\` arms it. Until then nothing runs at the commit.`:`${Q} is here but does not call flow \u2014 ${$r}.`},{id:"hooks-path",ok:e.hooksPath===Y,detail:e.hooksPath===Y?`core.hooksPath = ${Y}`:`core.hooksPath is ${e.hooksPath??"unset"} \u2014 run \`${Fn}\`. It is per-clone, so every fresh checkout needs it.`},...e.grammars.length===0?[]:[{id:"grammars",ok:e.grammars.every(o=>o.present),detail:e.grammars.every(o=>o.present)?`${e.grammars.map(o=>o.name).join(" \xB7 ")} \u2014 declared in ${P}, and their libraries are built`:e.grammars.filter(o=>!o.present).map(o=>an(o.name,o.libraryPath)).join(`
133
- `)}],{id:"hooks",ok:t.length===0,detail:t.length===0?`${e.settingsPath} \u2014 ${n.join(" \xB7 ")}`:`${e.settingsPath} does not call flow for ${t.join(" \xB7 ")} \u2014 re-run \`flow init\`. No live rail fires until it does.`}]}function Or(e){return[...e.refusals.map(n=>`${n.code}: ${n.detail}`),...e.dark,...e.fittings.filter(n=>!n.ok).map(n=>`${n.id}: ${n.detail}`)]}function Qs(e,n){return e==="guardrail"?en(n)&&We.guard.includes(n):nn(n)&&We.brief.includes(n)}function Pr(e){let n=e.load?.ok===!0?e.load.entries:[],t=e.load?.ok===!1?e.load.refusals:[],r=t.length>0?[]:Fe(n),o=r.filter(i=>i.disabled===null&&i.at.length>0&&!i.at.some(a=>Qs(i.kind,a))).map(i=>i.id),s=Ys(e);return{root:e.root,version:e.version,armed:!e.off,configPath:e.configPath,moments:Ie(r,null),categories:[...new Set(n.flatMap(i=>i.categories))].sort(),session:e.session,dark:o,fittings:s,refusals:t,green:Or({refusals:t,dark:o,fittings:s}).length===0}}function Zs(e){let n=[(e.on?.length??0)>0?`on ${e.on?.join(" ")}`:"",(e.ignore?.length??0)>0?`not ${e.ignore?.join(" ")}`:"",e.for.length>0?`for ${e.for.join(" \xB7 ")}`:""].filter(o=>o!==""),r=[` ${e.disabled!==null?"\u25CB":e.kind==="guardrail"?"\u2717":"\u{1F35E}"} ${e.id}${n.length===0?"":` \u2014 ${n.join(" \xB7 ")}`}`];return e.disabled!==null?r.push(` off: ${e.disabled||"no reason given"}`):e.says!==null&&r.push(` ${de(e.says,100)}`),r}function Tr(e){if(!e.armed)return[`flow is OFF \u2014 every rail is silenced (${z}/off is there). Delete that file to turn it back on.`];let{breadcrumbs:n,guardrails:t,disabled:r}=e.moments.totals,o=[e.refusals.length>0?`flow ${e.version} \u2014 the config will not load, so every guardrail and breadcrumb here is OFF.`:`flow is ON \u2014 ${En(t,"guardrail")} \xB7 ${En(n,"breadcrumb")}`+(r===0?"":` \xB7 ${r} disabled`)+", every one resolved and able to fire",` config ${e.configPath}`,` state ${e.root}/${z}`," session "+(e.session===null?"no live session has marked this worktree yet":`${e.session.id}${e.session.agent===null?"":` \xB7 ${e.session.agent}`}, wearing ${e.session.wearing.length===0?"no category":e.session.wearing.join(" \xB7 ")}`)];e.categories.length>0&&o.push(` categories ${e.categories.join(" \xB7 ")} \u2014 what the entries below bind to`);for(let{moment:s,entries:i}of e.moments.moments){o.push(` ${s}`);for(let a of i)o.push(...Zs(a))}for(let s of e.fittings)o.push(` ${s.ok?"\u2713":"\u2717"} ${s.id}: ${s.detail}`);for(let s of e.refusals)o.push(` \u2717 ${s.code}: ${s.detail}`);for(let s of e.dark)o.push(` \u2717 ${s}: bound only at a moment nothing delivers here \u2014 it loads, it counts, and it will never fire. This adapter carries ${We.guard.join(" \xB7 ")} for a guardrail and ${We.brief.join(" \xB7 ")} for a breadcrumb.`);return o.push(e.green?"green \u2014 every rule loads, every fitting is in place.":`${En(Or(e).length,"red line")} \u2014 flow is NOT fully in force here.`),o}var En=(e,n)=>`${e} ${n}${e===1?"":"s"}`;var ti=16*1024*1024;function Se(e,n){let t=Xs("bash",["-lc",e],{cwd:n,encoding:"utf8",maxBuffer:ti,env:tr(process.env)});return t.error?{stdout:"",stderr:`flow could not run a command: ${t.error.message}`,code:127}:{stdout:t.stdout,stderr:t.stderr,code:t.status??1}}function Nr(e,n){return Mr(n)?n:Re(e,n)}function G(e,n){try{return Ve(Nr(e,n),"utf8")}catch{return null}}function ri(e){return e.split(`
134
- `).map(n=>n.trim()).filter(n=>n!=="")}function In(e){return{exec:n=>Promise.resolve(Se(n,e)),fs:{read:n=>Promise.resolve(G(e,n)??""),exists:n=>Promise.resolve(Bn(Nr(e,n)))},git:{diff:n=>Promise.resolve(Se(n?`git diff -- ${re(n)}`:"git diff",e).stdout),stagedFiles:()=>Promise.resolve(ri(Se("git diff --cached --name-only --diff-filter=ACM",e).stdout))}}}function _r(e){try{let n=Re(e,".git"),t=ei(n).isDirectory()?n:jr(e,/gitdir:\s*(.+)/.exec(Ve(n,"utf8"))?.[1]?.trim()??"");return Zt(Ve(Re(t,"HEAD"),"utf8"))}catch{return null}}function Dn(e){let n=_r(e),{session:t,agent:r}=Ut(e,n);return{branch:n,session:t,agent:r,wearing:r===null?[]:De(e,t,r).categories??[]}}function oi(e){return process.env.CLAUDE_PROJECT_DIR||e}function Ln(e,n){return(e.grammars??[]).map(t=>Mr(t.libraryPath)?t:{...t,libraryPath:Re(n,t.libraryPath)})}function Wn(e,n){ft(Ln(e,n),Bn)}async function qe(e){let n=Re(e,P);if(!Bn(n))return{kind:"none"};try{let r=(await import(ni(n).href)).default;return!r||typeof r!="object"||!Array.isArray(r.bindings)?{kind:"broken",message:`flow: ${P} has no default export from \`defineConfig([\u2026])\` \u2014 that call IS the config, and its result is what flow reads.`}:(Wn(r.settings,e),{kind:"loaded",config:r,load:ue(r)})}catch(t){return{kind:"broken",message:Ke(P,t.message,process.versions.node)}}}function Gn(e){let n=null;return()=>(n??={value:e()},n.value)}function si(e,n){let t=typeof e.transcript_path=="string"?e.transcript_path:"",r=Gn(()=>t===""?null:G(n,t));return{root:n,id:typeof e.session_id=="string"&&e.session_id!==""?e.session_id:"unknown",agent:typeof e.agent_id=="string"&&e.agent_id!==""?e.agent_id:"main",branch:_r(n),transcriptPath:t,transcript:r,tokens:Gn(()=>{let o=r();return o===null?0:Yt(o)}),turn:Gn(()=>{let o=r();return o===null?[]:Qt(o,n)})}}function ii(e,n,t){if(t.length===0)return{wearing:[],faults:[],fresh:!1};let r=e.transcriptPath===""?null:Xt(e.transcriptPath),o=er({payload:n,transcript:e.transcript(),sidecar:r===null?null:G(e.root,r)});return It(e.root,e.id,e.agent,o,t)}function Ar(e,n){return{root:e,read:t=>G(e,t),turn:n.turn}}function ai(e,n){return n.text!==void 0?n.text:n.file===void 0?"":G(e,n.file)??""}function di(e){return e.rail==="guard"&&e.moment==="commit"?e.staged?.length??0:1}async function li(e,n,t){let r=await qe(t);if(r.kind==="none")return D;let o=we(t),s=si(n,t);e==="pre-tool-use"&&!o&&s.id!=="unknown"&&Ht(t,s.id,s.agent,s.branch);let i=$=>{if(o)return D;let h=Cn(G(t,P)),T=qt(Tn(e,n,Ar(t,s)),h,$),y=An(e,T);return T.told===null||y.exitCode!==0?y:{...y,stderr:`${T.told}
135
- `}};if(r.kind==="broken")return i(r.message);let{load:a,config:d}=r;if(!a.ok)return i(te(a.refusals));let l=a.entries,c=ii(s,n,kt(l)),u=Tn(e,n,Ar(t,s)),p=[];if(e==="pre-tool-use"&&!o){let $=nr(n,t);$&&p.push($)}let g=[],m=$n(t),w=await ci({events:u,session:s,load:a,settings:d.settings,identity:c,off:o,hook:e,payload:n,rows:p,steps:m?g:null});return o||Sn({root:t,session:s.id,branch:s.branch},p),m&&vn(t,s.id,g),An(e,w)}async function ci(e){let{events:n,session:t,load:r,settings:o,identity:s,off:i,hook:a,payload:d,rows:l,steps:c}=e,u=[],p=[],g=In(t.root),m=a==="session-start"&&d.source==="compact",w=De(t.root,t.id,t.agent),$=m&&r.ok?un(w.marks,r.entries):w.marks;m&&!i&&l.push({kind:"compaction"}),m&&c?.push({rail:"compaction"});for(let h of n){if(h.rail==="guard"){let C=c===null?null:kn(g),b=await Ne({load:r,event:{moment:h.moment,file:h.file,command:h.command,staged:h.staged,turn:h.turn,wearing:s.wearing},world:C?.world??g,faults:s.faults,off:i});c?.push({rail:"guard",moment:h.moment,...h.file===void 0?{}:{file:h.file},...h.command===void 0?{}:{command:h.command},...h.staged===void 0?{}:{staged:h.staged},...h.turn===void 0?{}:{turn:h.turn},wearing:s.wearing,world:C?.taken()??{}});for(let x of b.effects)x.do==="block"&&u.push({moment:h.moment,block:x});i||l.push(...ge(h.moment,b,di(h)));continue}c?.push({rail:"brief",moment:h.moment,...h.path===void 0?{}:{path:h.path},...h.command===void 0?{}:{command:h.command},wearing:s.wearing,tokens:t.tokens()});let T=cn({load:r,event:{moment:h.moment,path:h.path,command:h.command,wearing:s.wearing,tokens:t.tokens()},marks:$,settings:o,off:i}),y=[],O=[];for(let C of T.notices){let b=ai(t.root,C);if(b.trim()===""){C.entry!==null&&O.push(C.entry);continue}y.push(C),p.push({entry:C.entry,cause:C.cause,body:b})}$=ui(T.marks,$,O),!i&&y.length>0&&l.push(...ge(h.moment,{effects:y,tallies:[]},1))}return!i&&$!==w.marks&&xn(t.root,t.id,t.agent,{...w,marks:$}),{refused:u,shown:p}}function ui(e,n,t){if(t.length===0)return e;let r={};for(let[o,s]of Object.entries(e))t.includes(o)||(r[o]=s);for(let o of t){let s=n[o];s!==void 0&&(r[o]=s)}return r}async function fi(e,n){let t=await qe(e);if(t.kind==="none")return D;if(we(e))return D;if(t.kind==="broken")return He([{moment:"commit",block:se(t.message)}])??D;if(n.length===0)return D;let{branch:r,session:o,wearing:s}=Dn(e),{load:i}=t,a=$n(e)?kn(In(e)):null,d=await Ne({load:i,event:{moment:"commit",staged:n,wearing:s},world:a?.world??In(e),off:!1});a!==null&&vn(e,o,[{rail:"guard",moment:"commit",staged:n,wearing:s,world:a.taken()}]),Sn({root:e,session:o,branch:r},ge("commit",d,n.length));let l=d.effects.filter(c=>c.do==="block").map(c=>({moment:"commit",block:c}));return He(l)??D}function gi(){if(process.stdin.isTTY)return{ok:!0,payload:{}};let e;try{e=Ve(0,"utf8")}catch(t){return{ok:!1,why:"unreadable",detail:t.code??"unknown error"}}if(e.trim()==="")return{ok:!0,payload:{}};let n;try{n=JSON.parse(e)}catch{return{ok:!1,why:"unparseable",detail:`${e.length} bytes on stdin, and not JSON`}}return!n||typeof n!="object"||Array.isArray(n)?{ok:!1,why:"unparseable",detail:`JSON, but ${n===null?"null":Array.isArray(n)?"an array":typeof n} \u2014 a payload is an object`}:{ok:!0,payload:n}}async function Fr(e,n){try{if(!Pn(e))return D;let t=gi();if(!t.ok){let r=zt(e,t.why,t.detail);return e==="pre-tool-use"?{stdout:"",stderr:`
132
+ `;function ti(e){return e?ei:ni}function Ar(e){let n=e.settingsUnreadable?{settings:e.settings,added:[]}:Zs(e.settings);return{config:e.hasConfig?null:{path:P,body:ti(e.empty)},gate:!e.isGit||e.gateText!==null?null:{path:Q,body:Xs,mode:493},gateKept:e.isGit&&e.gateText!==null&&!Tr(e.gateText),notGit:!e.isGit,flowDir:!e.hasFlowDir,link:e.resolves?null:e.packageRoot,hooksPath:e.isGit&&e.hooksPath!==Y,settings:n.added.length===0?null:{path:e.settingsPath,value:n.settings},registered:n.added,settingsUnreadable:e.settingsUnreadable?e.settingsPath:null}}function jr(e,n){let t=[];e.config&&t.push(e.config.path),e.gate&&t.push(e.gate.path),e.flowDir&&t.push(`${z}/ \u2014 flow's own state, self-ignoring, never committed`),e.link&&t.push(`node_modules/@jawache/flow \u2192 ${e.link} (a link to the flow that is running \u2014 nothing here resolved @jawache/flow)`),e.settings&&t.push(`${e.settings.path} \u2014 ${e.registered.join(" \xB7 ")}`),e.hooksPath&&t.push(Fn);let r=t.length===0?["flow init \u2014 already set up here; nothing to do."]:["flow init \u2014 created:",...t.map(o=>` + ${o}`)];e.notGit&&r.push(" \xB7 not a git repo, so no commit gate was armed. Run `git init`, then `flow init` again."),e.gateKept&&r.push(` \xB7 kept the ${Q} already here \u2014 flow never overwrites one, so ${Pr} yourself.`),e.settingsUnreadable!==null&&r.push(` \u2717 ${e.settingsUnreadable} is not valid JSON, so nothing was registered and NOTHING was written to it \u2014 every other key in that file is somebody's, and there is no safe merge into bytes nobody could parse. Fix the JSON (a trailing comma, or a // comment) and run \`flow init\` again. Until then no rail fires.`);for(let o of n)r.push(` \u2717 ${o}`);return r.push(" next: `flow status` \u2014 what is bound, and what is not wired yet."),r}function ri(e){let n=Or(e.settings),t=Er.filter(o=>!n.includes(o.event)).map(o=>o.event),r=Tr(e.gateText);return[{id:"config",ok:e.hasConfig,detail:e.hasConfig?e.configPath:`no ${P} in ${e.root} \u2014 \`flow init\` writes one, with a demo you can read in a minute.`},{id:"commit-gate",ok:r,detail:r?`${Q} runs \`flow commit\` over the staged set`:e.gateText===null?`no ${Q} \u2014 \`flow init\` arms it. Until then nothing runs at the commit.`:`${Q} is here but does not call flow \u2014 ${Pr}.`},{id:"hooks-path",ok:e.hooksPath===Y,detail:e.hooksPath===Y?`core.hooksPath = ${Y}`:`core.hooksPath is ${e.hooksPath??"unset"} \u2014 run \`${Fn}\`. It is per-clone, so every fresh checkout needs it.`},...e.grammars.length===0?[]:[{id:"grammars",ok:e.grammars.every(o=>o.present),detail:e.grammars.every(o=>o.present)?`${e.grammars.map(o=>o.name).join(" \xB7 ")} \u2014 declared in ${P}, and their libraries are built`:e.grammars.filter(o=>!o.present).map(o=>dn(o.name,o.libraryPath)).join(`
133
+ `)}],{id:"hooks",ok:t.length===0,detail:t.length===0?`${e.settingsPath} \u2014 ${n.join(" \xB7 ")}`:`${e.settingsPath} does not call flow for ${t.join(" \xB7 ")} \u2014 re-run \`flow init\`. No live rail fires until it does.`}]}function Mr(e){return[...e.refusals.map(n=>`${n.code}: ${n.detail}`),...e.dark,...e.fittings.filter(n=>!n.ok).map(n=>`${n.id}: ${n.detail}`)]}function oi(e,n){return e==="guardrail"?nn(n)&&He.guard.includes(n):tn(n)&&He.brief.includes(n)}function Nr(e){let n=e.load?.ok===!0?e.load.entries:[],t=e.load?.ok===!1?e.load.refusals:[],r=t.length>0?[]:Fe(n),o=r.filter(i=>i.disabled===null&&i.at.length>0&&!i.at.some(a=>oi(i.kind,a))).map(i=>i.id),s=ri(e);return{root:e.root,version:e.version,armed:!e.off,configPath:e.configPath,moments:Be(r,null),categories:[...new Set(n.flatMap(i=>i.categories))].sort(),session:e.session,dark:o,fittings:s,refusals:t,green:Mr({refusals:t,dark:o,fittings:s}).length===0}}function si(e){let n=[(e.on?.length??0)>0?`on ${e.on?.join(" ")}`:"",(e.ignore?.length??0)>0?`not ${e.ignore?.join(" ")}`:"",e.for.length>0?`for ${e.for.join(" \xB7 ")}`:""].filter(o=>o!==""),r=[` ${e.disabled!==null?"\u25CB":e.kind==="guardrail"?"\u2717":"\u{1F35E}"} ${e.id}${n.length===0?"":` \u2014 ${n.join(" \xB7 ")}`}`];return e.disabled!==null?r.push(` off: ${e.disabled||"no reason given"}`):e.says!==null&&r.push(` ${de(e.says,100)}`),r}function Gr(e){if(!e.armed)return[`flow is OFF \u2014 every rail is silenced (${z}/off is there). Delete that file to turn it back on.`];let{breadcrumbs:n,guardrails:t,disabled:r}=e.moments.totals,o=[e.refusals.length>0?`flow ${e.version} \u2014 the config will not load, so every guardrail and breadcrumb here is OFF.`:`flow is ON \u2014 ${Cn(t,"guardrail")} \xB7 ${Cn(n,"breadcrumb")}`+(r===0?"":` \xB7 ${r} disabled`)+", every one resolved and able to fire",` config ${e.configPath}`,` state ${e.root}/${z}`," session "+(e.session===null?"no live session has marked this worktree yet":`${e.session.id}${e.session.agent===null?"":` \xB7 ${e.session.agent}`}, wearing ${e.session.wearing.length===0?"no category":e.session.wearing.join(" \xB7 ")}`)];e.categories.length>0&&o.push(` categories ${e.categories.join(" \xB7 ")} \u2014 what the entries below bind to`);for(let{moment:s,entries:i}of e.moments.moments){o.push(` ${s}`);for(let a of i)o.push(...si(a))}for(let s of e.fittings)o.push(` ${s.ok?"\u2713":"\u2717"} ${s.id}: ${s.detail}`);for(let s of e.refusals)o.push(` \u2717 ${s.code}: ${s.detail}`);for(let s of e.dark)o.push(` \u2717 ${s}: bound only at a moment nothing delivers here \u2014 it loads, it counts, and it will never fire. This adapter carries ${He.guard.join(" \xB7 ")} for a guardrail and ${He.brief.join(" \xB7 ")} for a breadcrumb.`);return o.push(e.green?"green \u2014 every rule loads, every fitting is in place.":`${Cn(Mr(e).length,"red line")} \u2014 flow is NOT fully in force here.`),o}var Cn=(e,n)=>`${e} ${n}${e===1?"":"s"}`;var li=16*1024*1024;function Se(e,n){let t=ii("bash",["-lc",e],{cwd:n,encoding:"utf8",maxBuffer:li,env:ar(process.env)});return t.error?{stdout:"",stderr:`flow could not run a command: ${t.error.message}`,code:127}:{stdout:t.stdout,stderr:t.stderr,code:t.status??1}}function Br(e,n){return Fr(n)?n:Re(e,n)}function F(e,n){try{return qe(Br(e,n),"utf8")}catch{return null}}function ci(e){return e.split(`
134
+ `).map(n=>n.trim()).filter(n=>n!=="")}function Bn(e){return{exec:n=>Promise.resolve(Se(n,e)),fs:{read:n=>Promise.resolve(F(e,n)??""),exists:n=>Promise.resolve(Dn(Br(e,n)))},git:{diff:n=>Promise.resolve(Se(n?`git diff -- ${re(n)}`:"git diff",e).stdout),stagedFiles:()=>Promise.resolve(ci(Se("git diff --cached --name-only --diff-filter=ACM",e).stdout))}}}function Dr(e){try{let n=Re(e,".git"),t=ai(n).isDirectory()?n:Ir(e,/gitdir:\s*(.+)/.exec(qe(n,"utf8"))?.[1]?.trim()??"");return rr(qe(Re(t,"HEAD"),"utf8"))}catch{return null}}function Ln(e){let n=Dr(e),{session:t,agent:r}=zt(e,n);return{branch:n,session:t,agent:r,wearing:r===null?[]:Le(e,t,r).categories??[]}}function ui(e){return process.env.CLAUDE_PROJECT_DIR||e}function Wn(e,n){return(e.grammars??[]).map(t=>Fr(t.libraryPath)?t:{...t,libraryPath:Re(n,t.libraryPath)})}function Hn(e,n){ht(Wn(e,n),Dn)}async function Je(e){let n=Re(e,P);if(!Dn(n))return{kind:"none"};try{let r=(await import(di(n).href)).default;return!r||typeof r!="object"||!Array.isArray(r.bindings)?{kind:"broken",message:`flow: ${P} has no default export from \`defineConfig([\u2026])\` \u2014 that call IS the config, and its result is what flow reads.`}:(Hn(r.settings,e),{kind:"loaded",config:r,load:ue(r)})}catch(t){return{kind:"broken",message:Ve(P,t.message,process.versions.node)}}}function In(e){let n=null;return()=>(n??={value:e()},n.value)}function fi(e,n){let t=typeof e.transcript_path=="string"?e.transcript_path:"",r=In(()=>t===""?null:F(n,t));return{root:n,id:typeof e.session_id=="string"&&e.session_id!==""?e.session_id:"unknown",agent:typeof e.agent_id=="string"&&e.agent_id!==""?e.agent_id:"main",branch:Dr(n),transcriptPath:t,transcript:r,tokens:In(()=>{let o=r();return o===null?0:nr(o)}),turn:In(()=>{let o=r();return o===null?[]:tr(o,n)})}}function gi(e,n,t){if(t.length===0)return{wearing:[],faults:[],fresh:!1};let r=e.transcriptPath===""?null:or(e.transcriptPath),o=sr({payload:n,transcript:e.transcript(),sidecar:r===null?null:F(e.root,r)});return Ht(e.root,e.id,e.agent,o,t)}function _r(e,n){return{root:e,read:t=>F(e,t),turn:n.turn}}function pi(e,n){return n.text!==void 0?n.text:n.file===void 0?"":F(e,n.file)??""}function yi(e){return e.rail==="guard"&&e.moment==="commit"?e.staged?.length??0:1}async function mi(e,n,t){let r=await Je(t);if(r.kind==="none")return D;let o=we(t),s=fi(n,t);e==="pre-tool-use"&&!o&&s.id!=="unknown"&&Jt(t,s.id,s.agent,s.branch);let i=$=>{if(o)return D;let h=On(F(t,P)),T=Zt(An(e,n,_r(t,s)),h,$),y=jn(e,T);return T.told===null||y.exitCode!==0?y:{...y,stderr:`${T.told}
135
+ `}};if(r.kind==="broken")return i(r.message);let{load:a,config:d}=r;if(!a.ok)return i(te(a.refusals));let l=a.entries,c=gi(s,n,Rt(l)),u=An(e,n,_r(t,s)),p=[];if(e==="pre-tool-use"&&!o){let $=ir(n,t);$&&p.push($)}let g=[],m=vn(t),w=await hi({events:u,session:s,load:a,settings:d.settings,identity:c,off:o,hook:e,payload:n,rows:p,steps:m?g:null});return o||Rn({root:t,session:s.id,branch:s.branch},p),m&&En(t,s.id,g),jn(e,w)}async function hi(e){let{events:n,session:t,load:r,settings:o,identity:s,off:i,hook:a,payload:d,rows:l,steps:c}=e,u=[],p=[],g=Bn(t.root),m=a==="session-start"&&d.source==="compact",w=Le(t.root,t.id,t.agent),$=m&&r.ok?fn(w.marks,r.entries):w.marks;m&&!i&&l.push({kind:"compaction"}),m&&c?.push({rail:"compaction"});for(let h of n){if(h.rail==="guard"){let C=c===null?null:bn(g),b=await Ge({load:r,event:{moment:h.moment,file:h.file,command:h.command,staged:h.staged,turn:h.turn,wearing:s.wearing},world:C?.world??g,faults:s.faults,off:i});c?.push({rail:"guard",moment:h.moment,...h.file===void 0?{}:{file:h.file},...h.command===void 0?{}:{command:h.command},...h.staged===void 0?{}:{staged:h.staged},...h.turn===void 0?{}:{turn:h.turn},wearing:s.wearing,world:C?.taken()??{}});for(let x of b.effects)x.do==="block"&&u.push({moment:h.moment,block:x});i||l.push(...ge(h.moment,b,yi(h)));continue}c?.push({rail:"brief",moment:h.moment,...h.path===void 0?{}:{path:h.path},...h.command===void 0?{}:{command:h.command},wearing:s.wearing,tokens:t.tokens()});let T=un({load:r,event:{moment:h.moment,path:h.path,command:h.command,wearing:s.wearing,tokens:t.tokens()},marks:$,settings:o,off:i}),y=[],O=[];for(let C of T.notices){let b=pi(t.root,C);if(b.trim()===""){C.entry!==null&&O.push(C.entry);continue}y.push(C),p.push({entry:C.entry,cause:C.cause,body:b})}$=ki(T.marks,$,O),!i&&y.length>0&&l.push(...ge(h.moment,{effects:y,tallies:[]},1))}return!i&&$!==w.marks&&Sn(t.root,t.id,t.agent,{...w,marks:$}),{refused:u,shown:p}}function ki(e,n,t){if(t.length===0)return e;let r={};for(let[o,s]of Object.entries(e))t.includes(o)||(r[o]=s);for(let o of t){let s=n[o];s!==void 0&&(r[o]=s)}return r}async function bi(e,n){let t=await Je(e);if(t.kind==="none")return D;if(we(e))return D;if(t.kind==="broken")return Ue([{moment:"commit",block:se(t.message)}])??D;if(n.length===0)return D;let{branch:r,session:o,wearing:s}=Ln(e),{load:i}=t,a=vn(e)?bn(Bn(e)):null,d=await Ge({load:i,event:{moment:"commit",staged:n,wearing:s},world:a?.world??Bn(e),off:!1});a!==null&&En(e,o,[{rail:"guard",moment:"commit",staged:n,wearing:s,world:a.taken()}]),Rn({root:e,session:o,branch:r},ge("commit",d,n.length));let l=d.effects.filter(c=>c.do==="block").map(c=>({moment:"commit",block:c}));return Ue(l)??D}function wi(){if(process.stdin.isTTY)return{ok:!0,payload:{}};let e;try{e=qe(0,"utf8")}catch(t){return{ok:!1,why:"unreadable",detail:t.code??"unknown error"}}if(e.trim()==="")return{ok:!0,payload:{}};let n;try{n=JSON.parse(e)}catch{return{ok:!1,why:"unparseable",detail:`${e.length} bytes on stdin, and not JSON`}}return!n||typeof n!="object"||Array.isArray(n)?{ok:!1,why:"unparseable",detail:`JSON, but ${n===null?"null":Array.isArray(n)?"an array":typeof n} \u2014 a payload is an object`}:{ok:!0,payload:n}}async function Lr(e,n){try{if(!Tn(e))return D;let t=wi();if(!t.ok){let r=er(e,t.why,t.detail);return e==="pre-tool-use"?{stdout:"",stderr:`
136
136
  ${r}
137
137
  `,exitCode:2}:{stdout:"",stderr:`${r}
138
- `,exitCode:0}}return await li(e,t.payload,oi(n))}catch(t){return{stdout:"",stderr:`[flow hook ${e}] the guard itself failed \u2014 ${t.message}
139
- `,exitCode:0}}}async function Gr(e,n){let t=jr(n);return fi(t,e.map(r=>H(r,t)))}import{existsSync as pi,readFileSync as yi,readdirSync as mi,statSync as hi}from"node:fs";import{homedir as Hn}from"node:os";import{join as ye}from"node:path";function Je(e){try{return yi(e,"utf8")}catch{return null}}function ki(e,n=Hn()){return ye(n,".claude","projects",rr(e))}function bi(e){let n=r=>{try{return mi(r,{withFileTypes:!0}).map(o=>o.isDirectory()?`${o.name}/`:o.name)}catch{return[]}},t=[];for(let r of n(e)){if(!r.endsWith("/")){t.push(r);continue}let o=r.slice(0,-1);for(let s of n(ye(e,o,"subagents")))s.endsWith("/")||t.push(`${o}/subagents/${s}`)}return t.sort()}function wi(e,n=Hn()){let t=ki(e,n);if(!pi(t))return{dir:t,exists:!1,transcripts:[],ignored:[]};let{transcripts:r,ignored:o}=or(bi(t));return{dir:t,exists:!0,transcripts:r.map(s=>{let i=ye(t,s.path),a=0,d=0;try{let l=hi(i);a=l.size,d=l.mtimeMs}catch{}return{ref:s,file:i,bytes:a,mtimeMs:d}}),ignored:o}}function xi(e){let n=Se("git ls-files",e);return n.code===0?n.stdout.split(`
140
- `).filter(t=>t.trim()!==""):[]}function Ir(e,n,t={}){let r=t.home??Hn(),o=t.nowMs??Date.now(),s=wi(e,r),i=[],a=new Map,d=new Map;for(let b of s.transcripts){if(b.ref.agent!==null){let V=d.get(b.ref.session)??[];V.push(b),d.set(b.ref.session,V);continue}let x=Je(b.file)??"",I=ir(x);I.cwd!==null&&I.cwd!==e||(a.set(b.ref.session,x),i.push({id:b.ref.session,bytes:b.bytes,mtimeMs:b.mtimeMs,started:I.started,branch:I.branch}))}let l=t.branch?i.filter(b=>b.branch===t.branch):i,c=t.session?{analyse:l.filter(b=>b.id===t.session),excluded:[],counts:{backlog:l.length,analysed:l.filter(b=>b.id===t.session).length,excluded:0}}:yr(l,Dt(e),t),u=Bt(e),p=new Map(u.map(b=>[b.session,b.rows])),g=n.ok?Fe(n.entries):[],m=cr(Je(ye(e,"justfile"))??""),w=gr(Je(ye(e,P))),$=[],h=[],T=[],y=0;for(let b of c.analyse){let x=p.get(b.id)??[];x.length>0&&(y+=1);let I=a.get(b.id)??"",V=lr(I,e);$.push({session:b.id,read:ur(V,m)}),h.push(...pr(x,V,w));let ve=ar(I);for(let Z of d.get(b.id)??[])T.push({...hr({session:b.id,agent:Z.ref.agent??"",meta:Z.ref.meta===null?null:sr(Je(ye(s.dir,Z.ref.meta))),spawns:ve})})}let O=Tt({sessions:u,entries:g,nowMs:o}),C=fr($);return{root:e,store:{dir:s.dir,exists:s.exists,ignored:s.ignored},selection:c,coverage:{analysed:c.analyse.length,withRecord:y,narrativeOnly:c.analyse.length-y},health:mr({armed:u.length>0,rows:u.reduce((b,x)=>b+x.rows.length,0),withRecord:y,analysed:c.analyse.length}),metrics:O,moments:Ie(g,O),terrain:At({paths:xi(e),heat:O.heat,entries:g}),narrative:C,uncovered:kr(C.touched,g),actors:T,weakened:h,marked:t.mark===!0?Lt(e,c.analyse.map(b=>b.id)):null}}import{execFileSync as Dr}from"node:child_process";import{createRequire as Si}from"node:module";import{chmodSync as Ri,existsSync as $e,lstatSync as $i,mkdirSync as Un,symlinkSync as vi,unlinkSync as Ei,writeFileSync as Br}from"node:fs";import{homedir as Ci}from"node:os";import{dirname as ze,join as L,resolve as Lr}from"node:path";import{fileURLToPath as Oi}from"node:url";function Wr(){return L(process.env.CLAUDE_CONFIG_DIR||L(Ci(),".claude"),"settings.json")}function Pi(){let e=ze(Oi(import.meta.url));for(let n=0;n<6;n++){let t=G(e,"package.json");if(t!==null)try{if(JSON.parse(t).name==="@jawache/flow")return e}catch{}let r=ze(e);if(r===e)break;e=r}return null}function Ti(e){try{return Si(L(e,"noop.js")).resolve("@jawache/flow"),!0}catch{return!1}}function Hr(e){try{let n=Dr("git",["-C",e,"config","--get","core.hooksPath"],{encoding:"utf8"}).trim();return n===""?null:n}catch{return null}}function Ur(e,n){let t=G(e,n);if(t===null||t.trim()==="")return{value:null,unreadable:!1};try{return{value:JSON.parse(t),unreadable:!1}}catch{return{value:null,unreadable:!0}}}function Ai(e){let{session:n,agent:t,wearing:r}=Dn(e);return t===null?null:{id:n,agent:t,wearing:r}}function Mi(e,n){let t=Wr(),r=Ur(e,t);return{root:e,empty:n,isGit:$e(L(e,".git")),hasConfig:$e(L(e,P)),gateText:G(e,Q),hasFlowDir:$e(L(e,z)),hooksPath:Hr(e),settingsPath:t,settings:r.value,settingsUnreadable:r.unreadable,resolves:Ti(e),packageRoot:Pi()}}function ji(e,n){let t=[],r=(o,s)=>{try{s()}catch(i){t.push(`${o}: ${i.message}`)}};for(let o of[n.config,n.gate])o!==null&&r(`could not write ${o.path}`,()=>{let s=L(e,o.path);Un(ze(s),{recursive:!0}),Br(s,o.body),o.mode!==void 0&&Ri(s,o.mode)});return n.flowDir&&r(`could not create ${z}/`,()=>{ae(e)}),n.link!==null&&r("could not link @jawache/flow",()=>{let o=L(e,"node_modules","@jawache");Un(o,{recursive:!0});let s=L(o,"flow");$i(s,{throwIfNoEntry:!1})?.isSymbolicLink()&&!$e(s)&&Ei(s),vi(n.link,s,"dir")}),n.settings!==null&&r(`could not write ${n.settings.path}`,()=>{Un(ze(n.settings?.path??""),{recursive:!0}),Br(n.settings?.path??"",`${JSON.stringify(n.settings?.value,null,2)}
141
- `)}),n.hooksPath&&r("could not set core.hooksPath",()=>Dr("git",["-C",e,"config","core.hooksPath",Y],{stdio:"ignore"})),t}function Kr(e,n){let t=Lr(e),r=Er(Mi(t,n.includes("--empty"))),o=ji(t,r);return{stdout:`${Cr(r,o).join(`
138
+ `,exitCode:0}}return await mi(e,t.payload,ui(n))}catch(t){return{stdout:"",stderr:`[flow hook ${e}] the guard itself failed \u2014 ${t.message}
139
+ `,exitCode:0}}}async function Wr(e,n){let t=Ir(n);return bi(t,e.map(r=>H(r,t)))}import{existsSync as xi,readFileSync as Si,readdirSync as Ri,statSync as $i}from"node:fs";import{homedir as Un}from"node:os";import{join as ye}from"node:path";function ze(e){try{return Si(e,"utf8")}catch{return null}}function vi(e,n=Un()){return ye(n,".claude","projects",dr(e))}function Ei(e){let n=r=>{try{return Ri(r,{withFileTypes:!0}).map(o=>o.isDirectory()?`${o.name}/`:o.name)}catch{return[]}},t=[];for(let r of n(e)){if(!r.endsWith("/")){t.push(r);continue}let o=r.slice(0,-1);for(let s of n(ye(e,o,"subagents")))s.endsWith("/")||t.push(`${o}/subagents/${s}`)}return t.sort()}function Ci(e,n=Un()){let t=vi(e,n);if(!xi(t))return{dir:t,exists:!1,transcripts:[],ignored:[]};let{transcripts:r,ignored:o}=lr(Ei(t));return{dir:t,exists:!0,transcripts:r.map(s=>{let i=ye(t,s.path),a=0,d=0;try{let l=$i(i);a=l.size,d=l.mtimeMs}catch{}return{ref:s,file:i,bytes:a,mtimeMs:d}}),ignored:o}}function Oi(e){let n=Se("git ls-files",e);return n.code===0?n.stdout.split(`
140
+ `).filter(t=>t.trim()!==""):[]}function Hr(e,n,t={}){let r=t.home??Un(),o=t.nowMs??Date.now(),s=Ci(e,r),i=[],a=new Map,d=new Map;for(let b of s.transcripts){if(b.ref.agent!==null){let V=d.get(b.ref.session)??[];V.push(b),d.set(b.ref.session,V);continue}let x=ze(b.file)??"",I=ur(x);I.cwd!==null&&I.cwd!==e||(a.set(b.ref.session,x),i.push({id:b.ref.session,bytes:b.bytes,mtimeMs:b.mtimeMs,started:I.started,branch:I.branch}))}let l=t.branch?i.filter(b=>b.branch===t.branch):i,c=t.session?{analyse:l.filter(b=>b.id===t.session),excluded:[],counts:{backlog:l.length,analysed:l.filter(b=>b.id===t.session).length,excluded:0}}:wr(l,Kt(e),t),u=Ut(e),p=new Map(u.map(b=>[b.session,b.rows])),g=n.ok?Fe(n.entries):[],m=yr(ze(ye(e,"justfile"))??""),w=kr(ze(ye(e,P))),$=[],h=[],T=[],y=0;for(let b of c.analyse){let x=p.get(b.id)??[];x.length>0&&(y+=1);let I=a.get(b.id)??"",V=pr(I,e);$.push({session:b.id,read:mr(V,m)}),h.push(...br(x,V,w));let ve=fr(I);for(let Z of d.get(b.id)??[])T.push({...Sr({session:b.id,agent:Z.ref.agent??"",meta:Z.ref.meta===null?null:cr(ze(ye(s.dir,Z.ref.meta))),spawns:ve})})}let O=Gt({sessions:u,entries:g,nowMs:o}),C=hr($);return{root:e,store:{dir:s.dir,exists:s.exists,ignored:s.ignored},selection:c,coverage:{analysed:c.analyse.length,withRecord:y,narrativeOnly:c.analyse.length-y},health:xr({armed:u.length>0,rows:u.reduce((b,x)=>b+x.rows.length,0),withRecord:y,analysed:c.analyse.length}),metrics:O,moments:Be(g,O),terrain:_t({paths:Oi(e),heat:O.heat,entries:g}),narrative:C,uncovered:Rr(C.touched,g),actors:T,weakened:h,marked:t.mark===!0?Vt(e,c.analyse.map(b=>b.id)):null}}import{execFileSync as Kr}from"node:child_process";import{createRequire as Pi}from"node:module";import{chmodSync as Ti,existsSync as $e,lstatSync as Ai,mkdirSync as Kn,symlinkSync as ji,unlinkSync as Mi,writeFileSync as Ur}from"node:fs";import{homedir as Ni}from"node:os";import{dirname as Ye,join as L,resolve as Vr}from"node:path";import{fileURLToPath as Gi}from"node:url";function qr(){return L(process.env.CLAUDE_CONFIG_DIR||L(Ni(),".claude"),"settings.json")}function _i(){let e=Ye(Gi(import.meta.url));for(let n=0;n<6;n++){let t=F(e,"package.json");if(t!==null)try{if(JSON.parse(t).name==="@jawache/flow")return e}catch{}let r=Ye(e);if(r===e)break;e=r}return null}function Fi(e){try{return Pi(L(e,"noop.js")).resolve("@jawache/flow"),!0}catch{return!1}}function Jr(e){try{let n=Kr("git",["-C",e,"config","--get","core.hooksPath"],{encoding:"utf8"}).trim();return n===""?null:n}catch{return null}}function zr(e,n){let t=F(e,n);if(t===null||t.trim()==="")return{value:null,unreadable:!1};try{return{value:JSON.parse(t),unreadable:!1}}catch{return{value:null,unreadable:!0}}}function Ii(e){let{session:n,agent:t,wearing:r}=Ln(e);return t===null?null:{id:n,agent:t,wearing:r}}function Bi(e,n){let t=qr(),r=zr(e,t);return{root:e,empty:n,isGit:$e(L(e,".git")),hasConfig:$e(L(e,P)),gateText:F(e,Q),hasFlowDir:$e(L(e,z)),hooksPath:Jr(e),settingsPath:t,settings:r.value,settingsUnreadable:r.unreadable,resolves:Fi(e),packageRoot:_i()}}function Di(e,n){let t=[],r=(o,s)=>{try{s()}catch(i){t.push(`${o}: ${i.message}`)}};for(let o of[n.config,n.gate])o!==null&&r(`could not write ${o.path}`,()=>{let s=L(e,o.path);Kn(Ye(s),{recursive:!0}),Ur(s,o.body),o.mode!==void 0&&Ti(s,o.mode)});return n.flowDir&&r(`could not create ${z}/`,()=>{ae(e)}),n.link!==null&&r("could not link @jawache/flow",()=>{let o=L(e,"node_modules","@jawache");Kn(o,{recursive:!0});let s=L(o,"flow");Ai(s,{throwIfNoEntry:!1})?.isSymbolicLink()&&!$e(s)&&Mi(s),ji(n.link,s,"dir")}),n.settings!==null&&r(`could not write ${n.settings.path}`,()=>{Kn(Ye(n.settings?.path??""),{recursive:!0}),Ur(n.settings?.path??"",`${JSON.stringify(n.settings?.value,null,2)}
141
+ `)}),n.hooksPath&&r("could not set core.hooksPath",()=>Kr("git",["-C",e,"config","core.hooksPath",Y],{stdio:"ignore"})),t}function Yr(e,n){let t=Vr(e),r=Ar(Bi(t,n.includes("--empty"))),o=Di(t,r);return{stdout:`${jr(r,o).join(`
142
142
  `)}
143
- `,stderr:"",exitCode:o.length===0?0:1}}async function Vr(e,n){let t=Lr(e),r=L(t,P),o=await qe(t);if(o.kind==="broken")return{stdout:"",stderr:`${o.message}
144
- `,exitCode:2};let s=Wr(),i={root:t,version:me,off:we(t),configPath:r,hasConfig:o.kind==="loaded",load:o.kind==="loaded"?o.load:null,gateText:G(t,Q),hooksPath:Hr(t),settingsPath:s,settings:Ur(t,s).value,grammars:o.kind==="loaded"?Ln(o.config.settings,t).map(l=>({name:l.name,libraryPath:l.libraryPath,present:$e(l.libraryPath)})):[],session:Ai(t)},a=Pr(i),d=Jt(a);return n.includes("--json")?{stdout:`${JSON.stringify(a,null,2)}
145
- `,stderr:"",exitCode:d}:{stdout:`${Tr(a).join(`
143
+ `,stderr:"",exitCode:o.length===0?0:1}}async function Qr(e,n){let t=Vr(e),r=L(t,P),o=await Je(t);if(o.kind==="broken")return{stdout:"",stderr:`${o.message}
144
+ `,exitCode:2};let s=qr(),i={root:t,version:me,off:we(t),configPath:r,hasConfig:o.kind==="loaded",load:o.kind==="loaded"?o.load:null,gateText:F(t,Q),hooksPath:Jr(t),settingsPath:s,settings:zr(t,s).value,grammars:o.kind==="loaded"?Wn(o.config.settings,t).map(l=>({name:l.name,libraryPath:l.libraryPath,present:$e(l.libraryPath)})):[],session:Ii(t)},a=Nr(i),d=Xt(a);return n.includes("--json")?{stdout:`${JSON.stringify(a,null,2)}
145
+ `,stderr:"",exitCode:d}:{stdout:`${Gr(a).join(`
146
146
  `)}
147
- `,stderr:"",exitCode:d}}var Vn=process.argv.slice(2);process.removeAllListeners("warning");process.on("warning",e=>{e.name!=="ExperimentalWarning"&&process.stderr.write(`${e.stack??e.message}
148
- `)});Fi({load(e,n,t){if(!wr(e))return t(e,n);let r=_i(Ii(e),"utf8");return{format:"module",shortCircuit:!0,source:Gi(r,{mode:"strip",sourceUrl:e})}}});async function qn(e){let n=Kn(process.cwd(),e),t;try{t=await import(Bi(n).href)}catch(o){throw new Error(Ke(e,o.message,process.versions.node))}let r=t.default;if(!r||typeof r!="object"||!Array.isArray(r.bindings))throw new Error(`${e} has no default export from \`defineConfig([\u2026])\` \u2014 that call IS the config, and its result is what flow reads.`);return Wn(r.settings,Di(n)),r}function Wi(e,n){let t=n.filter(i=>!i.ok),r=e.filter(i=>i.spec.kind==="guardrail"&&!i.spec.disabled).length;for(let i of t)process.stdout.write(` \u2717 ${i.entry} \xB7 ${i.expect} case ${i.index+1}
147
+ `,stderr:"",exitCode:d}}var qn=process.argv.slice(2);process.removeAllListeners("warning");process.on("warning",e=>{e.name!=="ExperimentalWarning"&&process.stderr.write(`${e.stack??e.message}
148
+ `)});Hi({load(e,n,t){if(!vr(e))return t(e,n);let r=Wi(Ki(e),"utf8");return{format:"module",shortCircuit:!0,source:Ui(r,{mode:"strip",sourceUrl:e})}}});async function Jn(e){let n=Vn(process.cwd(),e),t;try{t=await import(Vi(n).href)}catch(o){throw new Error(Ve(e,o.message,process.versions.node))}let r=t.default;if(!r||typeof r!="object"||!Array.isArray(r.bindings))throw new Error(`${e} has no default export from \`defineConfig([\u2026])\` \u2014 that call IS the config, and its result is what flow reads.`);return Hn(r.settings,qi(n)),r}function zi(e,n){let t=n.filter(i=>!i.ok),r=e.filter(i=>i.spec.kind==="guardrail"&&!i.spec.disabled).length;for(let i of t)process.stdout.write(` \u2717 ${i.entry} \xB7 ${i.expect} case ${i.index+1}
149
149
  ${i.detail}
150
150
  `);let o=e.filter(i=>i.spec.disabled).length,s=o?` \xB7 ${o} disabled, not run`:"";return t.length===0?(process.stdout.write(`flow test \u2014 ${n.length} cases over ${r} guardrails, all green${s}
151
151
  `),0):(process.stdout.write(`flow test \u2014 ${t.length} of ${n.length} cases failed, over ${r} guardrails${s}
152
- `),1)}async function Hi(e){let n=await qn(e),t=ot(ue(n));return Wi(t,await pt(t))}function qr(e){e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr),process.exitCode=e.exitCode}function K(e,n){let t=e.indexOf(`--${n}`);if(t===-1)return null;let r=e[t+1];return r===void 0||r.startsWith("--")?"":r}var Ui=e=>{let n=[];for(let t=0;t<e.length;t++){let r=e[t];if(!r.startsWith("--")){n.push(r);continue}let o=e[t+1];o!==void 0&&!o.startsWith("--")&&(t+=1)}return n};async function Ki(e){let[n,t]=Ui(e);if(n===void 0)return process.stderr.write(`flow replay <recording.jsonl> [config] [--against <log.jsonl>]
153
- `),2;let r=await qn(t??P),o=ue(r),s=Wt(Kn(process.cwd(),n));if(s.steps.length===0)return process.stderr.write(`flow replay \u2014 ${n} holds no steps. Arm the recorder with \`touch .flow/record\`.
154
- `),2;let i=await Nt({load:o,recording:s,settings:r.settings}),a=(u,p)=>de(u[p],100),d=i.rows.filter(u=>u.kind==="guardrail"||u.kind==="breadcrumb");for(let u of d){let p=a(u,"subject");process.stdout.write(u.kind==="guardrail"?` \u2717 ${a(u,"id")} \xB7 ${a(u,"moment")}${p===""?"":` \xB7 ${p}`}
152
+ `),1)}async function Yi(e){let n=await Jn(e),t=dt(ue(n));return zi(t,await bt(t))}function Zr(e){e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr),process.exitCode=e.exitCode}function K(e,n){let t=e.indexOf(`--${n}`);if(t===-1)return null;let r=e[t+1];return r===void 0||r.startsWith("--")?"":r}var Qi=e=>{let n=[];for(let t=0;t<e.length;t++){let r=e[t];if(!r.startsWith("--")){n.push(r);continue}let o=e[t+1];o!==void 0&&!o.startsWith("--")&&(t+=1)}return n};async function Zi(e){let[n,t]=Qi(e);if(n===void 0)return process.stderr.write(`flow replay <recording.jsonl> [config] [--against <log.jsonl>]
153
+ `),2;let r=await Jn(t??P),o=ue(r),s=qt(Vn(process.cwd(),n));if(s.steps.length===0)return process.stderr.write(`flow replay \u2014 ${n} holds no steps. Arm the recorder with \`touch .flow/record\`.
154
+ `),2;let i=await Bt({load:o,recording:s,settings:r.settings}),a=(u,p)=>de(u[p],100),d=i.rows.filter(u=>u.kind==="guardrail"||u.kind==="breadcrumb");for(let u of d){let p=a(u,"subject");process.stdout.write(u.kind==="guardrail"?` \u2717 ${a(u,"id")} \xB7 ${a(u,"moment")}${p===""?"":` \xB7 ${p}`}
155
155
  `:` \u{1F35E} ${a(u,"id")} \xB7 ${a(u,"moment")} \xB7 ${a(u,"cause")}
156
156
  `)}process.stdout.write(`flow replay \u2014 ${s.steps.length} steps \xB7 ${d.filter(u=>u.kind==="guardrail").length} blocked \xB7 ${d.filter(u=>u.kind==="breadcrumb").length} shown, with no repo and no harness
157
157
  `);for(let u of i.unanswered)process.stderr.write(` ! the recording never answered a ${u.kind} of \`${u.asked}\`
158
- `);let l=K(e,"against");if(l===null)return i.unanswered.length>0?1:0;let c=_t(i.rows,Rn(Kn(process.cwd(),l)));for(let u of c)process.stderr.write(` ${u.side==="replay"?"+":"-"} [${u.at}] ${u.row}
158
+ `);let l=K(e,"against");if(l===null)return i.unanswered.length>0?1:0;let c=Dt(i.rows,$n(Vn(process.cwd(),l)));for(let u of c)process.stderr.write(` ${u.side==="replay"?"+":"-"} [${u.at}] ${u.row}
159
159
  `);return process.stdout.write(c.length===0?`flow replay \u2014 the replay and ${l} agree on every block and every injection. Diff empty.
160
160
  `:`flow replay \u2014 ${c.length} difference(s) against ${l}.
161
- `),c.length===0&&i.unanswered.length===0?0:1}async function Vi(e){let n=process.cwd(),t=Ni(Li(n,P))?ue(await qn(P)):{ok:!0,entries:[]},r=K(e,"limit"),o=K(e,"since"),s=Ir(n,t,{session:K(e,"session"),branch:K(e,"branch"),limit:r===null||r===""?null:Number(r),all:K(e,"all")!==null,largest:K(e,"largest")!==null,since:o===null||o===""?null:Date.parse(o),mark:K(e,"mark")!==null});if(K(e,"json")!==null)return process.stdout.write(`${JSON.stringify(s,null,2)}
162
- `),s.health.blocked===null?0:1;let i=br(s);return process.stdout.write(`${i.join(`
161
+ `),c.length===0&&i.unanswered.length===0?0:1}async function Xi(e){let n=process.cwd(),t=Li(Ji(n,P))?ue(await Jn(P)):{ok:!0,entries:[]},r=K(e,"limit"),o=K(e,"since"),s=Hr(n,t,{session:K(e,"session"),branch:K(e,"branch"),limit:r===null||r===""?null:Number(r),all:K(e,"all")!==null,largest:K(e,"largest")!==null,since:o===null||o===""?null:Date.parse(o),mark:K(e,"mark")!==null});if(K(e,"json")!==null)return process.stdout.write(`${JSON.stringify(s,null,2)}
162
+ `),s.health.blocked===null?0:1;let i=$r(s);return process.stdout.write(`${i.join(`
163
163
  `)}
164
- `),s.health.blocked===null?0:1}var[U,...le]=Vn;if(Vn.includes("--version")||Vn.includes("-v"))process.stdout.write(`${me}
165
- `);else if(U==="test")try{process.exitCode=await Hi(le[0]??"flow.config.ts")}catch(e){process.stderr.write(`${e instanceof fe,e.message}
166
- `),process.exitCode=2}else if(U==="hook")qr(await Fr(le[0]??"",process.cwd()));else if(U==="commit")qr(await Gr(le,process.cwd()));else if(U==="init"||U==="status"){let e=U==="init"?Kr(process.cwd(),le):await Vr(process.cwd(),le);e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr),process.exitCode=e.exitCode}else if(U==="replay"||U==="facts")try{process.exitCode=U==="replay"?await Ki(le):await Vi(le)}catch(e){process.stderr.write(`${e instanceof fe,e.message}
167
- `),process.exitCode=2}else process.stderr.write([`flow ${me}`,""," flow init [--empty] scaffold flow.config.ts, arm the git gate, register the hooks"," flow status [--json] what is bound here, at which moments \u2014 and what is not wired yet"," flow test [config] run every bound entry's cases (default: flow.config.ts)",` flow hook <event> a harness hook, payload on stdin \u2014 ${On.join(" \xB7 ")}`," flow commit <files\u2026> the git pre-commit gate, over the staged set"," flow replay <file> a recorded session, back through the engine \u2014 --against <log> diffs it"," flow facts what the record and the conversations say about this repo \u2014 --json for all of it",""].join(`
164
+ `),s.health.blocked===null?0:1}var[U,...le]=qn;if(qn.includes("--version")||qn.includes("-v"))process.stdout.write(`${me}
165
+ `);else if(U==="test")try{process.exitCode=await Yi(le[0]??"flow.config.ts")}catch(e){process.stderr.write(`${e instanceof fe,e.message}
166
+ `),process.exitCode=2}else if(U==="hook")Zr(await Lr(le[0]??"",process.cwd()));else if(U==="commit")Zr(await Wr(le,process.cwd()));else if(U==="init"||U==="status"){let e=U==="init"?Yr(process.cwd(),le):await Qr(process.cwd(),le);e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr),process.exitCode=e.exitCode}else if(U==="replay"||U==="facts")try{process.exitCode=U==="replay"?await Zi(le):await Xi(le)}catch(e){process.stderr.write(`${e instanceof fe,e.message}
167
+ `),process.exitCode=2}else process.stderr.write([`flow ${me}`,""," flow init [--empty] scaffold flow.config.ts, arm the git gate, register the hooks"," flow status [--json] what is bound here, at which moments \u2014 and what is not wired yet"," flow test [config] run every bound entry's cases (default: flow.config.ts)",` flow hook <event> a harness hook, payload on stdin \u2014 ${Pn.join(" \xB7 ")}`," flow commit <files\u2026> the git pre-commit gate, over the staged set"," flow replay <file> a recorded session, back through the engine \u2014 --against <log> diffs it"," flow facts what the record and the conversations say about this repo \u2014 --json for all of it",""].join(`
168
168
  `)),process.exitCode=2;