@paniolo/scan 0.2.1 → 0.2.3

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/cli.js CHANGED
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import{readFile as ra}from"node:fs/promises";var wt={status:"not-run",score:null,grade:"not-run",checks:[],findings:[]};var ea=[{min:85,grade:"excellent"},{min:70,grade:"good"},{min:50,grade:"fair"},{min:0,grade:"poor"}];function we(e){for(let{min:t,grade:n}of ea)if(e>=t)return n;return"poor"}function Rt(e){let t=(e.hint??"").toLowerCase().match(/[a-z0-9]+/g),n=t===null?"":[...new Set(t)].toSorted().join(" ");return`${e.ruleId}::${e.file??""}::${n}`}function Zr(e){let t=e.indexOf(":");return t===-1?null:e.slice(t+1)}function I(e,t){let n=e[t];return typeof n=="string"?n:""}import{access as ta}from"node:fs/promises";import na from"node:path";var W=75,bt=300,Ue=["CLAUDE.md","GEMINI.md",".github/copilot-instructions.md"];function E(e,t){return e.files.some(n=>n.path===t)}function h(e,t){return e.fileContents.get(t)??null}function U(e,t){return e.files.find(s=>s.path===t)?.lines??null}function eo(e){return e.includes("AGENTS.md")||e.includes("docs/ai/rules.md")}function Be(e){return e.match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1]??null}function ce(e,t){return new RegExp(`^${t}:`,"m").test(e)}async function le(e,t){try{return await ta(na.join(e,t)),!0}catch{return!1}}function ue(e,t){return e.files.filter(n=>n.path.startsWith(t)).map(n=>n.path)}function N(e){return e.files.some(t=>t.path.startsWith("skills/")&&t.path.endsWith("/SKILL.md"))}function Ve(e){return e.includes("available-skills.md")||e.includes("skills/*/SKILL.md")||e.includes("npm run qmd")||e.includes("skills/")&&e.includes("available-skills")}function ze(e){return/agent routing/i.test(e)&&e.includes("|")&&/agents\/.*\.agent\.md/.test(e)}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var w={"AI1-contradiction":{checkId:"AI1-contradiction",title:"Cross-guidance contradictions",schemaKey:"contradictions",entryFields:["ruleA","ruleB","explanation"]},"AI2-adapter-fidelity":{checkId:"AI2-adapter-fidelity",title:"Adapter fidelity to shared layer",schemaKey:"drifts",entryFields:["claim","explanation"]},"AI3-security-review":{checkId:"AI3-security-review",title:"Semantic security review (advisory)",schemaKey:"risks",entryFields:["location","risk","explanation"]},"AI4-deadweight":{checkId:"AI4-deadweight",title:"Dead-weight instructions (deletion test)",schemaKey:"deadweight",entryFields:["rule","reason"]},"AI5-vague-rules":{checkId:"AI5-vague-rules",title:"Vague rules lacking a decision boundary",schemaKey:"vague",entryFields:["rule","reason"]}};function to(e){return typeof e=="string"&&e in w}function Ct(e){if(!y(e.data))return[];let t=e.data[w[e.checkId].schemaKey];return Array.isArray(t)?t.filter(n=>y(n)):[]}function At(e){let t=Ct(e);if(e.checkId==="AI1-contradiction")return t.map(s=>({ruleId:"ai-contradiction",severity:"warn",message:`Contradiction: ${I(s,"explanation")}`,file:null,line:null,harnesses:[],hint:`"${I(s,"ruleA")}" conflicts with "${I(s,"ruleB")}"`}));if(e.checkId==="AI4-deadweight")return t.map(s=>({ruleId:"ai-deadweight",severity:"warn",message:`Dead weight: ${I(s,"reason")}`,file:null,line:null,harnesses:[],hint:`Rule: "${I(s,"rule")}" \u2014 a capable agent would follow it unprompted.`}));if(e.checkId==="AI5-vague-rules")return t.map(s=>({ruleId:"ai-vague-rule",severity:"warn",message:`Vague rule: ${I(s,"reason")}`,file:null,line:null,harnesses:[],hint:`Rule: "${I(s,"rule")}" \u2014 give it a testable decision boundary.`}));if(e.checkId==="AI3-security-review")return t.map(s=>({ruleId:"ai-security-review",severity:"info",message:`Possible security risk (${I(s,"risk")}): ${I(s,"explanation")}`,file:null,line:null,harnesses:[],hint:`LLM-judged at ${I(s,"location")} \u2014 verify manually before acting.`}));let n=Zr(e.taskId);return t.map(s=>({ruleId:"ai-adapter-fidelity",severity:"warn",message:`Adapter drift: ${I(s,"explanation")}`,file:n,line:null,harnesses:[],hint:`Adapter claim: "${I(s,"claim")}"`}))}function It(e){return e.map(t=>{let n=new Map;for(let s of At(t)){let r=Rt(s);n.has(r)||n.set(r,s)}return n})}function Et(e,t,n,s){let r=0,o;for(let i of e){let a=i.get(t);a!==void 0&&(r+=1,o??=a)}if(o!==void 0)return r>=n?o:{...o,severity:"info",message:`${o.message} [low-confidence: LLM judge variance, agreed in ${String(r)}/${String(s)} runs]`}}function vt(e){let t=new Map;for(let s of e){let r=t.get(s.taskId)??[];r.push(s),t.set(s.taskId,r)}let n=[];for(let s of t.values()){let r=It(s),o=Math.ceil(s.length/2),i=new Set;for(let a of r)for(let c of a.keys())i.add(c);for(let a of i){let c=Et(r,a,o,s.length);c!==void 0&&n.push(c)}}return n}function Tt(e,t){let n={"AI1-contradiction":"ai-contradiction","AI2-adapter-fidelity":"ai-adapter-fidelity","AI3-security-review":"ai-security-review","AI4-deadweight":"ai-deadweight","AI5-vague-rules":"ai-vague-rule"},s=new Set,r=[];for(let o of e){if(s.has(o.checkId))continue;s.add(o.checkId);let i=n[o.checkId],a=t.filter(c=>c.ruleId===i).length;r.push({checkId:o.checkId,title:w[o.checkId].title,findingsCount:a,passed:a===0})}return r}var sa=12;function qe(e){let t=vt(e),n=t.filter(r=>r.severity!=="info"),s=Math.max(0,100-sa*n.length);return{status:"run",score:s,grade:we(s),checks:Tt(e,t),findings:t}}function Lt(e,t,n){let s=w[t];if(!y(n))throw new TypeError(`AI review result "${e}" data must be an object.`);let r=n[s.schemaKey];if(!Array.isArray(r))throw new TypeError(`AI review result "${e}" must have an array "${s.schemaKey}".`);for(let[o,i]of r.entries()){if(!y(i))throw new TypeError(`AI review result "${e}" ${s.schemaKey}[${String(o)}] must be an object.`);for(let a of s.entryFields){let c=i[a];if(typeof c!="string"||c.trim().length===0)throw new TypeError(`AI review result "${e}" ${s.schemaKey}[${String(o)}] is missing "${a}".`)}}}function Ft(e,t){if(!y(e))throw new TypeError(`AI review result #${String(t)} must be an object.`);let{taskId:n,checkId:s,data:r}=e;if(typeof n!="string"||n.length===0)throw new TypeError(`AI review result #${String(t)} is missing a "taskId".`);if(!to(s))throw new TypeError(`AI review result "${n}" has an unknown checkId: ${String(s)}.`);return Lt(n,s,r),{taskId:n,checkId:s,data:r}}function Ke(e){if(!y(e))throw new TypeError("AI review results must be a JSON object.");if(e.version!==1)throw new TypeError('AI review results must have "version": 1.');let{results:t}=e;if(!Array.isArray(t))throw new TypeError('AI review results must include a "results" array.');return{version:1,results:t.map((n,s)=>Ft(n,s))}}async function _t(e){let t=await ra(e,"utf8"),n=JSON.parse(t);return Ke(n).results}import ia from"node:path";function no(e){return e==="error"||e==="warn"||e==="info"?e:(process.stderr.write(`error: invalid --fail-on value: ${e}
3
- `),process.exit(2),"error")}function so(e){return e==="terminal"||e==="json"?e:(process.stderr.write(`error: invalid --format value: ${e}
4
- `),process.exit(2),"terminal")}function Nt(e){let t=e.split(",").map(r=>r.trim()).filter(r=>r.length>0);if(t.length===0)return null;let n=[],s=[];for(let r of t)r==="copilot"||r==="cursor"||r==="codex"||r==="antigravity"||r==="claude"||r==="gemini"?n.push(r):s.push(r);return s.length>0?(process.stderr.write(`error: unknown harness(es): ${s.join(", ")}
5
- `),process.exit(2),[]):n}var ro=[/\balways\b/i,/\bnever\b/i,/\bdont\b/i,/\bdon't\b/i,/\bmake sure\b/i,/\bremember to\b/i],oo=[/\bno\b/i,/\bwrong\b/i,/\bnot that\b/i,/\bi said\b/i,/\bstop\b/i,/\bthat's not right\b/i,/\bthats not right\b/i,/\bnot correct\b/i,/\btry again\b/i,/\bnot right\b/i],io=/\b(run|npm|pnpm|yarn|node|python|python3|pytest|make|docker|git|curl|bash|sh|cat|ls|find|grep|sed|awk|rm|cp|mv|touch|tee|mkdir|rmdir)\b/i,ao=[/^<[a-z-]+>/i,/^<\/[a-z-]+>/i,/^─{4,}/,/^={4,}/,/^-{4,}/,/^\*{4,}/,/^#{4,}\s*$/,/^UserPromptSubmit/,/^SessionStart/,/^OK$/,/^Tool loaded/],L={SS1:"Repeated instructions",SS2:"Ignored rules",SS3:"Friction hotspots",SS4:"Missing rule suggestions"};function Pt(e){let t=process.cwd(),n=null,s="terminal",r="error",o=!1,i=!1,a=null,c=!1,l=null,p=30,f=!1;for(let m=0;m<e.length;m+=1){let d=e[m];if(d!==void 0){if(d==="-h"||d==="--help"){o=!0;continue}if(d==="--emit-ai-tasks"){i=!0;continue}if(d==="--session-analysis"){c=!0;continue}if(d==="--include-raw-snippets"){f=!0;continue}if(d==="--session-root"){let g=e[m+1];g===void 0&&(process.stderr.write(`error: --session-root requires a path
6
- `),process.exit(2)),l=g,m+=1;continue}if(d==="--max-sessions"){let g=e[m+1];g===void 0&&(process.stderr.write(`error: --max-sessions requires a value
7
- `),process.exit(2));let S=Number.parseInt(g,10);(!Number.isFinite(S)||S<=0)&&(process.stderr.write(`error: --max-sessions must be a positive integer
8
- `),process.exit(2)),p=S,m+=1;continue}if(d==="--ingest-ai-results"){let g=e[m+1];g===void 0&&(process.stderr.write(`error: --ingest-ai-results requires a file path
9
- `),process.exit(2)),a=g,m+=1;continue}if(d==="--harness"){let g=e[m+1];g===void 0&&(process.stderr.write(`error: --harness requires a value
10
- `),process.exit(2)),n=Nt(g),m+=1;continue}if(d==="--format"){let g=e[m+1];g===void 0&&(process.stderr.write(`error: --format requires a value
11
- `),process.exit(2)),s=so(g),m+=1;continue}if(d==="--fail-on"){let g=e[m+1];g===void 0&&(process.stderr.write(`error: --fail-on requires a value
12
- `),process.exit(2)),r=no(g),m+=1;continue}d.startsWith("-")&&(process.stderr.write(`error: unknown option: ${d}
13
- `),process.exit(2)),t=ia.resolve(d)}}return{repoRoot:t,harnessFilter:n,format:s,failOn:r,help:o,emitAiTasks:i,ingestResultsPath:a,sessionAnalysis:c,sessionRoot:l,maxSessions:p,includeRawSnippets:f}}function Ht(){process.stdout.write(`paniolo-scan \u2014 AI harness diagnostic (read-only)
2
+ import{readFile as fa}from"node:fs/promises";var vt={status:"not-run",score:null,grade:"not-run",checks:[],findings:[]};var ua=[{min:85,grade:"excellent"},{min:70,grade:"good"},{min:50,grade:"fair"},{min:0,grade:"poor"}];function be(e){for(let{min:t,grade:n}of ua)if(e>=t)return n;return"poor"}function Tt(e){let t=(e.hint??"").toLowerCase().match(/[a-z0-9]+/g),n=t===null?"":[...new Set(t)].toSorted().join(" ");return`${e.ruleId}::${e.file??""}::${n}`}function ro(e){let t=e.indexOf(":");return t===-1?null:e.slice(t+1)}function v(e,t){let n=e[t];return typeof n=="string"?n:""}import{access as da}from"node:fs/promises";import pa from"node:path";var W=75,Lt=300,Ke=["CLAUDE.md","GEMINI.md",".github/copilot-instructions.md"];function S(e,t){return e.files.some(n=>n.path===t)}function h(e,t){return e.fileContents.get(t)??null}function U(e,t){return e.files.find(r=>r.path===t)?.lines??null}function so(e){return e.includes("AGENTS.md")||e.includes("docs/ai/rules.md")}function Ye(e){return e.match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1]??null}function me(e,t){return new RegExp(`^${t}:`,"m").test(e)}async function fe(e,t){try{return await da(pa.join(e,t)),!0}catch{return!1}}function ge(e,t){return e.files.filter(n=>n.path.startsWith(t)).map(n=>n.path)}function I(e){return e.files.some(t=>t.path.startsWith("skills/")&&t.path.endsWith("/SKILL.md"))}function Je(e){return e.includes("available-skills.md")||e.includes("skills/*/SKILL.md")||e.includes("npm run qmd")||e.includes("skills/")&&e.includes("available-skills")}function Xe(e){return/agent routing/i.test(e)&&e.includes("|")&&/agents\/.*\.agent\.md/.test(e)}function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var C={"AI1-contradiction":{checkId:"AI1-contradiction",title:"Cross-guidance contradictions",schemaKey:"contradictions",entryFields:["ruleA","ruleB","explanation"]},"AI2-adapter-fidelity":{checkId:"AI2-adapter-fidelity",title:"Adapter fidelity to shared layer",schemaKey:"drifts",entryFields:["claim","explanation"]},"AI3-security-review":{checkId:"AI3-security-review",title:"Semantic security review (advisory)",schemaKey:"risks",entryFields:["location","risk","explanation"]},"AI4-deadweight":{checkId:"AI4-deadweight",title:"Dead-weight instructions (deletion test)",schemaKey:"deadweight",entryFields:["rule","reason"]},"AI5-vague-rules":{checkId:"AI5-vague-rules",title:"Vague rules lacking a decision boundary",schemaKey:"vague",entryFields:["rule","reason"]}};function oo(e){return typeof e=="string"&&e in C}function _t(e){if(!x(e.data))return[];let t=e.data[C[e.checkId].schemaKey];return Array.isArray(t)?t.filter(n=>x(n)):[]}function Ft(e){let t=_t(e);if(e.checkId==="AI1-contradiction")return t.map(r=>({ruleId:"ai-contradiction",severity:"warn",message:`Contradiction: ${v(r,"explanation")}`,file:null,line:null,harnesses:[],hint:`"${v(r,"ruleA")}" conflicts with "${v(r,"ruleB")}"`}));if(e.checkId==="AI4-deadweight")return t.map(r=>({ruleId:"ai-deadweight",severity:"warn",message:`Dead weight: ${v(r,"reason")}`,file:null,line:null,harnesses:[],hint:`Rule: "${v(r,"rule")}" \u2014 a capable agent would follow it unprompted.`}));if(e.checkId==="AI5-vague-rules")return t.map(r=>({ruleId:"ai-vague-rule",severity:"warn",message:`Vague rule: ${v(r,"reason")}`,file:null,line:null,harnesses:[],hint:`Rule: "${v(r,"rule")}" \u2014 give it a testable decision boundary.`}));if(e.checkId==="AI3-security-review")return t.map(r=>({ruleId:"ai-security-review",severity:"info",message:`Possible security risk (${v(r,"risk")}): ${v(r,"explanation")}`,file:null,line:null,harnesses:[],hint:`LLM-judged at ${v(r,"location")} \u2014 verify manually before acting.`}));let n=ro(e.taskId);return t.map(r=>({ruleId:"ai-adapter-fidelity",severity:"warn",message:`Adapter drift: ${v(r,"explanation")}`,file:n,line:null,harnesses:[],hint:`Adapter claim: "${v(r,"claim")}"`}))}function Nt(e){return e.map(t=>{let n=new Map;for(let r of Ft(t)){let s=Tt(r);n.has(s)||n.set(s,r)}return n})}function Pt(e,t,n,r){let s=0,o;for(let i of e){let a=i.get(t);a!==void 0&&(s+=1,o??=a)}if(o!==void 0)return s>=n?o:{...o,severity:"info",message:`${o.message} [low-confidence: LLM judge variance, agreed in ${String(s)}/${String(r)} runs]`}}function Ht(e){let t=new Map;for(let r of e){let s=t.get(r.taskId)??[];s.push(r),t.set(r.taskId,s)}let n=[];for(let r of t.values()){let s=Nt(r),o=Math.ceil(r.length/2),i=new Set;for(let a of s)for(let c of a.keys())i.add(c);for(let a of i){let c=Pt(s,a,o,r.length);c!==void 0&&n.push(c)}}return n}function Mt(e,t){let n={"AI1-contradiction":"ai-contradiction","AI2-adapter-fidelity":"ai-adapter-fidelity","AI3-security-review":"ai-security-review","AI4-deadweight":"ai-deadweight","AI5-vague-rules":"ai-vague-rule"},r=new Set,s=[];for(let o of e){if(r.has(o.checkId))continue;r.add(o.checkId);let i=n[o.checkId],a=t.filter(c=>c.ruleId===i).length;s.push({checkId:o.checkId,title:C[o.checkId].title,findingsCount:a,passed:a===0})}return s}var ma=12;function Qe(e){let t=Ht(e),n=t.filter(s=>s.severity!=="info"),r=Math.max(0,100-ma*n.length);return{status:"run",score:r,grade:be(r),checks:Mt(e,t),findings:t}}function Dt(e,t,n){let r=C[t];if(!x(n))throw new TypeError(`AI review result "${e}" data must be an object.`);let s=n[r.schemaKey];if(!Array.isArray(s))throw new TypeError(`AI review result "${e}" must have an array "${r.schemaKey}".`);for(let[o,i]of s.entries()){if(!x(i))throw new TypeError(`AI review result "${e}" ${r.schemaKey}[${String(o)}] must be an object.`);for(let a of r.entryFields){let c=i[a];if(typeof c!="string"||c.trim().length===0)throw new TypeError(`AI review result "${e}" ${r.schemaKey}[${String(o)}] is missing "${a}".`)}}}function Ot(e,t){if(!x(e))throw new TypeError(`AI review result #${String(t)} must be an object.`);let{taskId:n,checkId:r,data:s}=e;if(typeof n!="string"||n.length===0)throw new TypeError(`AI review result #${String(t)} is missing a "taskId".`);if(!oo(r))throw new TypeError(`AI review result "${n}" has an unknown checkId: ${String(r)}.`);return Dt(n,r,s),{taskId:n,checkId:r,data:s}}function Ze(e){if(!x(e))throw new TypeError("AI review results must be a JSON object.");if(e.version!==1)throw new TypeError('AI review results must have "version": 1.');let{results:t}=e;if(!Array.isArray(t))throw new TypeError('AI review results must include a "results" array.');return{version:1,results:t.map((n,r)=>Ot(n,r))}}async function $t(e){let t=await fa(e,"utf8"),n=JSON.parse(t);return Ze(n).results}import ha from"node:path";function io(e){return e==="error"||e==="warn"||e==="info"?e:(process.stderr.write(`error: invalid --fail-on value: ${e}
3
+ `),process.exit(2),"error")}function ao(e){return e==="terminal"||e==="json"?e:(process.stderr.write(`error: invalid --format value: ${e}
4
+ `),process.exit(2),"terminal")}function Gt(e){let t=e.split(",").map(s=>s.trim()).filter(s=>s.length>0);if(t.length===0)return null;let n=[],r=[];for(let s of t)s==="copilot"||s==="cursor"||s==="codex"||s==="antigravity"||s==="claude"||s==="gemini"?n.push(s):r.push(s);return r.length>0?(process.stderr.write(`error: unknown harness(es): ${r.join(", ")}
5
+ `),process.exit(2),[]):n}var co=[/\balways\b/i,/\bnever\b/i,/\bdont\b/i,/\bdon't\b/i,/\bmake sure\b/i,/\bremember to\b/i],lo=[/\bno\b/i,/\bwrong\b/i,/\bnot that\b/i,/\bi said\b/i,/\bstop\b/i,/\bthat's not right\b/i,/\bthats not right\b/i,/\bnot correct\b/i,/\btry again\b/i,/\bnot right\b/i],uo=/\b(run|npm|pnpm|yarn|node|python|python3|pytest|make|docker|git|curl|bash|sh|cat|ls|find|grep|sed|awk|rm|cp|mv|touch|tee|mkdir|rmdir)\b/i,_={SS1:"Repeated instructions",SS2:"Ignored rules",SS3:"Friction hotspots",SS4:"Missing rule suggestions"};function jt(e){let t=process.cwd(),n=null,r="terminal",s="error",o=!1,i=!1,a=null,c=!1,l=null,m=30,u=!1;for(let f=0;f<e.length;f+=1){let d=e[f];if(d!==void 0){if(d==="-h"||d==="--help"){o=!0;continue}if(d==="--emit-ai-tasks"){i=!0;continue}if(d==="--session-analysis"){c=!0;continue}if(d==="--include-raw-snippets"){u=!0;continue}if(d==="--session-root"){let g=e[f+1];g===void 0&&(process.stderr.write(`error: --session-root requires a path
6
+ `),process.exit(2)),l=g,f+=1;continue}if(d==="--max-sessions"){let g=e[f+1];g===void 0&&(process.stderr.write(`error: --max-sessions requires a value
7
+ `),process.exit(2));let y=Number.parseInt(g,10);(!Number.isFinite(y)||y<=0)&&(process.stderr.write(`error: --max-sessions must be a positive integer
8
+ `),process.exit(2)),m=y,f+=1;continue}if(d==="--ingest-ai-results"){let g=e[f+1];g===void 0&&(process.stderr.write(`error: --ingest-ai-results requires a file path
9
+ `),process.exit(2)),a=g,f+=1;continue}if(d==="--harness"){let g=e[f+1];g===void 0&&(process.stderr.write(`error: --harness requires a value
10
+ `),process.exit(2)),n=Gt(g),f+=1;continue}if(d==="--format"){let g=e[f+1];g===void 0&&(process.stderr.write(`error: --format requires a value
11
+ `),process.exit(2)),r=ao(g),f+=1;continue}if(d==="--fail-on"){let g=e[f+1];g===void 0&&(process.stderr.write(`error: --fail-on requires a value
12
+ `),process.exit(2)),s=io(g),f+=1;continue}d.startsWith("-")&&(process.stderr.write(`error: unknown option: ${d}
13
+ `),process.exit(2)),t=ha.resolve(d)}}return{repoRoot:t,harnessFilter:n,format:r,failOn:s,help:o,emitAiTasks:i,ingestResultsPath:a,sessionAnalysis:c,sessionRoot:l,maxSessions:m,includeRawSnippets:u}}function Wt(){process.stdout.write(`paniolo-scan \u2014 AI harness diagnostic (read-only)
14
14
 
15
15
  Usage:
16
16
  paniolo-scan [options] [path]
@@ -36,26 +36,26 @@ Examples:
36
36
  npx @paniolo/scan --ingest-ai-results paniolo-ai-results.json --format json
37
37
  npx @paniolo/scan --session-analysis
38
38
  npx @paniolo/scan --session-analysis --format json --include-raw-snippets
39
- `)}function Mt(e){process.stdout.write(`${JSON.stringify(e,null,2)}
40
- `)}var aa=["SS4","SS2","SS3","SS1"];function Dt(e){if(process.stdout.write(`# paniolo-scan \u2014 Session Analysis (extended)
39
+ `)}function Ut(e){process.stdout.write(`${JSON.stringify(e,null,2)}
40
+ `)}var ya=["SS4","SS2","SS3","SS1"];function Bt(e){if(process.stdout.write(`# paniolo-scan \u2014 Session Analysis (extended)
41
41
 
42
42
  `),e.status==="no-sessions"){process.stdout.write(`No ${e.harness} session logs found for this repo. Nothing to analyze.
43
- `);return}let t=e.findings.filter(s=>s.checkId==="SS4").length,n=e.findings.filter(s=>s.checkId==="SS3"&&s.snippet!==null).length;if(process.stdout.write(`Analyzed ${String(e.sessionsAnalyzed)} session(s): ${String(t)} candidate missing rule(s), ${String(n)} recurring friction theme(s).
43
+ `);return}let t=e.findings.filter(r=>r.checkId==="SS4").length,n=e.findings.filter(r=>r.checkId==="SS3"&&r.snippet!==null).length;if(process.stdout.write(`Analyzed ${String(e.sessionsAnalyzed)} session(s): ${String(t)} candidate missing rule(s), ${String(n)} recurring friction theme(s).
44
44
  `),process.stdout.write(e.redacted?`Snippets are redacted; re-run with --include-raw-snippets to reveal them.
45
45
 
46
46
  `:`Snippets shown verbatim (--include-raw-snippets).
47
47
 
48
48
  `),e.findings.length===0){process.stdout.write(`No recurring instructions, ignored rules, or friction detected.
49
- `);return}for(let s of aa){let r=e.findings.filter(o=>o.checkId===s);if(r.length!==0){process.stdout.write(`## ${s} \u2014 ${L[s]}
49
+ `);return}for(let r of ya){let s=e.findings.filter(o=>o.checkId===r);if(s.length!==0){process.stdout.write(`## ${r} \u2014 ${_[r]}
50
50
 
51
- `);for(let o of r)process.stdout.write(`- ${o.detail}
51
+ `);for(let o of s)process.stdout.write(`- ${o.detail}
52
52
  `);process.stdout.write(`
53
- `)}}}var ca={"shared-agents-md":["Memory","Planning"],"shared-rules-doc":["Planning","Action"],"adapter-thin-claude":["Memory"],"adapter-thin-gemini":["Memory"],"adapter-thin-copilot":["Memory"],"adapter-points-to-shared":["Memory"],"skills-index":["Action"],"claude-agent-routing":["Planning"],"agents-md-mentions-skills":["Action"],"skill-doc-deep-links":["Memory"],"qmd-script-present":["Memory"],"memory-docs-indexed":["Memory"],"focused-test-commands-present":["Reflection"],"skill-frontmatter":["Action"],"skill-line-count":["Memory"],"agent-frontmatter":["Action"],"no-duplicate-skill-trees":["Memory"],"no-duplicate-agent-trees":["Memory"],"guidance-links-resolve":["Memory"],"forbidden-legacy-paths":["Memory"],"local-context-patterns":["Memory"],"correction-loop-documented":["Reflection"],"guidance-maintenance-script":["Reflection"],"pr-template-ai-harness-check":["Reflection"],"emphasis-keyword-density":["Memory"],"identity-language-absent":["Memory"],"adapter-content-duplication":["Memory"],"adapter-context-budget":["Memory"],"always-loaded-budget":["Memory"],"strict-typecheck-present":["Reflection","System Operation"],"lint-gate-present":["Reflection","System Operation"],"jsdoc-enforcement-present":["Reflection"],"test-gates-present":["Reflection"],"ci-enforcement-gates":["Reflection","System Operation"],"ci-validation-gates":["Reflection","System Operation"],"ci-guidance-lint":["Reflection"],"vscode-skills-location":["Action"],"vscode-agents-location":["Action"],"vscode-custom-hooks":["Reflection","System Operation"],"no-dangerous-auto-approve":["Action"],"hook-no-network-exfil":["Action","System Operation"],"hook-stop-circuit-breaker":["Reflection","System Operation"],"env-files-gitignored":["Action"],"secret-scanning-configured":["System Operation"],"no-pull-request-target":["System Operation"],"actions-sha-pinned":["System Operation"],"claude-hooks-valid":["System Operation"],"codex-hooks-valid":["System Operation"],"model-interface-pinned":["System Operation","Action"],"llm-output-schema-validated":["Action"],"tool-contract-tests-present":["Action","System Operation"],"escalation-protocol-discoverability":["Planning","Reflection"],"agent-resource-budget-caps":["System Operation"],"tool-allowlist-inventory":["Action"],"untrusted-input-action-boundary":["Action","Memory"],"memory-write-provenance":["Memory"],"high-impact-action-confirmation":["Action"]};function Ye(e){return ca[e]??[]}var Ot=["error","warn","info"],co={error:"ERROR",warn:"WARN",info:"INFO"},lo={layering:"Layering",sharing:"Sharing",discoverability:"Discoverability",harnessWiring:"Harness wiring",maintainability:"Maintainability",guardrails:"Guardrails"},uo=["layering","sharing","discoverability","harnessWiring","maintainability","guardrails"],po=["copilot","cursor","codex","antigravity","claude","gemini"];function $t(e){let t=co[e.severity],n=e.file===null?"":` ${e.file}${e.line===null?"":`:${String(e.line)}`}`,s=e.harnesses.length===0?"":`
54
- Harnesses: ${e.harnesses.join(", ")}`,r=e.hint===void 0?"":`
55
- Hint: ${e.hint}`,o=Ye(e.ruleId),i=o.length===0?"":`
53
+ `)}}}var Sa={"shared-agents-md":["Memory","Planning"],"shared-rules-doc":["Planning","Action"],"adapter-thin-claude":["Memory"],"adapter-thin-gemini":["Memory"],"adapter-thin-copilot":["Memory"],"adapter-points-to-shared":["Memory"],"skills-index":["Action"],"claude-agent-routing":["Planning"],"agents-md-mentions-skills":["Action"],"skill-doc-deep-links":["Memory"],"qmd-script-present":["Memory"],"memory-docs-indexed":["Memory"],"focused-test-commands-present":["Reflection"],"skill-frontmatter":["Action"],"skill-line-count":["Memory"],"agent-frontmatter":["Action"],"no-duplicate-skill-trees":["Memory"],"no-duplicate-agent-trees":["Memory"],"guidance-links-resolve":["Memory"],"forbidden-legacy-paths":["Memory"],"local-context-patterns":["Memory"],"correction-loop-documented":["Reflection"],"guidance-maintenance-script":["Reflection"],"pr-template-ai-harness-check":["Reflection"],"emphasis-keyword-density":["Memory"],"identity-language-absent":["Memory"],"adapter-content-duplication":["Memory"],"adapter-context-budget":["Memory"],"always-loaded-budget":["Memory"],"strict-typecheck-present":["Reflection","System Operation"],"lint-gate-present":["Reflection","System Operation"],"jsdoc-enforcement-present":["Reflection"],"test-gates-present":["Reflection"],"ci-enforcement-gates":["Reflection","System Operation"],"ci-validation-gates":["Reflection","System Operation"],"ci-guidance-lint":["Reflection"],"vscode-skills-location":["Action"],"vscode-agents-location":["Action"],"vscode-custom-hooks":["Reflection","System Operation"],"no-dangerous-auto-approve":["Action"],"hook-no-network-exfil":["Action","System Operation"],"hook-stop-circuit-breaker":["Reflection","System Operation"],"env-files-gitignored":["Action"],"secret-scanning-configured":["System Operation"],"no-pull-request-target":["System Operation"],"actions-sha-pinned":["System Operation"],"claude-hooks-valid":["System Operation"],"codex-hooks-valid":["System Operation"],"model-interface-pinned":["System Operation","Action"],"llm-output-schema-validated":["Action"],"tool-contract-tests-present":["Action","System Operation"],"escalation-protocol-discoverability":["Planning","Reflection"],"agent-resource-budget-caps":["System Operation"],"tool-allowlist-inventory":["Action"],"untrusted-input-action-boundary":["Action","Memory"],"memory-write-provenance":["Memory"],"high-impact-action-confirmation":["Action"]};function et(e){return Sa[e]??[]}var Vt=["error","warn","info"],po={error:"ERROR",warn:"WARN",info:"INFO"},mo={layering:"Layering",sharing:"Sharing",discoverability:"Discoverability",harnessWiring:"Harness wiring",maintainability:"Maintainability",guardrails:"Guardrails"},fo=["layering","sharing","discoverability","harnessWiring","maintainability","guardrails"],go=["copilot","cursor","codex","antigravity","claude","gemini"];function zt(e){let t=po[e.severity],n=e.file===null?"":` ${e.file}${e.line===null?"":`:${String(e.line)}`}`,r=e.harnesses.length===0?"":`
54
+ Harnesses: ${e.harnesses.join(", ")}`,s=e.hint===void 0?"":`
55
+ Hint: ${e.hint}`,o=et(e.ruleId),i=o.length===0?"":`
56
56
  Prevents: ${o.join(", ")}-class agent failures`;return`[${t}] ${e.ruleId}
57
57
  ${e.message}${n?`
58
- ${n}`:""}${s}${i}${r}`}var fo=`---
58
+ ${n}`:""}${r}${i}${s}`}var ho=`---
59
59
 
60
60
  \u2139\uFE0F Need professional-grade agent infrastructure?
61
61
 
@@ -68,38 +68,38 @@ For professional or production-grade work, we strongly recommend
68
68
  engaging Paniolo's professional services to design, tune, and evolve
69
69
  your infrastructure. Learn more at https://paniolo.ai or contact us
70
70
  directly at https://paniolo.ai/#contact.
71
- `;function Gt(e){if(process.stdout.write(`## AI review (optional)
71
+ `;function qt(e){if(process.stdout.write(`## AI review (optional)
72
72
 
73
73
  `),e.status==="not-run"){process.stdout.write(`Not run \u2014 pass --ingest-ai-results to score this dimension.
74
74
 
75
75
  `);return}let t=e.score===null?"n/a":`${String(e.score)}/100`;process.stdout.write(`AI review: ${t} (${e.grade})
76
- `);for(let n of e.checks){let s=n.passed?"\u2713":`\u2717 ${String(n.findingsCount)} finding(s)`;process.stdout.write(` ${s} ${n.title}
77
- `)}for(let n of e.findings){let s=n.file===null?"":` (${n.file})`;process.stdout.write(` - ${n.message}${s}
76
+ `);for(let n of e.checks){let r=n.passed?"\u2713":`\u2717 ${String(n.findingsCount)} finding(s)`;process.stdout.write(` ${r} ${n.title}
77
+ `)}for(let n of e.findings){let r=n.file===null?"":` (${n.file})`;process.stdout.write(` - ${n.message}${r}
78
78
  `)}process.stdout.write(`
79
- `)}function jt(e){if(e===void 0)return;let t=e.harnesses.filter(n=>n.detected);if(t.length!==0){process.stdout.write(`## Context budget
79
+ `)}function Kt(e){if(e===void 0)return;let t=e.harnesses.filter(n=>n.detected);if(t.length!==0){process.stdout.write(`## Context budget
80
80
 
81
81
  `);for(let n of t){process.stdout.write(`${n.harness}: ${String(n.totalLines)} always-loaded lines, ~${String(n.estimatedTokens)} tokens (${n.status})
82
- `);for(let s of n.files.slice(0,3))process.stdout.write(` ${s.path}: ${String(s.lines)} lines
82
+ `);for(let r of n.files.slice(0,3))process.stdout.write(` ${r.path}: ${String(r.lines)} lines
83
83
  `)}process.stdout.write(`
84
- `)}}function Wt(e){if(process.stdout.write(`## Predicted runtime failure exposure
84
+ `)}}function Yt(e){if(process.stdout.write(`## Predicted runtime failure exposure
85
85
 
86
86
  `),e.byDimension.length===0){process.stdout.write(`No findings map to a runtime failure class.
87
87
 
88
- `);return}let t=[...e.byDimension].sort((n,s)=>s.findingCount-n.findingCount);for(let n of t){let s=`${String(n.error)} error / ${String(n.warn)} warn / ${String(n.info)} info`;process.stdout.write(`${n.dimension}: ${String(n.findingCount)} finding(s) \u2014 ${s}
88
+ `);return}let t=[...e.byDimension].sort((n,r)=>r.findingCount-n.findingCount);for(let n of t){let r=`${String(n.error)} error / ${String(n.warn)} warn / ${String(n.info)} info`;process.stdout.write(`${n.dimension}: ${String(n.findingCount)} finding(s) \u2014 ${r}
89
89
  `),process.stdout.write(` Rules: ${n.ruleIds.join(", ")}
90
90
  `)}e.untaggedFindings>0&&process.stdout.write(`
91
91
  ${String(e.untaggedFindings)} finding(s) not yet mapped to a failure class.
92
92
  `),process.stdout.write(`
93
- `)}var Ut=new Set(["shared","skills","agents"]),K=["copilot","cursor","codex","antigravity","claude","gemini"];function mo(e,t){return t.length>=2?!0:Ut.has(e.layer)||e.path==="AGENTS.md"}function Je(e){switch(e){case"yes":return"\u2713";case"partial":return"~";case"no":return"\u2717";case"na":return"\u2014"}}import{readFile as la}from"node:fs/promises";import ua from"node:path";async function Bt(e){try{return await la(ua.join(e,".codex/hooks.json"),"utf8"),!0}catch{return!1}}function u(e,t){return{status:e,detail:t}}function Vt(){let e={copilot:u("na",""),cursor:u("na",""),codex:u("na",""),antigravity:u("na",""),claude:u("na",""),gemini:u("na","")};return{sharedSkillsDiscoverable:{...e},customAgents:{...e},lifecycleHooks:{...e},thinAdapter:{...e},workflows:{...e}}}var da={copilot:".github/copilot-instructions.md",claude:"CLAUDE.md",gemini:"GEMINI.md"};function P(e){return da[e]??null}function Re(e,t){if(!N(e))return!1;if(E(e,"docs/ai/available-skills.md"))return!0;let n=h(e,"AGENTS.md");if(n!==null&&Ve(n))return!0;let s=P(t);if(s===null)return!1;let r=h(e,s);return r!==null&&r.includes("skills/")}function v(e,t,n){let s=e.settings?.[t];if(y(s)&&Object.keys(s).some(a=>a.startsWith(n)))return!0;if(e.settingsRaw===null)return!1;let r=t.replaceAll(".",String.raw`\.`);return new RegExp(`"${r}"\\s*:\\s*\\{[^}]*"${n}[^"]*"`).test(e.settingsRaw)}var pa=50;function go(e){return e.files.some(t=>t.path.startsWith("agents/")&&t.path.endsWith(".agent.md"))}function Xe(e,t){let n=U(e,t);return n===null?!1:n<=pa}function ho(e,t){let n=h(e,t);return n===null?!1:n.includes("AGENTS.md")||n.includes("docs/ai/rules.md")}function Qe(e){return e.files.some(t=>t.path.startsWith(".agent/workflows/"))}function yo(e){let t=h(e,"CLAUDE.md");return t!==null&&ze(t)}function zt(e,t){let n=go(t.context);switch(e){case"copilot":case"cursor":return v(t.vscode,"chat.agentFilesLocations","agents")&&n?u("yes","agents/ wired in chat.agentFilesLocations"):n?u("partial","agents/ present but not wired in VS Code settings"):u("no","No agents/ tree or VS Code agent locations");case"codex":return t.context.files.some(r=>r.path.startsWith(".codex/agents/"))&&n?u("yes",".codex/agents wrappers with shared agents/"):n?u("partial","agents/ present without .codex/agents wrappers"):u("no","No custom agents configured");case"claude":return yo(t.context)?u("yes","Agent routing table in CLAUDE.md"):n?u("partial","agents/ present without routing table in CLAUDE.md"):u("no","No agent routing or agents/ tree");case"gemini":{if(!n)return u("no","No agents/ tree");let s=P("gemini"),r=s===null?null:t.context.fileContents.get(s)??null;return r!==null&&r.includes("agents/")?u("partial","agents/ referenced from GEMINI.md"):u("partial","agents/ present; document routing in GEMINI.md")}case"antigravity":return u("na","Uses workflow playbooks instead of custom agents");default:return u("no","Unknown harness")}}function qt(e,t){let n=t.vscode.hooksDirExists,s=t.vscode.settings?.["chat.useCustomAgentHooks"]===!0;switch(e){case"copilot":case"cursor":return n&&s?u("yes",".github/hooks/ with chat.useCustomAgentHooks"):n||s?u("partial","Hooks partially configured in VS Code workspace"):u("no","No lifecycle hooks configured");case"codex":return t.codexHooksExists?u("yes",".codex/hooks.json present"):n?u("partial","Shared .github/hooks/ only; no .codex/hooks.json"):u("no","No Codex hooks configured");case"claude":return t.claudeSettingsRaw!==null&&/"hooks"\s*:/.test(t.claudeSettingsRaw)?u("yes","Hooks in .claude/settings.json"):n?u("partial","Shared .github/hooks/ only; no .claude hooks"):u("no","No Claude hooks configured");case"gemini":return n&&s?u("partial","Shared VS Code hooks only; no Gemini-native hooks"):u("no","No lifecycle hooks for Gemini");case"antigravity":return u("na","No hook surface for Antigravity workflows");default:return u("no","Unknown harness")}}function Kt(e,t){if(!N(t.context))return u("no","No skills/ tree");switch(e){case"copilot":case"cursor":return v(t.vscode,"chat.agentSkillsLocations","skills")?u("yes","skills/ wired in chat.agentSkillsLocations"):u("partial","skills/ present but not wired in VS Code settings");case"codex":return Re(t.context,"codex")?u("partial","skills/ with prose discovery via AGENTS.md or skill index"):u("partial","skills/ present; no documented discovery workflow");case"claude":case"gemini":return Re(t.context,e)?u("partial","Prose discovery via skill index or adapter pointers"):u("no","skills/ without index or adapter pointers");case"antigravity":return Qe(t.context)?u("yes","skills/ with workflow playbooks"):u("partial","skills/ present without workflow playbooks");default:return u("no","Unknown harness")}}function Yt(e,t){switch(e){case"copilot":{let n=P("copilot");return n===null||!t.context.files.some(s=>s.path===n)?u("no","Missing .github/copilot-instructions.md"):Xe(t.context,n)?u("yes","Copilot instructions within line budget"):u("partial","Copilot instructions exceed thin adapter budget")}case"cursor":{let n=t.context.files.some(r=>r.path.startsWith(".cursor/rules/")),s=v(t.vscode,"chat.agentSkillsLocations","skills")&&v(t.vscode,"chat.agentFilesLocations","agents");return n||s?u("yes","Cursor rules or VS Code agent settings configured"):u("partial","Cursor detected without rules or agent settings")}case"codex":return t.context.files.some(s=>s.path.startsWith(".codex/"))?t.context.files.some(s=>s.path==="AGENTS.md")?u("yes",".codex/ with shared AGENTS.md entry"):u("partial",".codex/ without root AGENTS.md"):u("no","No .codex/ config surface");case"claude":{let n=P("claude");if(n===null||!t.context.files.some(o=>o.path===n))return u("no","Missing CLAUDE.md");let s=Xe(t.context,n),r=ho(t.context,n);return s&&r?u("yes","Thin CLAUDE.md referencing shared layers"):s?u("partial","CLAUDE.md thin but missing shared layer pointers"):u("partial","CLAUDE.md exceeds thin adapter budget")}case"gemini":{let n=P("gemini");return n===null||!t.context.files.some(s=>s.path===n)?u("no","Missing GEMINI.md"):Xe(t.context,n)?u("yes","Thin GEMINI.md adapter"):u("partial","GEMINI.md exceeds thin adapter budget")}case"antigravity":return u("partial","Workflows only; no classic root adapter");default:return u("no","Unknown harness")}}function Jt(e,t){return e!=="antigravity"?u("na","Workflow playbooks are Antigravity-specific"):Qe(t.context)?u("yes",".agent/workflows/ playbooks present"):u("no","No .agent/workflows/ playbooks")}function Xt(e,t,n){switch(e){case"sharedSkillsDiscoverable":return Kt(t,n);case"customAgents":return zt(t,n);case"lifecycleHooks":return qt(t,n);case"thinAdapter":return Yt(t,n);case"workflows":return Jt(t,n);default:return u("no","Unknown capability")}}var Qt={sharedSkillsDiscoverable:"Shared skills discoverable",customAgents:"Custom agents",lifecycleHooks:"Lifecycle hooks",thinAdapter:"Thin adapter",workflows:"Workflows / playbooks"},be=["sharedSkillsDiscoverable","customAgents","lifecycleHooks","thinAdapter","workflows"],So="Harness not detected";import{readFile as fa}from"node:fs/promises";import ma from"node:path";async function Zt(e){try{return await fa(ma.join(e,".claude/settings.json"),"utf8")}catch{return null}}async function en(e,t){let n=K.filter(o=>e.harnesses.includes(o)),s={context:e,vscode:t,claudeSettingsRaw:await Zt(e.repoRoot),codexHooksExists:await Bt(e.repoRoot)},r=Vt();for(let o of be){let i=r[o];for(let a of K){if(!e.harnesses.includes(a)){i[a]=u("na",So);continue}i[a]=Xt(o,a,s)}}return{capabilities:be,harnesses:n,matrix:r}}function tn(e){if(process.stdout.write(`## Harness gap matrix
93
+ `)}var Jt=new Set(["shared","skills","agents"]),Q=["copilot","cursor","codex","antigravity","claude","gemini"];function yo(e,t){return t.length>=2?!0:Jt.has(e.layer)||e.path==="AGENTS.md"}function tt(e){switch(e){case"yes":return"\u2713";case"partial":return"~";case"no":return"\u2717";case"na":return"\u2014"}}import{readFile as ka}from"node:fs/promises";import xa from"node:path";async function Xt(e){try{return await ka(xa.join(e,".codex/hooks.json"),"utf8"),!0}catch{return!1}}function p(e,t){return{status:e,detail:t}}function Qt(){let e={copilot:p("na",""),cursor:p("na",""),codex:p("na",""),antigravity:p("na",""),claude:p("na",""),gemini:p("na","")};return{sharedSkillsDiscoverable:{...e},customAgents:{...e},lifecycleHooks:{...e},thinAdapter:{...e},workflows:{...e}}}var Ra={copilot:".github/copilot-instructions.md",claude:"CLAUDE.md",gemini:"GEMINI.md"};function P(e){return Ra[e]??null}function Ce(e,t){if(!I(e))return!1;if(S(e,"docs/ai/available-skills.md"))return!0;let n=h(e,"AGENTS.md");if(n!==null&&Je(n))return!0;let r=P(t);if(r===null)return!1;let s=h(e,r);return s!==null&&s.includes("skills/")}function T(e,t,n){let r=e.settings?.[t];if(x(r)&&Object.keys(r).some(a=>a.startsWith(n)))return!0;if(e.settingsRaw===null)return!1;let s=t.replaceAll(".",String.raw`\.`);return new RegExp(`"${s}"\\s*:\\s*\\{[^}]*"${n}[^"]*"`).test(e.settingsRaw)}var wa=50;function So(e){return e.files.some(t=>t.path.startsWith("agents/")&&t.path.endsWith(".agent.md"))}function nt(e,t){let n=U(e,t);return n===null?!1:n<=wa}function ko(e,t){let n=h(e,t);return n===null?!1:n.includes("AGENTS.md")||n.includes("docs/ai/rules.md")}function rt(e){return e.files.some(t=>t.path.startsWith(".agent/workflows/"))}function xo(e){let t=h(e,"CLAUDE.md");return t!==null&&Xe(t)}function Zt(e,t){let n=So(t.context);switch(e){case"copilot":case"cursor":return T(t.vscode,"chat.agentFilesLocations","agents")&&n?p("yes","agents/ wired in chat.agentFilesLocations"):n?p("partial","agents/ present but not wired in VS Code settings"):p("no","No agents/ tree or VS Code agent locations");case"codex":return t.context.files.some(s=>s.path.startsWith(".codex/agents/"))&&n?p("yes",".codex/agents wrappers with shared agents/"):n?p("partial","agents/ present without .codex/agents wrappers"):p("no","No custom agents configured");case"claude":return xo(t.context)?p("yes","Agent routing table in CLAUDE.md"):n?p("partial","agents/ present without routing table in CLAUDE.md"):p("no","No agent routing or agents/ tree");case"gemini":{if(!n)return p("no","No agents/ tree");let r=P("gemini"),s=r===null?null:t.context.fileContents.get(r)??null;return s!==null&&s.includes("agents/")?p("partial","agents/ referenced from GEMINI.md"):p("partial","agents/ present; document routing in GEMINI.md")}case"antigravity":return p("na","Uses workflow playbooks instead of custom agents");default:return p("no","Unknown harness")}}function en(e,t){let n=t.vscode.hooksDirExists,r=t.vscode.settings?.["chat.useCustomAgentHooks"]===!0;switch(e){case"copilot":case"cursor":return n&&r?p("yes",".github/hooks/ with chat.useCustomAgentHooks"):n||r?p("partial","Hooks partially configured in VS Code workspace"):p("no","No lifecycle hooks configured");case"codex":return t.codexHooksExists?p("yes",".codex/hooks.json present"):n?p("partial","Shared .github/hooks/ only; no .codex/hooks.json"):p("no","No Codex hooks configured");case"claude":return t.claudeSettingsRaw!==null&&/"hooks"\s*:/.test(t.claudeSettingsRaw)?p("yes","Hooks in .claude/settings.json"):n?p("partial","Shared .github/hooks/ only; no .claude hooks"):p("no","No Claude hooks configured");case"gemini":return n&&r?p("partial","Shared VS Code hooks only; no Gemini-native hooks"):p("no","No lifecycle hooks for Gemini");case"antigravity":return p("na","No hook surface for Antigravity workflows");default:return p("no","Unknown harness")}}function tn(e,t){if(!I(t.context))return p("no","No skills/ tree");switch(e){case"copilot":case"cursor":return T(t.vscode,"chat.agentSkillsLocations","skills")?p("yes","skills/ wired in chat.agentSkillsLocations"):p("partial","skills/ present but not wired in VS Code settings");case"codex":return Ce(t.context,"codex")?p("partial","skills/ with prose discovery via AGENTS.md or skill index"):p("partial","skills/ present; no documented discovery workflow");case"claude":case"gemini":return Ce(t.context,e)?p("partial","Prose discovery via skill index or adapter pointers"):p("no","skills/ without index or adapter pointers");case"antigravity":return rt(t.context)?p("yes","skills/ with workflow playbooks"):p("partial","skills/ present without workflow playbooks");default:return p("no","Unknown harness")}}function nn(e,t){switch(e){case"copilot":{let n=P("copilot");return n===null||!t.context.files.some(r=>r.path===n)?p("no","Missing .github/copilot-instructions.md"):nt(t.context,n)?p("yes","Copilot instructions within line budget"):p("partial","Copilot instructions exceed thin adapter budget")}case"cursor":{let n=t.context.files.some(s=>s.path.startsWith(".cursor/rules/")),r=T(t.vscode,"chat.agentSkillsLocations","skills")&&T(t.vscode,"chat.agentFilesLocations","agents");return n||r?p("yes","Cursor rules or VS Code agent settings configured"):p("partial","Cursor detected without rules or agent settings")}case"codex":return t.context.files.some(r=>r.path.startsWith(".codex/"))?t.context.files.some(r=>r.path==="AGENTS.md")?p("yes",".codex/ with shared AGENTS.md entry"):p("partial",".codex/ without root AGENTS.md"):p("no","No .codex/ config surface");case"claude":{let n=P("claude");if(n===null||!t.context.files.some(o=>o.path===n))return p("no","Missing CLAUDE.md");let r=nt(t.context,n),s=ko(t.context,n);return r&&s?p("yes","Thin CLAUDE.md referencing shared layers"):r?p("partial","CLAUDE.md thin but missing shared layer pointers"):p("partial","CLAUDE.md exceeds thin adapter budget")}case"gemini":{let n=P("gemini");return n===null||!t.context.files.some(r=>r.path===n)?p("no","Missing GEMINI.md"):nt(t.context,n)?p("yes","Thin GEMINI.md adapter"):p("partial","GEMINI.md exceeds thin adapter budget")}case"antigravity":return p("partial","Workflows only; no classic root adapter");default:return p("no","Unknown harness")}}function rn(e,t){return e!=="antigravity"?p("na","Workflow playbooks are Antigravity-specific"):rt(t.context)?p("yes",".agent/workflows/ playbooks present"):p("no","No .agent/workflows/ playbooks")}function sn(e,t,n){switch(e){case"sharedSkillsDiscoverable":return tn(t,n);case"customAgents":return Zt(t,n);case"lifecycleHooks":return en(t,n);case"thinAdapter":return nn(t,n);case"workflows":return rn(t,n);default:return p("no","Unknown capability")}}var on={sharedSkillsDiscoverable:"Shared skills discoverable",customAgents:"Custom agents",lifecycleHooks:"Lifecycle hooks",thinAdapter:"Thin adapter",workflows:"Workflows / playbooks"},Ae=["sharedSkillsDiscoverable","customAgents","lifecycleHooks","thinAdapter","workflows"],Ro="Harness not detected";import{readFile as ba}from"node:fs/promises";import Ca from"node:path";async function an(e){try{return await ba(Ca.join(e,".claude/settings.json"),"utf8")}catch{return null}}async function cn(e,t){let n=Q.filter(o=>e.harnesses.includes(o)),r={context:e,vscode:t,claudeSettingsRaw:await an(e.repoRoot),codexHooksExists:await Xt(e.repoRoot)},s=Qt();for(let o of Ae){let i=s[o];for(let a of Q){if(!e.harnesses.includes(a)){i[a]=p("na",Ro);continue}i[a]=sn(o,a,r)}}return{capabilities:Ae,harnesses:n,matrix:s}}function ln(e){if(process.stdout.write(`## Harness gap matrix
94
94
 
95
95
  `),e.harnesses.length===0){process.stdout.write(`No harnesses detected \u2014 add tool adapters to compare capabilities.
96
96
 
97
- `);return}let t=28,n=Math.max(...e.harnesses.map(r=>r.length),6)+2,s=`${"Capability".padEnd(t)}${e.harnesses.map(r=>r.padEnd(n)).join("")}`;process.stdout.write(`${s}
98
- `);for(let r of be){let o=Qt[r].padEnd(t),i=e.harnesses.map(a=>{let{status:c}=e.matrix[r][a];return Je(c).padEnd(n)}).join("");process.stdout.write(`${o}${i}
97
+ `);return}let t=28,n=Math.max(...e.harnesses.map(s=>s.length),6)+2,r=`${"Capability".padEnd(t)}${e.harnesses.map(s=>s.padEnd(n)).join("")}`;process.stdout.write(`${r}
98
+ `);for(let s of Ae){let o=on[s].padEnd(t),i=e.harnesses.map(a=>{let{status:c}=e.matrix[s][a];return tt(c).padEnd(n)}).join("");process.stdout.write(`${o}${i}
99
99
  `)}process.stdout.write(`
100
100
  Legend: \u2713 yes ~ partial \u2717 no \u2014 not applicable
101
101
 
102
- `)}function nn(e){e!==void 0&&(process.stdout.write(`## Intelligence layer
102
+ `)}function un(e){e!==void 0&&(process.stdout.write(`## Intelligence layer
103
103
 
104
104
  `),process.stdout.write(`Surfaces: ${String(e.surfaces.length)} detected
105
105
  `),process.stdout.write(`Enforcement: ${String(e.enforcement.scripts.length)} script(s), ${String(e.enforcement.configs.length)} config(s), ${String(e.enforcement.ciWorkflows.length)} CI workflow(s)
@@ -109,83 +109,85 @@ Legend: \u2713 yes ~ partial \u2717 no \u2014 not applicable
109
109
  `),process.stdout.write(`Correction loop: ${String(e.correctionLoop.scripts.length)} script(s), ${String(e.correctionLoop.prTemplates.length)} PR template(s), ${String(e.correctionLoop.ciWorkflows.length)} CI workflow(s)
110
110
  `),process.stdout.write(`Correction checks: ${String(e.correctionLoop.maintenanceScripts.length)} maintenance script(s), ${String(e.correctionLoop.prTemplateChecks.length)} PR reminder(s), ${String(e.correctionLoop.guidanceCiWorkflows.length)} CI guidance gate(s)
111
111
 
112
- `))}function sn(e){process.stdout.write(`## Meta-harness dimensions
112
+ `))}function dn(e){process.stdout.write(`## Meta-harness dimensions
113
113
 
114
- `);for(let t of uo){let n=e.dimensions[t];if(n===void 0)continue;let s=lo[t],r=n.applicableRules===0?" (no rules yet)":` (${String(n.passedRules)}/${String(n.applicableRules)} rules)`;process.stdout.write(`${s}: ${String(n.score)}/100 (${n.grade})${r}
115
- `)}process.stdout.write(`
116
- `)}function rn(e){process.stdout.write(`## Harness optimization
114
+ `);for(let c of fo){let l=e.dimensions[c];if(l===void 0)continue;let m=mo[c],u=l.applicableRules===0?" (no rules yet)":` (${String(l.passedRules)}/${String(l.applicableRules)} rules)`;process.stdout.write(`${m}: ${String(l.score)}/100 (${l.grade})${u}
115
+ `)}let{coverage:t}=e,n=`Total: ${String(e.total_score)}/100 (${e.score_scope}) \u2014 ${String(t.rulesApplied)} rules across ${String(t.dimensionsRun)}/${String(t.dimensionsTotal)} core dimensions`,r=t.level==="partial"?` (partial coverage: ${t.dimensionsNotRun.join(", ")} did not run \u2014 the score reflects evaluated surfaces only)`:"";process.stdout.write(`${n}${r}
116
+ `);let{harnessNet:s}=e,o=s.score>0?"+":"",i=s.repoReadiness===null?"":` \xB7 repo readiness ${String(s.repoReadiness)}/100`,a=s.status==="implicit-only"?" (implicit infrastructure only \u2014 tests, gates, and enforced comments count as harness; no guidance files detected)":` (${String(s.contributions.length)} contributions, ${String(s.liabilities.length)} liabilities)`;process.stdout.write(`Harness net: ${o}${String(s.score)} vs bare-repo baseline 0${a}${i}
117
+
118
+ `)}function pn(e){process.stdout.write(`## Harness optimization
117
119
 
118
- `);let t=e.filter(s=>s.detected);if(t.length===0){process.stdout.write(`No harnesses detected \u2014 add tool adapters to evaluate optimization.
120
+ `);let t=e.filter(r=>r.detected);if(t.length===0){process.stdout.write(`No harnesses detected \u2014 add tool adapters to evaluate optimization.
119
121
 
120
- `);return}for(let s of t){let r=s.score===null?"n/a":`${String(s.score)}/100 (${s.grade})`;process.stdout.write(`${s.harness}: ${r}
121
- `),s.loadProfile!==null&&process.stdout.write(` Load profile: ${String(s.loadProfile.sharedLines)} shared + ${String(s.loadProfile.uniqueLines)} unique lines (${String(s.loadProfile.sharedPercent)}% shared)
122
- `);let o=s.checks.filter(a=>!a.passed),i=s.checks.length-o.length;process.stdout.write(` Checks: ${String(i)}/${String(s.checks.length)} passed`),s.findingsCount.error+s.findingsCount.warn>0&&process.stdout.write(`; findings: ${String(s.findingsCount.error)} error, ${String(s.findingsCount.warn)} warn`),process.stdout.write(`
122
+ `);return}for(let r of t){let s=r.score===null?"n/a":`${String(r.score)}/100 (${r.grade})`;process.stdout.write(`${r.harness}: ${s}
123
+ `),r.loadProfile!==null&&process.stdout.write(` Load profile: ${String(r.loadProfile.sharedLines)} shared + ${String(r.loadProfile.uniqueLines)} unique lines (${String(r.loadProfile.sharedPercent)}% shared)
124
+ `);let o=r.checks.filter(a=>!a.passed),i=r.checks.length-o.length;process.stdout.write(` Checks: ${String(i)}/${String(r.checks.length)} passed`),r.findingsCount.error+r.findingsCount.warn>0&&process.stdout.write(`; findings: ${String(r.findingsCount.error)} error, ${String(r.findingsCount.warn)} warn`),process.stdout.write(`
123
125
  `);for(let a of o.slice(0,5))process.stdout.write(` \u2717 ${a.label}
124
126
  `);o.length>5&&process.stdout.write(` \u2026 and ${String(o.length-5)} more
125
127
  `),process.stdout.write(`
126
- `)}let n=e.filter(s=>!s.detected);n.length>0&&process.stdout.write(`Not detected: ${n.map(s=>s.harness).join(", ")}
128
+ `)}let n=e.filter(r=>!r.detected);n.length>0&&process.stdout.write(`Not detected: ${n.map(r=>r.harness).join(", ")}
127
129
 
128
- `)}function on(e){process.stdout.write(`## Guidance sharing
130
+ `)}function mn(e){process.stdout.write(`## Guidance sharing
129
131
 
130
132
  `),process.stdout.write(`Shared (canonical / multi-harness): ${String(e.shared.lines)} lines (${String(e.shared.percentLines)}%) across ${String(e.shared.files)} file(s)
131
133
  `),process.stdout.write(`Harness-specific: ${String(e.unique.totals.lines)} lines (${String(e.unique.totals.percentLines)}%) across ${String(e.unique.totals.files)} file(s)
132
- `);let t=po.filter(n=>e.unique.byHarness[n].lines>0);if(t.length>0){process.stdout.write(`
134
+ `);let t=go.filter(n=>e.unique.byHarness[n].lines>0);if(t.length>0){process.stdout.write(`
133
135
  Per-harness unique guidance:
134
- `);for(let n of t){let s=e.unique.byHarness[n];process.stdout.write(` ${n}: ${String(s.lines)} lines (${String(s.files)} file(s))
136
+ `);for(let n of t){let r=e.unique.byHarness[n];process.stdout.write(` ${n}: ${String(r.lines)} lines (${String(r.files)} file(s))
135
137
  `)}}process.stdout.write(`
136
- `)}function an(e){if(process.stdout.write(`paniolo-scan \u2014 AI harness diagnostic
138
+ `)}function fn(e){if(process.stdout.write(`paniolo-scan \u2014 AI harness diagnostic
137
139
 
138
140
  `),process.stdout.write(`Root: ${e.root}
139
141
  `),process.stdout.write(`Harnesses: ${e.harnesses.length===0?"(none detected)":e.harnesses.join(", ")}
140
142
  `),process.stdout.write(`Guidance files: ${String(e.inventory.fileCount)}
141
143
  `),process.stdout.write(`Findings: ${String(e.summary.error)} error(s), ${String(e.summary.warn)} warn(s), ${String(e.summary.info)} info
142
144
 
143
- `),on(e.sharing),nn(e.intelligenceLayer),jt(e.contextBudget),sn(e.metaHarness),Gt(e.aiReview),tn(e.harnessGapMatrix),rn(e.harnessOptimization),Wt(e.failureModeExposure),process.stdout.write(`## Findings
145
+ `),mn(e.sharing),un(e.intelligenceLayer),Kt(e.contextBudget),dn(e.metaHarness),qt(e.aiReview),ln(e.harnessGapMatrix),pn(e.harnessOptimization),Yt(e.failureModeExposure),process.stdout.write(`## Findings
144
146
 
145
147
  `),e.findings.length===0)process.stdout.write(`No findings.
146
148
 
147
- `);else{let t=[...e.findings].sort((n,s)=>{let r=Ot.indexOf(n.severity)-Ot.indexOf(s.severity);return r!==0?r:n.ruleId.localeCompare(s.ruleId)});for(let n of t)process.stdout.write(`${$t(n)}
148
-
149
- `)}process.stdout.write(fo)}import yl from"node:path";function cn(){return{copilot:{files:0,lines:0,bytes:0},cursor:{files:0,lines:0,bytes:0},codex:{files:0,lines:0,bytes:0},antigravity:{files:0,lines:0,bytes:0},claude:{files:0,lines:0,bytes:0},gemini:{files:0,lines:0,bytes:0}}}function ln(e,t){return e.harness!==void 0?t.includes(e.harness)?[e.harness]:[]:Ut.has(e.layer)?t:e.path.startsWith(".cursor/")?t.includes("cursor")?["cursor"]:[]:e.path.startsWith(".codex/")?t.includes("codex")?["codex"]:[]:e.path.startsWith(".agent/")?t.includes("antigravity")?["antigravity"]:[]:e.path==="AGENTS.md"||e.path.startsWith("docs/ai/")?t:[]}function Y(e,t){return t===0?0:Math.round(e/t*1e3)/10}function un(e,t){let n={files:0,lines:0,bytes:0},s=cn(),r={files:0,lines:0,bytes:0},o={files:0,lines:0,bytes:0},i=[];for(let a of e){let c=ln(a,t);if(c.length===0)continue;o.files+=1,o.lines+=a.lines,o.bytes+=a.bytes;let l=mo(a,c),p=l?"shared":"unique";if(i.push({path:a.path,lines:a.lines,scope:p,harnesses:c}),l)n.files+=1,n.lines+=a.lines,n.bytes+=a.bytes;else{let[f]=c;f!==void 0&&(s[f].files+=1,s[f].lines+=a.lines,s[f].bytes+=a.bytes),r.files+=1,r.lines+=a.lines,r.bytes+=a.bytes}}return{totals:o,shared:{...n,percentLines:Y(n.lines,o.lines)},unique:{byHarness:s,totals:{...r,percentLines:Y(r.lines,o.lines)}},files:i}}import T from"node:path";import{access as ga}from"node:fs/promises";async function x(e){try{return await ga(e),!0}catch{return!1}}function dn(e){return e===null?!1:e["chat.agentSkillsLocations"]!==void 0||e["chat.agentFilesLocations"]!==void 0||e["chat.useCustomAgentHooks"]===!0}import{readFile as ha}from"node:fs/promises";function pn(e){if(e==="true")return!0;if(e==="false")return!1;if(e==="null")return null;if(e.startsWith('"')&&e.endsWith('"'))return e.slice(1,-1);let t=Number(e);return Number.isNaN(t)?e:t}function fn(e){let t={},n=/"([^"]+)"\s*:\s*(true|false|null|\d+(?:\.\d+)?|"[^"]*")/g;for(let[,s,r]of e.matchAll(n))s===void 0||r===void 0||(t[s]=pn(r));return Object.keys(t).length===0?null:t}function Ce(e){try{let t=JSON.parse(e);if(y(t))return t}catch{}return fn(e)}async function mn(e){try{let t=await ha(e,"utf8");return Ce(t)}catch{return null}}async function Ae(e){let t=new Set;await x(T.join(e,".github/copilot-instructions.md"))&&t.add("copilot"),await x(T.join(e,".github/hooks"))&&t.add("copilot");let n=await mn(T.join(e,".vscode/settings.json"));return dn(n)&&(t.add("cursor"),t.add("copilot")),await x(T.join(e,".cursor"))&&t.add("cursor"),await x(T.join(e,".codex/config.toml"))&&t.add("codex"),await x(T.join(e,".codex/hooks.json"))&&t.add("codex"),await x(T.join(e,".codex/agents"))&&t.add("codex"),await x(T.join(e,".agent/workflows"))&&t.add("antigravity"),await x(T.join(e,".agent/README.md"))&&t.add("antigravity"),await x(T.join(e,"CLAUDE.md"))&&t.add("claude"),await x(T.join(e,".claude/settings.json"))&&t.add("claude"),await x(T.join(e,"GEMINI.md"))&&t.add("gemini"),[...t].sort()}function Ie(e){return Math.ceil(e/4)}function H(e,t){return{path:e.path,lines:e.lines,bytes:e.bytes,estimatedTokens:Ie(e.bytes),reason:t}}function gn(e,t){let n=e.fileContents.get(t.path);return n===void 0?!1:/^alwaysApply:\s*true\s*$/im.test(n)||/^always_apply:\s*true\s*$/im.test(n)}function J(e,t){return e.files.find(n=>n.path===t)??null}function hn(e,t){let n=[];if(t==="copilot"){let s=J(e,".github/copilot-instructions.md");s!==null&&n.push(H(s,"Copilot workspace instructions are loaded by Copilot Chat."))}if(t==="cursor")for(let s of e.files)s.path.startsWith(".cursor/rules/")&&gn(e,s)&&n.push(H(s,"Cursor rule declares alwaysApply: true."));if(t==="codex"){let s=J(e,"AGENTS.md");s!==null&&n.push(H(s,"Root AGENTS.md is the Codex repo instruction entry."));for(let r of e.files)r.path.startsWith(".codex/")&&r.layer==="adapter"&&n.push(H(r,"Codex adapter guidance under .codex/."))}if(t==="antigravity"){let s=J(e,".agent/README.md");s!==null&&n.push(H(s,"Antigravity workspace adapter README."))}if(t==="claude"){let s=J(e,"CLAUDE.md");s!==null&&n.push(H(s,"Claude Code root instruction file."))}if(t==="gemini"){let s=J(e,"GEMINI.md");s!==null&&n.push(H(s,"Gemini root instruction file."))}return n.toSorted((s,r)=>s.path.localeCompare(r.path))}function yn(e,t){if(!e.harnesses.includes(t))return{harness:t,detected:!1,files:[],totalLines:0,totalBytes:0,estimatedTokens:0,maxRecommendedLines:250,status:"ok"};let s=hn(e,t),r=s.reduce((i,a)=>i+a.lines,0),o=s.reduce((i,a)=>i+a.bytes,0);return{harness:t,detected:!0,files:s,totalLines:r,totalBytes:o,estimatedTokens:Ie(o),maxRecommendedLines:250,status:r>250?"high":"ok"}}function Sn(e){return{harnesses:K.map(t=>yn(e,t)),maxRecommendedLines:250,maxRecommendedFileLines:150}}var kn=["Memory","Reflection","Planning","Action","System Operation"];function xn(e){let t=new Map(kn.map(i=>[i,{dimension:i,findingCount:0,error:0,warn:0,info:0,ruleIds:[]}])),n=new Map(kn.map(i=>[i,new Set])),s=0,r=0;for(let i of e){let a=Ye(i.ruleId);if(a.length===0){r+=1;continue}s+=1;for(let c of a){let l=t.get(c),p=n.get(c);l===void 0||p===void 0||(l.findingCount+=1,l[i.severity]+=1,p.has(i.ruleId)||(p.add(i.ruleId),l.ruleIds.push(i.ruleId)))}}return{byDimension:kn.map(i=>t.get(i)).filter(i=>i.findingCount>0),taggedFindings:s,untaggedFindings:r}}function wn(e,t){let n={sharedLines:0,uniqueLines:0,totalLines:0,sharedPercent:0,uniquePercent:0},s={copilot:{...n},cursor:{...n},codex:{...n},antigravity:{...n},claude:{...n},gemini:{...n}};for(let r of t){let o=e.unique.byHarness[r].lines,i=e.shared.lines,a=i+o;s[r]={sharedLines:i,uniqueLines:o,totalLines:a,sharedPercent:Y(i,a),uniquePercent:Y(o,a)}}return s}function Rn(e,t){let n={error:0,warn:0,info:0};for(let s of e)s.harnesses.includes(t)&&(s.severity==="error"?n.error+=1:s.severity==="warn"?n.warn+=1:n.info+=1);return n}var xo=[{min:85,grade:"excellent"},{min:70,grade:"good"},{min:50,grade:"fair"},{min:0,grade:"poor"}],Ze={error:12,warn:5,info:1},wo=40;function bn(e){let t=e.error*Ze.error+e.warn*Ze.warn+e.info*Ze.info;return Math.min(t,wo)}import ve from"node:path";function M(e,t){return e.files.some(n=>n.path===t)}function Cn(e,t){return e.fileContents.get(t)??null}function ya(e,t){return e.files.find(s=>s.path===t)?.lines??null}function Sa(e){return e.includes("AGENTS.md")||e.includes("docs/ai/rules.md")}function X(e){return e.files.some(t=>t.path.startsWith("skills/"))}function Ee(e){return e.files.some(t=>t.path.startsWith("agents/"))}function An(e,t){return e.settings?.[t]===!0}function et(e,t){let n=ya(e,t);return n===null?!1:n<=W}function tt(e,t){let n=Cn(e,t);return n===null?!1:Sa(n)}function In(e){let t=Cn(e,".agent/README.md");return t===null?!1:/\.agent\/workflows\/|workflows\//i.test(t)&&/(workflow|playbook|slash command|mission|turbo)/i.test(t)}function Q(e,t,n){let s=e.settings?.[t];if(y(s)&&Object.keys(s).some(a=>a.startsWith(n)))return!0;if(e.settingsRaw===null)return!1;let r=t.replaceAll(".",String.raw`\.`);return new RegExp(`"${r}"\\s*:\\s*\\{[^}]*"${n}[^"]*"`).test(e.settingsRaw)}var Ro={copilot:[{id:"copilot-instructions",label:"Copilot instructions file present",weight:15,run:({context:e})=>M(e,".github/copilot-instructions.md")},{id:"copilot-references-shared",label:"Copilot instructions reference shared layers",weight:15,run:({context:e})=>tt(e,".github/copilot-instructions.md")},{id:"copilot-adapter-thin",label:"Copilot instructions stay thin",weight:10,run:({context:e})=>et(e,".github/copilot-instructions.md")},{id:"copilot-skills-location",label:"chat.agentSkillsLocations points at skills/",weight:15,run:({vscode:e})=>Q(e,"chat.agentSkillsLocations","skills")},{id:"copilot-agents-location",label:"chat.agentFilesLocations points at agents/",weight:15,run:({vscode:e})=>Q(e,"chat.agentFilesLocations","agents")},{id:"copilot-hooks-enabled",label:"Custom agent hooks enabled when .github/hooks/ exists",weight:15,run:({vscode:e})=>!e.hooksDirExists||An(e,"chat.useCustomAgentHooks")},{id:"copilot-shared-skills",label:"Shared skills/ tree present",weight:8,run:({context:e})=>X(e)},{id:"copilot-shared-agents",label:"Shared agents/ tree present",weight:7,run:({context:e})=>Ee(e)}],cursor:[{id:"cursor-rules-or-settings",label:"Cursor rules or VS Code agent settings present",weight:20,run:({context:e,vscode:t})=>e.files.some(n=>n.path.startsWith(".cursor/rules/"))||Q(t,"chat.agentSkillsLocations","skills")},{id:"cursor-skills-location",label:"chat.agentSkillsLocations points at skills/",weight:20,run:({vscode:e})=>Q(e,"chat.agentSkillsLocations","skills")},{id:"cursor-agents-location",label:"chat.agentFilesLocations points at agents/",weight:20,run:({vscode:e})=>Q(e,"chat.agentFilesLocations","agents")},{id:"cursor-hooks-enabled",label:"Custom agent hooks enabled when .github/hooks/ exists",weight:15,run:({vscode:e})=>!e.hooksDirExists||An(e,"chat.useCustomAgentHooks")},{id:"cursor-shared-skills",label:"Shared skills/ tree present",weight:13,run:({context:e})=>X(e)},{id:"cursor-shared-agents",label:"Shared agents/ tree present",weight:12,run:({context:e})=>Ee(e)}],codex:[{id:"codex-config-surface",label:"Codex config surface present (.codex/ or nested AGENTS.md)",weight:25,run:async({context:e})=>e.files.some(t=>t.path.startsWith(".codex/"))?!0:await x(ve.join(e.repoRoot,"api/AGENTS.md"))||await x(ve.join(e.repoRoot,"react/AGENTS.md"))||await x(ve.join(e.repoRoot,"shared/AGENTS.md"))},{id:"codex-hooks",label:"Codex hooks.json present",weight:20,run:({context:e})=>x(ve.join(e.repoRoot,".codex/hooks.json"))},{id:"codex-agents-wrappers",label:"Codex agent wrappers present",weight:20,run:({context:e})=>x(ve.join(e.repoRoot,".codex/agents"))},{id:"codex-shared-entry",label:"Root AGENTS.md present",weight:20,run:({context:e})=>M(e,"AGENTS.md")},{id:"codex-shared-skills",label:"Shared skills/ tree present",weight:8,run:({context:e})=>X(e)},{id:"codex-shared-rules",label:"Canonical rules doc present",weight:7,run:({context:e})=>M(e,"docs/ai/rules.md")}],antigravity:[{id:"antigravity-workflows",label:"Workflow playbooks present (.agent/workflows/)",weight:35,run:({context:e})=>e.files.some(t=>t.path.startsWith(".agent/workflows/"))},{id:"antigravity-readme",label:".agent/README.md documents workflow layout",weight:15,run:({context:e})=>In(e)},{id:"antigravity-shared-entry",label:"Root AGENTS.md present",weight:20,run:({context:e})=>M(e,"AGENTS.md")},{id:"antigravity-shared-skills",label:"Shared skills/ tree present",weight:15,run:({context:e})=>X(e)},{id:"antigravity-ai-system-doc",label:"AI system layout doc present",weight:15,run:({context:e})=>M(e,"docs/ai/ai-system.md")}],claude:[{id:"claude-adapter",label:"CLAUDE.md adapter present",weight:25,run:({context:e})=>M(e,"CLAUDE.md")},{id:"claude-references-shared",label:"CLAUDE.md references shared layers",weight:25,run:({context:e})=>tt(e,"CLAUDE.md")},{id:"claude-adapter-thin",label:"CLAUDE.md stays thin",weight:20,run:({context:e})=>et(e,"CLAUDE.md")},{id:"claude-shared-skills",label:"Shared skills/ tree present",weight:15,run:({context:e})=>X(e)},{id:"claude-skills-index",label:"Skill index doc for prose discovery",weight:8,run:({context:e})=>M(e,"docs/ai/available-skills.md")},{id:"claude-shared-agents",label:"Shared agents/ tree present",weight:7,run:({context:e})=>Ee(e)}],gemini:[{id:"gemini-adapter",label:"GEMINI.md adapter present",weight:30,run:({context:e})=>M(e,"GEMINI.md")},{id:"gemini-references-shared",label:"GEMINI.md references shared layers",weight:25,run:({context:e})=>tt(e,"GEMINI.md")},{id:"gemini-adapter-thin",label:"GEMINI.md stays thin",weight:20,run:({context:e})=>et(e,"GEMINI.md")},{id:"gemini-shared-skills",label:"Shared skills/ tree present",weight:15,run:({context:e})=>X(e)},{id:"gemini-shared-agents",label:"Shared agents/ tree present",weight:10,run:({context:e})=>Ee(e)}]};async function En(e,t){let n=Ro[e],s=[];for(let r of n){let o=await r.run(t);s.push({id:r.id,label:r.label,passed:o,weight:r.weight})}return s}function vn(e){let t=e.reduce((s,r)=>s+r.weight,0);if(t===0)return 0;let n=e.filter(s=>s.passed).reduce((s,r)=>s+r.weight,0);return Math.round(n/t*100)}function Tn(e){for(let{min:t,grade:n}of xo)if(e>=t)return n;return"poor"}async function Ln(e,t,n,s,r,o){if(!t.harnesses.includes(e))return{harness:e,detected:!1,score:null,grade:"not-detected",checks:[],findingsCount:{error:0,warn:0,info:0},loadProfile:null};let c=await En(e,{context:t,vscode:n,harness:e}),l=Rn(s,e),p=vn(c),f=bn(l),m=Math.max(0,Math.min(100,p-f));return{harness:e,detected:!0,score:m,grade:Tn(m),checks:c,findingsCount:l,loadProfile:o[e]??null}}async function Fn(e,t,n,s){let r=wn(s,e.harnesses),o=[];for(let i of K){let a=await Ln(i,e,t,n,s,r);o.push(a)}return o}import{readFileSync as ka}from"node:fs";import{dirname as xa,join as bo}from"node:path";import{fileURLToPath as wa}from"node:url";var Ra=wa(import.meta.url),Co=xa(Ra);function nt(e){return typeof e=="object"&&e!==null}function ba(e){return nt(e)&&nt(e.dimensions)&&nt(e.check_weights)}function Ca(e){return nt(e)}function Ao(e,t){let n=JSON.parse(ka(e,"utf8"));if(!t(n))throw new Error(`Invalid standards file: ${e}`);return n}var _n=Ao(bo(Co,"standards","weights.json"),ba),Nn=Ao(bo(Co,"standards","reference-thresholds.json"),Ca);function Pn(e){return!Number.isFinite(e)||e<0?0:e<=1?e:e<=10?e/10:e<=100?e/100:1}function Io(e,t){return e>=t?1:0}function Eo(e,t){return e<=t?1:e===0?0:t/e}function vo(e,t){if(t<=0)return 0;let n=e/t;return Math.max(0,Math.min(1,n))}function Hn(e,t,n){return e>=t&&e<=n?1:e<t?t===0?0:e/t:e===0?0:n/e}function Mn(e){if(e.curve===void 0)return Pn(e.rawScore??0);let t=e.measuredValue??0,n=e.referenceValue,s=typeof n=="number"?n:0;switch(e.curve){case"binary":return Io(t,s);case"asymptoticDecay":return Eo(t,s);case"ratio":return vo(t,s);case"goldilocks":{let[r,o]=Array.isArray(n)?n:[0,s];return Hn(t,r??0,o??0)}}}function Dn(e,t){let n={};for(let r of Object.keys(t.dimensions))n[r]={weightedSum:0,weightSum:0,ran:!1,passedRules:0,applicableRules:0};for(let r of e){let o=n[r.dimension];if(!o)continue;o.ran=!0,o.applicableRules+=1;let i=Mn(r);i===1&&(o.passedRules+=1);let a=r.weight??t.check_weights[r.checkId]??1;!Number.isFinite(a)||a<=0||(o.weightedSum+=i*a,o.weightSum+=a)}let s={};for(let[r,o]of Object.entries(t.dimensions)){let i=n[r];if(!i||!i.ran){s[r]={status:"not_run",score:null,grade:"not-run",passedRules:0,applicableRules:0};continue}let a=i.weightSum>0?i.weightedSum/i.weightSum*o.max_score:0,c=Number.isFinite(a)?Math.round(a):0;s[r]={status:"run",score:c,grade:we(c),passedRules:i.passedRules,applicableRules:i.applicableRules}}return s}function On(e,t){let n=0,s=0;for(let[r,o]of Object.entries(t.dimensions)){let i=e[r];if(!i||i.status!=="run"||i.score===null)continue;let a=Number(o.weight);!Number.isFinite(a)||a<=0||(n+=i.score/o.max_score*a,s+=a)}return s===0?0:Math.round(n/s*100)}var Aa=new Set(["deep","session"]);function $n(e){for(let[t,n]of Object.entries(e))if(Aa.has(t)&&n.status==="run")return"core+extended";return"core"}function Gn(e,t,n,s,r){if(n.totals.lines>0){let l=typeof Nn.sharing_target_percent=="number"?Nn.sharing_target_percent:65;e.push({checkId:"sharing-percent",dimension:"sharing",curve:"ratio",measuredValue:n.shared.percentLines,referenceValue:l})}let o=s.filter(l=>l.detected&&l.score!==null);if(o.length>0){let l=o.reduce((p,f)=>p+(f.score??0),0)/o.length;e.push({checkId:"harness-optimization-avg",dimension:"harnessWiring",curve:"ratio",measuredValue:l,referenceValue:100})}let i=Dn(e,_n),a=On(i,_n),c=$n(i);return{profile:"meta-harness",total_score:a,score_scope:c,dimensions:i}}import{readFile as Fa}from"node:fs/promises";import Un from"node:path";import{readdir as Ia}from"node:fs/promises";import Ea from"node:path";async function st(e){let t=[".md",".mdc"];function n(o){return t.some(i=>o.endsWith(i))}let s=[],r=[];try{r=await Ia(e,{withFileTypes:!0})}catch{return s}for(let o of r){if(o.isSymbolicLink())continue;let i=Ea.join(e,o.name);o.isDirectory()?s.push(...await st(i)):o.isFile()&&n(i)&&s.push(i)}return s}import{readFile as va,stat as Ta}from"node:fs/promises";import La from"node:path";function jn(e){return e.length===0?0:e.split(`
150
- `).length}async function Wn(e,t,n,s){let r=La.join(e,t);try{if(!(await Ta(r)).isFile())return null;let i=await va(r,"utf8"),a=jn(i),c={path:t,layer:n,lines:a,bytes:Buffer.byteLength(i,"utf8")};return s!==void 0&&(c.harness=s),c}catch{return null}}var _a=["AGENTS.md","docs/ai/rules.md","docs/ai/ai-system.md","docs/ai/available-skills.md","docs/ai/hooks.md"],Na=[{path:"CLAUDE.md",harness:"claude"},{path:"GEMINI.md",harness:"gemini"},{path:".github/copilot-instructions.md",harness:"copilot"},{path:".agent/README.md",harness:"antigravity"}],Pa=[{dir:"skills",layer:"skills"},{dir:"agents",layer:"agents"},{dir:".cursor/rules",layer:"adapter",harness:"cursor"},{dir:".agent/workflows",layer:"workflows",harness:"antigravity"},{dir:".codex",layer:"adapter",harness:"codex"},{dir:"docs/ai",layer:"shared"}];async function Te(e){let t=[],n=new Map,s=new Set;async function r(o,i,a){let c=o.replaceAll("\\","/");if(s.has(c))return;let l=await Wn(e,c,i,a);if(l===null)return;s.add(c),t.push(l);let p=Un.join(e,c);try{let f=await Fa(p,"utf8");n.set(c,f)}catch{}}for(let o of _a)await r(o,"shared");for(let o of Na)await r(o.path,"adapter",o.harness);for(let{dir:o,layer:i,harness:a}of Pa){let c=Un.join(e,o),l=await st(c);for(let p of l){let f=Un.relative(e,p).replaceAll("\\","/");await r(f,i,a)}}return t.sort((o,i)=>o.path.localeCompare(i.path)),{files:t,contents:n}}import{readFile as Ha}from"node:fs/promises";import To from"node:path";import{fileURLToPath as Ma}from"node:url";function Bn(e){return typeof e=="object"&&e!==null&&"version"in e&&typeof e.version=="string"}async function Vn(){let e=To.resolve(To.dirname(Ma(import.meta.url)),"../package.json"),t=await Ha(e,"utf8"),n=JSON.parse(t);if(!Bn(n))throw new Error("package.json is missing a string version field");return{version:n.version}}var Lo=null;function Fo(){return Lo??=Vn(),Lo}import{extname as ja}from"node:path";import{readdir as Da}from"node:fs/promises";import $o from"node:path";var _o=new Set([".git","node_modules","dist","coverage"]),No=[/^tsconfig(?:\..+)?\.json$/],Po=[/^eslint\.config\.[cm]?[jt]s$/,/^\.eslintrc(?:\..+)?$/,/^\.oxlintrc(?:\..+)?$/,/^biome\.jsonc?$/,/^ruff\.toml$/,/^\.ruff\.toml$/],Ho=[/^\.prettierrc(?:\..+)?$/,/^\.markdownlint(?:rc)?(?:\..+)?$/],Mo=[/^vitest\.config\.[cm]?[jt]s$/,/^jest\.config\.[cm]?[jt]s$/,/^playwright\.config\.[cm]?[jt]s$/,/^cypress\.config\.[cm]?[jt]s$/],Do=[/^package\.json$/,/^pyproject\.toml$/,/^Cargo\.toml$/,/^go\.mod$/],zn=/(scan:self|check:ai-system|check:md|lint:md|check:links|qmd|markdownlint|textlint|remark|cspell|paniolo-scan)/i,Oo=/(correction loop|intelligence layer|diagnostic rule|rules catalog|canonical rules|paired skill|guidance hygiene|adapters stayed thin|json output keys are stable)/i;async function pe(e,t=""){let n=$o.join(e,t),s=[];try{s=await Da(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let o of s){if(o.isSymbolicLink()||_o.has(o.name))continue;let i=$o.join(t,o.name).replaceAll("\\","/");o.isDirectory()?r.push(...await pe(e,i)):o.isFile()&&r.push(i)}return r}var Go=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".json",".jsonc",".yaml",".yml",".toml"]),jo=new Set(["package-lock.json","npm-shrinkwrap.json","yarn.lock","pnpm-lock.yaml","bun.lock","bun.lockb","cargo.lock","poetry.lock","uv.lock","composer.lock","gemfile.lock"]),Wo=512*1024,qn=/(?:\.(?:test|spec)\.[a-z]+$|(?:^|\/)(?:__tests__|__fixtures__|fixtures|test|tests)\/)/i,Uo=/\b(?:claude|gpt|chatgpt|gemini|mistral|codestral|llama|grok|deepseek|command|qwen|o1|o3|o4)[a-z0-9.]*(?:-[a-z0-9.]+)*-latest\b/i,Le=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py"]),Bo=/\b(?:anthropic|openai|mistralai|cohere|generativeai|langchain|chat\.completions|messages\.create|responses\.create|generateobject|generatetext|streamtext|generate_content)\b/i,Vo=/\.choices\s*\[|tool_?calls?\b|function_?call|\.content\s*\[|\bJSON\.parse\s*\(|\bjson\.loads\s*\(/i,zo=/\b(?:zod|valibot|superstruct|typebox|class-validator|ajv|yup|pydantic|basemodel|model_validate|parse_obj|typeadapter|jsonschema|marshmallow)\b|\.safeparse\s*\(|\bz\.object\s*\(/i,rt=/\btools\s*:\s*\[|\btool_choice\s*[:=]|\bfunction_?declarations\s*[:=]|\b(?:defineTool|zodFunction|registerTool)\s*\(|\bserver\.tool\s*\(|\binput_?schema\s*[:=]|^\s*@tool\b/im,qo=/\btool\b|\barguments?\b|\bfunction_?call|\bparameters?\b|\binput_?schema\b/i,Ko=/\btothrow\b|\.rejects\b|\bassert_?raises\b|pytest\.raises|\binvalid\b|\bmalformed\b|\bmissing\b|\bsafeparse\b|\berrors?\b/i;import Yo from"node:path";function Kn(e){let t=Yo.basename(e).toLowerCase();return jo.has(t)?!1:Go.has(Yo.extname(t))}import{readFile as Oa,stat as $a}from"node:fs/promises";import Ga from"node:path";async function Yn(e,t){let n=Ga.join(e,t);try{return(await $a(n)).size>Wo?null:{path:t,content:await Oa(n,"utf8")}}catch{return null}}async function Jn(e){let n=(await pe(e)).filter(o=>Kn(o)),r=(await Promise.all(n.map(o=>Yn(e,o)))).filter(o=>o!==null);return{sourceFiles:r.filter(o=>!qn.test(o.path)).toSorted((o,i)=>o.path.localeCompare(i.path)),testFiles:r.filter(o=>qn.test(o.path)&&Le.has(ja(o.path))).toSorted((o,i)=>o.path.localeCompare(i.path))}}async function Xn(e){let{sourceFiles:t,testFiles:n}=await Jn(e);return{sourceFiles:t,testFiles:n}}import Ba from"node:path";import{readFile as Wa,stat as Ua}from"node:fs/promises";import Jo from"node:path";function Xo(e){return e.length===0?0:e.split(`
151
- `).length}async function Qo(e,t){try{return(await Ua(Jo.join(e,t))).isFile()}catch{return!1}}async function D(e,t){try{return await Wa(Jo.join(e,t),"utf8")}catch{return null}}function ot(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function fe(e,t){return t.some(n=>n.test(e))}function Zo(e){return/^\.github\/workflows\/.+\.ya?ml$/.test(e)}function ei(e){return e===".github/PULL_REQUEST_TEMPLATE.md"||/^\.github\/PULL_REQUEST_TEMPLATE\/.+\.md$/.test(e)||/^docs\/pull_request_template\.md$/i.test(e)}function it(e,t){return zn.test(`${e}
152
- ${t}`)}function at(e){return zn.test(e.commands.join(`
153
- `))}function ti(e){return Oo.test(e)}function ni(e){let t=e.toLowerCase();return t.includes("naming")||t.includes("comment")||t.includes("local-context")||t.includes("codebase-map")}function Qn(e){let t=Ba.posix.basename(e);return fe(t,No)?{path:e,kind:"typecheck",capabilities:["typecheck"]}:fe(t,Po)?{path:e,kind:"lint",capabilities:["lint"]}:fe(t,Ho)?{path:e,kind:"format",capabilities:["format"]}:fe(t,Mo)?{path:e,kind:"test",capabilities:["test"]}:fe(t,Do)?{path:e,kind:"manifest",capabilities:["project-manifest"]}:null}function Zn(e){let t=e.toLowerCase();return t==="docs/architecture.md"||t==="docs/overview.md"||t==="docs/meta-harness.md"||t==="docs/ai/codebase-map.md"||t==="docs/ai/ai-system.md"||t.includes("/adr")||t.includes("architecture")||t.includes("codebase-map")||t.includes("design")}function es(e){let t=e.toLowerCase();return t==="docs/ai/codebase-map.md"||t==="docs/ai/ai-system.md"||t==="docs/overview.md"||t.endsWith("/adr/index.md")||t.endsWith("/adrs/index.md")}function Fe(e){if(!ot(e))return{};let t={};for(let[n,s]of Object.entries(e))typeof s=="string"&&(t[n]=s);return t}function ts(e){if(e===null)return{path:null,scripts:{},dependencies:[],devDependencies:[]};try{let t=JSON.parse(e);if(!ot(t))return{path:"package.json",scripts:{},dependencies:[],devDependencies:[]};let n=Fe(t.scripts),s=Object.keys(Fe(t.dependencies)).toSorted(),r=Object.keys(Fe(t.devDependencies)).toSorted();return{path:"package.json",scripts:n,dependencies:s,devDependencies:r}}catch{return{path:"package.json",scripts:{},dependencies:[],devDependencies:[]}}}import{stat as Va}from"node:fs/promises";import za from"node:path";async function B(e,t,n,s,r){let o=za.join(e,t),i=await Va(o),a=await D(e,t),c={path:t,kind:n,layer:s,capabilities:r,bytes:i.size};return a!==null&&(c.lines=Xo(a)),c}function ns(e){let t=[],n=/^\s*-\s*run:\s*(.+)$/,s=/^\s*-\s*run:\s*[>|]/,r=!1;for(let o of e.split(/\r?\n/)){let i=o.match(n);if(i!==null){t.push(i[1]?.trim()??""),r=!1;continue}if(s.test(o)){r=!0;continue}r&&(/^\s{6,}\S/.test(o)?t.push(o.trim()):/^\s*-\s/.test(o)&&(r=!1))}return t.filter(o=>o.length>0)}async function ss(e,t){let n=await D(e,t);return n===null?null:{path:t,commands:ns(n),content:n}}function ct(e){let t=Object.keys(e.packageJson.scripts),n=t.filter(i=>/(^|:)(typecheck|lint|format|check)(:|$)/i.test(i)),s=t.filter(i=>/(^|:)(test|e2e)(:|$)/i.test(i)),r=t.filter(i=>it(i,e.packageJson.scripts[i]??"")),o=e.workflows.filter(at).map(i=>i.path).toSorted();return{surfaces:e.surfaces,enforcement:{scripts:n.toSorted(),configs:e.configs.filter(i=>i.kind==="typecheck"||i.kind==="lint").map(i=>i.path).toSorted(),ciWorkflows:e.workflows.filter(i=>/(typecheck|lint|format|check)/i.test(i.commands.join(`
154
- `))).map(i=>i.path).toSorted()},validation:{scripts:s.toSorted(),configs:e.configs.filter(i=>i.kind==="test").map(i=>i.path).toSorted(),ciWorkflows:e.workflows.filter(i=>/(npm test|npm run test|vitest|jest|playwright|cypress)/i.test(i.commands.join(`
155
- `))).map(i=>i.path).toSorted()},memory:{docs:e.memoryDocs.toSorted(),indexes:e.memoryIndexes.toSorted()},localContext:{conventions:e.localContextConventions.toSorted(),nestedAgentsFiles:e.nestedAgentsFiles.toSorted()},correctionLoop:{scripts:r.toSorted(),prTemplates:e.prTemplates.toSorted(),ciWorkflows:o,maintenanceScripts:e.guidanceMaintenanceScripts.toSorted(),prTemplateChecks:e.aiHarnessPrTemplates.toSorted(),guidanceCiWorkflows:o}}}async function rs(e){let t=await pe(e),n=ts(await D(e,"package.json")),s=[],r=[],o=[],i=[],a=[],c=[],l=[],p=[],f=[],m={customChecker:!1,packageScript:!1,lintRules:!1,stopHook:!1,guidance:!1};m.packageScript=Object.entries(n.scripts).some(([d,g])=>/(^|:)(lint:jsdoc|check:jsdoc)(:|$)/i.test(d)||/find-missing-jsdoc|check-jsdoc-files/i.test(g));for(let d of t){let g=Qn(d);if(g!==null){let S={...g},A=await D(e,d);g.kind==="typecheck"&&A!==null&&/"strict"\s*:\s*true/.test(A)&&(S.capabilities=[...g.capabilities,"strict-typecheck"]),g.kind==="lint"&&A!==null&&/jsdoc\/require-(returns|param)/i.test(A)&&(m.lintRules=!0),s.push(S),f.push(await B(e,d,"enforcement","config",S.capabilities))}if(Zo(d)){let S=await ss(e,d);if(S!==null){r.push(S);let A=await B(e,d,"workflow","automation",["ci-workflow"]);f.push(A)}}if(ei(d)){o.push(d);let S=await D(e,d);S!==null&&ti(S)&&i.push(d);let A=await B(e,d,"automation","pull-request",["pr-template"]);f.push(A)}if(d.endsWith(".md")&&Zn(d)&&(a.push(d),es(d)&&c.push(d),f.push(await B(e,d,"memory","docs",["memory"]))),d.endsWith(".md")&&ni(d)&&l.push(d),(d==="scripts/find-missing-jsdoc/analyzeFile.ts"||d==="scripts/find-missing-jsdoc/check-jsdoc-files.bun.ts")&&(m.customChecker=!0),(d==="docs/ai/code-comment-best-practices.md"||d==="skills/code-comment-best-practices/SKILL.md")&&(m.guidance=!0),d.startsWith(".github/hooks/")&&d.endsWith(".json")){let S=await D(e,d);S!==null&&/lint-on-stop|find-missing-jsdoc|jsdoc/i.test(S)&&(m.stopHook=!0)}if(d.endsWith("/AGENTS.md")){p.push(d);let S=await B(e,d,"local-context","nested-entry",["nested-agents-md"]);f.push(S)}}return n.path!==null&&await Qo(e,n.path)&&f.push(await B(e,n.path,"automation","project",["package-scripts"])),{packageJson:n,configs:s.toSorted((d,g)=>d.path.localeCompare(g.path)),workflows:r.toSorted((d,g)=>d.path.localeCompare(g.path)),prTemplates:o,guidanceMaintenanceScripts:Object.entries(n.scripts).filter(([d,g])=>it(d,g)).map(([d])=>d).toSorted(),aiHarnessPrTemplates:i.toSorted(),guidanceCiWorkflows:r.filter(d=>at(d)).map(d=>d.path).toSorted(),memoryDocs:a,memoryIndexes:c.toSorted(),localContextConventions:l.toSorted(),nestedAgentsFiles:p,surfaces:f.toSorted((d,g)=>d.path.localeCompare(g.path)),jsdocEnforcement:m}}import Xa from"node:path";import{readdir as qa}from"node:fs/promises";import Ka from"node:path";async function os(e,t){let n=[];try{n=await qa(Ka.join(e,t),{withFileTypes:!0})}catch{return[]}return n.filter(s=>s.isFile()).map(s=>`${t}/${s.name}`)}import{readFile as Ya,stat as Ja}from"node:fs/promises";import ui from"node:path";var si=[".claude/settings.json",".claude/settings.local.json"],ri=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local",".env.test"],oi=[".gitleaks.toml",".github/gitleaks.toml",".github/secret_scanning.yml",".github/secret_scanning.yaml"],ii=[".pre-commit-config.yaml",".pre-commit-config.yml"],ai=["config/worker-vars.list","config/env-secrets.dev.list","config/env-secrets.staging.list","config/env-secrets.production.list","scripts/env/run-with-env/run-with-env.bun.ts"],ci=/gitleaks|trufflehog|detect-secrets|ggshield/i,li=/(?:\.\/)?(?:[\w.-]+\/)+[\w.-]+\.(?:tsx?|mts|cts|mjs|cjs|js|sh|bash|py)/g;async function F(e,t){try{return await Ya(ui.join(e,t),"utf8")}catch{return null}}async function O(e,t){try{return(await Ja(ui.join(e,t))).isFile()}catch{return!1}}function V(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function lt(e){try{return{ok:!0,value:JSON.parse(e)}}catch{return{ok:!1,value:null}}}function di(e){let{permissions:t}=e;return!V(t)||!Array.isArray(t.allow)?[]:t.allow.filter(n=>typeof n=="string")}function pi(e){let{permissions:t}=e;return!V(t)||typeof t.defaultMode!="string"?null:t.defaultMode}function ut(e){let t=e.match(li)??[];return[...new Set(t.map(n=>n.replace(/^\.\//,"")))]}async function fi(e,t,n){let s=await O(e,n),r=s?await F(e,n):null;return{reference:{source:t,path:n,exists:s},content:r}}async function is(e,t){for(let n of await os(e,".claude/hooks")){let s=await F(e,n);s!==null&&t.push({source:n,path:n,isStop:/stop/i.test(Xa.posix.basename(n)),content:s})}}async function as(e){for(let t of ai)if(await O(e,t))return!0;return!1}function cs(e){let t=e.hooks;if(t===void 0)return{hooks:[],malformed:!1};if(!V(t))return{hooks:[],malformed:!0};let n=[],s=!1;for(let[r,o]of Object.entries(t)){if(!Array.isArray(o)){s=!0;continue}for(let i of o){if(!V(i)||!Array.isArray(i.hooks)){s=!0;continue}for(let a of i.hooks){if(!V(a)||typeof a.command!="string"){s=!0;continue}n.push({event:r,command:a.command})}}}return{hooks:n,malformed:s}}async function ls(e,t){let n=await F(e,t);if(n===null)return null;let{ok:s,value:r}=lt(n);if(!s||!V(r))return{path:t,valid:!1,allow:[],defaultMode:null,hooks:[],hooksMalformed:!1};let{hooks:o,malformed:i}=cs(r);return{path:t,valid:!0,allow:di(r),defaultMode:pi(r),hooks:o,hooksMalformed:i}}async function us(e){let t=".codex/hooks.json",n=await F(e,t);if(n===null)return null;let{ok:s,value:r}=lt(n);if(!s)return{path:t,valid:!1,referencedScripts:[]};let o=[];for(let i of ut(JSON.stringify(r))){let a=await O(e,i);o.push({source:t,path:i,exists:a})}return{path:t,valid:!0,referencedScripts:o}}async function ds(e){let t=[];for(let n of ri)await O(e,n)&&t.push(n);return t}async function ps(e,t){let n=[],s=[],r=t.flatMap(o=>o.hooks.map(i=>({surface:o,hook:i})));for(let{surface:o,hook:i}of r){let a=`${o.path} (${i.event} hook)`,c=[i.command];for(let l of ut(i.command)){let{reference:p,content:f}=await fi(e,a,l);s.push(p),f!==null&&c.push(f)}n.push({source:a,path:null,isStop:i.event==="Stop",content:c.join(`
156
- `)})}return{hookScripts:n,referencedClaudeScripts:s}}async function fs(e){let t=[];for(let n of oi)await O(e,n)&&t.push(n);for(let n of ii){let s=await F(e,n);s!==null&&ci.test(s)&&t.push(n)}return t}async function _e(e){let t=[];for(let l of si){let p=await ls(e,l);p!==null&&t.push(p)}let{hookScripts:n,referencedClaudeScripts:s}=await ps(e,t);await is(e,n);let[r,o,i,a,c]=await Promise.all([us(e),F(e,".gitignore"),ds(e),fs(e),as(e)]);return{claudeSettings:t,referencedClaudeScripts:s,hookScripts:n,codexHooks:r,gitignore:o,envFilesPresent:i,secretScanningFiles:a,usesKeyringSecrets:c}}import{readFile as Qa,stat as Za}from"node:fs/promises";import mi from"node:path";async function Z(e){let t=mi.join(e,".github/hooks"),n=!1;try{n=(await Za(t)).isDirectory()}catch{n=!1}let s=mi.join(e,".vscode/settings.json"),r=null,o=null;try{let i=await Qa(s,"utf8");o=i,r=Ce(i)}catch{r=null,o=null}return{settings:r,settingsRaw:o,hooksDirExists:n}}function Ne(e,t,n,s){return{ruleId:e,severity:"warn",message:`${t} has ${String(n)} lines; keep root adapters thin (max ${String(W)}).`,file:t,line:null,harnesses:[s],hint:"Move detailed guidance to docs/ai/ and skills/; keep the adapter as a pointer."}}import{extname as gi}from"node:path";function ms(e){let t=[],n=e.split(`
157
- `);for(let s=0;s<n.length;s+=1){let r=Uo.exec(n[s]??"");r!==null&&t.push({line:s+1,alias:r[0]})}return t}function gs(e){if(!Bo.test(e)||zo.test(e))return null;let t=e.split(`
158
- `);for(let n=0;n<t.length;n+=1)if(Vo.test(t[n]??""))return n+1;return null}var Pe={findings:[],records:[]},ec={id:"model-interface-pinned",title:"Model interface pinned",severity:"warn",category:"reliability",dimension:"guardrails",harnesses:[],check(e){let t=e.boundary?.sourceFiles;if(t===void 0)return Pe;let n=[];for(let s of t)for(let{line:r,alias:o}of ms(s.content))n.push({ruleId:"model-interface-pinned",severity:"warn",message:`${s.path} references the floating model alias "${o}"; the model behind a "latest" tag can change without notice.`,file:s.path,line:r,harnesses:[],hint:"Pin a dated/versioned model snapshot (e.g. a -YYYYMMDD or explicit-version id) so model upgrades are a deliberate, reviewable change."});return{findings:n,records:[]}}},tc={id:"llm-output-schema-validated",title:"LLM output schema-validated",severity:"warn",category:"reliability",dimension:"guardrails",harnesses:[],check(e){let t=e.boundary?.sourceFiles;if(t===void 0)return Pe;let n=[];for(let s of t){if(!Le.has(gi(s.path)))continue;let r=gs(s.content);r!==null&&n.push({ruleId:"llm-output-schema-validated",severity:"warn",message:`${s.path} consumes LLM/tool output (line ${String(r)}) without a schema validator; a shape change in the model response surfaces as a downstream type error.`,file:s.path,line:r,harnesses:[],hint:"Validate the parsed response against a Zod/Pydantic/JSON-Schema schema at the boundary before reading its fields."})}return{findings:n,records:[]}}},nc={id:"tool-contract-tests-present",title:"Tool contract tests present",severity:"info",category:"reliability",dimension:"guardrails",harnesses:[],check(e){let{boundary:t}=e;if(t===void 0)return Pe;let n=t.sourceFiles.find(r=>Le.has(gi(r.path))&&rt.test(r.content));return n===void 0||t.testFiles.some(r=>qo.test(r.content)&&Ko.test(r.content))?Pe:{findings:[{ruleId:"tool-contract-tests-present",severity:"info",message:`${n.path} declares model-callable tools, but no test exercises tool-call argument validation or error responses \u2014 only happy-path behavior is covered.`,file:n.path,line:null,harnesses:[],hint:"Add tests that feed malformed or missing tool-call arguments and assert the error path, per declared tool."}],records:[]}}},hi=[ec,tc,nc];function hs(e){let t=[];for(let n of Ue){if(!E(e,n))continue;let s=h(e,n);s===null||eo(s)||t.push({ruleId:"adapter-points-to-shared",severity:"warn",message:`${n} should reference AGENTS.md and docs/ai/rules.md.`,file:n,line:null,harnesses:[],hint:"Keep adapters thin; point at shared layers instead of duplicating rules."})}return{findings:t,records:[]}}function ys(e){let t=[];for(let n of ue(e,"agents/")){if(!n.endsWith(".agent.md"))continue;let s=h(e,n);if(s===null)continue;let r=Be(s);if(r===null){t.push({ruleId:"agent-frontmatter",severity:"error",message:`${n} is missing YAML frontmatter.`,file:n,line:null,harnesses:[]});continue}ce(r,"name")||t.push({ruleId:"agent-frontmatter",severity:"error",message:`${n} is missing a name field in frontmatter.`,file:n,line:null,harnesses:[]}),ce(r,"description")||t.push({ruleId:"agent-frontmatter",severity:"error",message:`${n} is missing a description field in frontmatter.`,file:n,line:null,harnesses:[]})}return{findings:t,records:[]}}function Ss(e){if(!N(e)||!E(e,"AGENTS.md"))return{findings:[],records:[]};let t=h(e,"AGENTS.md");return t!==null&&Ve(t)?{findings:[],records:[]}:{findings:[{ruleId:"agents-md-mentions-skills",severity:"info",message:"AGENTS.md should point at docs/ai/available-skills.md or the qmd search workflow.",file:"AGENTS.md",line:null,harnesses:[],hint:"Document how agents discover skills (index doc or npm run qmd -- search)."}],records:[]}}function ks(e){if(!e.harnesses.includes("claude")||!E(e,"CLAUDE.md"))return{findings:[],records:[]};let t=h(e,"CLAUDE.md");return t!==null&&ze(t)?{findings:[],records:[]}:{findings:[{ruleId:"claude-agent-routing",severity:"info",message:"CLAUDE.md should include an Agent Routing table pointing at agents/*.agent.md.",file:"CLAUDE.md",line:null,harnesses:["claude"],hint:"Add a markdown table mapping task types to shared agents/*.agent.md files."}],records:[]}}var yi=/!?\[([^\]]*)\]\(([^)]+)\)/g;function ee(e){let t=[],n=yi.exec(e);for(;n!==null;){let[s]=n;s.startsWith("!")||t.push({label:n[1]??"",href:(n[2]??"").trim()}),n=yi.exec(e)}return t}var sc=new Set(["url","path","href","link","..."]);function He(e){return e.length===0||sc.has(e.toLowerCase())||e.startsWith("http://")||e.startsWith("https://")||e.startsWith("mailto:")||e.startsWith("tel:")?!0:(e.split("#")[0]??"").length===0}function xs(e){let t=e.replaceAll("\\","/").split("/"),n=[];for(let s of t)if(!(s===""||s===".")){if(s===".."){n.pop();continue}n.push(s)}return n.join("/")}function Me(e,t){let n=(t.split("#")[0]??"").trim();if(n.length===0)return null;let s=n;try{s=decodeURIComponent(n)}catch{s=n}if(s.startsWith("/"))return s.slice(1).replaceAll("\\","/");let r=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"",o=r.length===0?s:`${r}/${s}`;return xs(o)}function ws(e){return!e.endsWith(".md")&&!e.endsWith(".mdc")?!1:e.startsWith("docs/")||e.includes("/docs/")}function Rs(e,t){for(let n of ee(t)){if(He(n.href))continue;let s=Me(e,n.href);if(s!==null&&ws(s))return!0}return!1}var rc=50;function bs(e){let t=[];for(let n of e.files){if(!n.path.startsWith("skills/")||!n.path.endsWith("SKILL.md")||(n.lines??0)<=rc)continue;let s=h(e,n.path);s===null||Rs(n.path,s)||t.push({ruleId:"skill-doc-deep-links",severity:"info",message:`${n.path} does not deep-link into a durable doc under docs/.`,file:n.path,line:null,harnesses:[],hint:"Pair the skill with a docs/ reference and link it (for example a **Details:** link to a docs/ page) instead of inlining all detail."})}return{findings:t,records:[]}}function Cs(e){let t=[];for(let n of ue(e,"skills/")){if(!n.endsWith("/SKILL.md")&&!n.endsWith("SKILL.md"))continue;let s=h(e,n);if(s===null)continue;let r=Be(s);if(r===null){t.push({ruleId:"skill-frontmatter",severity:"error",message:`${n} is missing YAML frontmatter.`,file:n,line:null,harnesses:[]});continue}ce(r,"name")||t.push({ruleId:"skill-frontmatter",severity:"error",message:`${n} is missing a name field in frontmatter.`,file:n,line:null,harnesses:[]}),ce(r,"description")||t.push({ruleId:"skill-frontmatter",severity:"error",message:`${n} is missing a description field in frontmatter.`,file:n,line:null,harnesses:[]})}return{findings:t,records:[]}}function As(e){let t=[];for(let n of ue(e,"skills/")){if(!n.endsWith("SKILL.md"))continue;let s=U(e,n);s!==null&&s>bt&&t.push({ruleId:"skill-line-count",severity:"warn",message:`${n} has ${String(s)} lines; keep skills under ${String(bt)}.`,file:n,line:null,harnesses:[],hint:"Move detail to docs/; keep SKILL.md as a pointer."})}return{findings:t,records:[]}}var Si="docs/ai/available-skills.md";function Is(e){return N(e)?E(e,Si)?{findings:[],records:[]}:{findings:[{ruleId:"skills-index",severity:"info",message:`${Si} is missing; add a skill slug index when using skills/.`,file:null,line:null,harnesses:[],hint:"List each skills/<slug>/ folder so agents can pick a minimal skill set."}],records:[]}:{findings:[],records:[]}}var oc=["AGENTS.md","CLAUDE.md","GEMINI.md",".github/copilot-instructions.md",".agent/README.md"],ki=["IMPORTANT","CRITICAL","MANDATORY","REQUIRED","MUST NOT","MUST","NEVER","ALWAYS","SHALL","DO NOT"],xi=.03,wi=40,Ri=[{pattern:/\byou are an? (?:expert|senior|world[- ]class|10x|highly skilled|seasoned|professional)\b/i,label:"identity framing (\u201Cyou are a/an \u2026\u201D)"},{pattern:/\bact as an?\b/i,label:"roleplay framing (\u201Cact as a \u2026\u201D)"},{pattern:/\bas an ai (?:language model|assistant)\b/i,label:"AI self-reference"},{pattern:/\bworld[- ]class\b/i,label:"superlative filler (\u201Cworld-class\u201D)"}];function dt(e){return e.replaceAll(/```[\s\S]*?```/g," ")}function bi(e){let t=e.match(/\S+/g);return t===null?0:t.length}function me(e){return oc.filter(t=>h(e,t)!==null)}function Es(e){let t=0;for(let n of ki){let s=e.match(new RegExp(`\\b${n}\\b`,"g"));s!==null&&(t+=s.length)}return t}function vs(e){let t=[];for(let n of me(e)){let s=h(e,n);if(s===null)continue;let r=dt(s),o=bi(r);if(o<wi)continue;let i=Es(r),a=i/o;if(a<=xi)continue;let c=(a*100).toFixed(1);t.push({ruleId:"emphasis-keyword-density",severity:"info",message:`${n} uses ${String(i)} all-caps emphasis keyword(s) across ${String(o)} words (${c}%); emphasis loses force when overused.`,file:n,line:null,harnesses:[],hint:"Reserve IMPORTANT/MUST/NEVER for the few rules that truly need them; rewrite the rest as plain, action-oriented instructions."})}return{findings:t,records:[]}}function Ts(e){let t=[];for(let n of me(e)){let s=h(e,n);if(s===null)continue;let r=dt(s),o=Ri.filter(({pattern:i})=>i.test(r)).map(({label:i})=>i);o.length!==0&&t.push({ruleId:"identity-language-absent",severity:"info",message:`${n} contains identity/roleplay filler: ${o.join(", ")}.`,file:n,line:null,harnesses:[],hint:"Drop identity framing; state what to do, not who to be. Action-oriented rules outperform persona prompts."})}return{findings:t,records:[]}}var Ci=[{id:"emphasis-keyword-density",title:"Emphasis-keyword density",severity:"info",category:"instruction-quality",dimension:"maintainability",harnesses:[],check:vs},{id:"identity-language-absent",title:"No identity-language filler",severity:"info",category:"instruction-quality",dimension:"maintainability",harnesses:[],check:Ts}];var Ai=/\bask\s+(?:the\s+)?(?:user|human|maintainer)\b|\bask\s+for\s+clarif|\brequest\s+clarification|\bseek\s+clarification|\bclarifying\s+questions?|\bwhen\s+(?:in\s+doubt|unsure|uncertain)\b|\bstop\s+and\s+ask\b|\bask\s+before\s+(?:assum|guess|proceed)|\bescalat(?:e|ion)\b|\b(?:ambiguous|unclear|contradictory|conflicting|incomplete)\b[^.\n]{0,40}\b(?:ask|clarif|escalat|confirm)/i,Ii=/\bmax[_\s-]?(?:iterations?|steps?|turns?|calls?|requests?|attempts?|retries|tokens?|cost|budget)\b|\bmax_calls_per_minute\b|\bcurrency_limits?\b|\brate[_\s-]?limit|\bbudget[_\s-]?(?:cap|limit)|\biteration[_\s-]?(?:cap|limit)|\bcost[_\s-]?(?:cap|limit)/i,Ei=/\blanggraph\b|\bcrewai\b|\bautogen\b|\bAgentExecutor\b|\bcreateReactAgent\b|@modelcontextprotocol|\bmcp\.server\b|\bserver\.tool\s*\(/i;function te(e){return[...e.fileContents.values()].join(`
159
- `)}function De(e){return(e.boundary?.sourceFiles??[]).map(t=>t.content).join(`
160
- `)}var vi=/\bmcpservers\b|\.mcp\.json\b|\bmcp__|modelcontextprotocol|\bmcp\s+servers?\b/i,Ti=/\ballow[\s_-]?list\b|\bmcpservers\b|allowed[_\s-]?tools|permitted[_\s-]?tools|"allow"\s*:|pinned\s+(?:tool|server|mcp)/i,Li=/\bmem0\b|memory\.(?:add|write|store|save|upsert)\b|vector[\s_-]?(?:store|db|database)|\bupsert\s*\(|\bembeddings?\b|\bpinecone\b|\bweaviate\b|\bchroma(?:db)?\b|\bqdrant\b|persistent\s+memory/i,Fi=/\bprovenance\b|\bquarantin|\buntrusted\b|\btaint(?:ed)?\b|trust[\s_-]?(?:level|tag|boundary)|source[\s_-]?tag|re-?validat/i,_i=/\bfetch\s*\(|\bwebfetch\b|\baxios\b|requests?\.get\b|\burllib\b|\bhttpx\b|\bscrap(?:e|ing)\b|\bcrawl|retriev(?:e|al)|web[\s_-]?search/i,Ni=/\bexec(?:Sync)?\s*\(|child_process|\bspawn\s*\(|\bsubprocess\b|os\.system|writeFileSync|\bfs\.write|\bunlink\s*\(|\brm\s+-rf\b/i,Pi=/saniti[sz]|\bvalidat|\ballow[\s_-]?list\b|\bescape\b|\bconfirm|\bapproval\b|\bguard(?:rail)?\b/i,Hi=/force[\s_-]?push|push\s+--force|\brm\s+-rf\b|delete\s+from\b|\.delete\s*\(|\bdestroy\s*\(|\bstripe\b|\bpayment|\bcharge\s*\(|wire\s+transfer|send[_\s-]?email|\bsendmail\b|\bdeploy\b|drop\s+table/i,Mi=/human[\s_-]?in[\s_-]?the[\s_-]?loop|\bconfirm(?:ation)?\b|\bapproval\b|\bescalat|requires?\s+(?:approval|confirmation)|dry[\s_-]?run|are\s+you\s+sure/i;function Ls(e){return e.files.some(n=>n.layer==="agents")?!0:(e.boundary?.sourceFiles??[]).some(n=>rt.test(n.content)||Ei.test(n.content))}function pt(e,t,n,s){return{findings:[{ruleId:e,severity:t,message:n,file:null,line:null,harnesses:[],hint:s}],records:[]}}var $={findings:[],records:[]},ic={id:"escalation-protocol-discoverability",title:"Escalation protocol discoverable",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=me(e);return t.length===0||Ai.test(te(e))?$:{findings:[{ruleId:"escalation-protocol-discoverability",severity:"info",message:"No discoverable escalation protocol in guidance: nothing documents when or how the agent should ask for clarification on missing, ambiguous, or contradictory specs.",file:t[0]??null,line:null,harnesses:[],hint:"Document an 'ask before guessing' protocol in AGENTS.md or the rules doc \u2014 the epistemic counterpart to action confirmation (HiL-Bench's 53-82pp finding)."}],records:[]}}},ac={id:"agent-resource-budget-caps",title:"Agent resource budget caps",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){if(!Ls(e))return $;let t=(e.boundary?.sourceFiles??[]).map(n=>n.content).join(`
161
- `);return Ii.test(`${te(e)}
162
- ${t}`)?$:{findings:[{ruleId:"agent-resource-budget-caps",severity:"info",message:"An agent/tool surface is present but no resource caps are declared (max iterations, cost, or rate limit); an unbounded loop is a resource-drain (R7) risk.",file:null,line:null,harnesses:[],hint:"Declare max-iteration, max-cost, or rate-limit caps, mirroring OAP's max_calls_per_minute / currency_limits."}],records:[]}}},cc={id:"tool-allowlist-inventory",title:"Tool allowlist inventory",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=`${te(e)}
163
- ${De(e)}`;return!vi.test(t)||Ti.test(t)?$:pt("tool-allowlist-inventory","info","Repo references MCP/tool servers but declares no explicit, pinned tool allowlist; arbitrary tool discovery widens the attack surface (R1/R3).","Declare an explicit allowlist of tools/MCP servers with pinned versions instead of allowing arbitrary discovery.")}},lc={id:"untrusted-input-action-boundary",title:"Untrusted input / action boundary",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=De(e);if(!(_i.test(t)&&Ni.test(t)))return $;let s=`${te(e)}
164
- ${t}`;return Pi.test(s)?$:pt("untrusted-input-action-boundary","warn","Source ingests external/untrusted content and takes actions (exec, file write) with no sanitization, validation, or confirmation in evidence (R2/R3 unconstrained data flow).","Sanitize, allow-list, or confirm untrusted content before it reaches shell exec, file writes, or tool dispatch.")}},uc={id:"memory-write-provenance",title:"Memory write provenance",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=`${te(e)}
165
- ${De(e)}`;return!Li.test(t)||Fi.test(t)?$:pt("memory-write-provenance","info","Repo writes to persistent agent memory but shows no provenance/trust tagging or re-validation; memory writes from untrusted sources can later be read as trusted (R6).","Tag or quarantine memory writes derived from untrusted sources and re-validate them before trusted reads.")}},dc={id:"high-impact-action-confirmation",title:"High-impact action confirmation",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=De(e);if(!Hi.test(t))return $;let n=`${te(e)}
166
- ${t}`;return Mi.test(n)?$:pt("high-impact-action-confirmation","warn","Source performs high-impact actions (deletion, payment, force-push, deploy, external send) with no human-in-the-loop confirmation or escalation in evidence (R6/R7).","Gate high-impact actions behind an explicit confirmation/escalation step, not just allow/deny (OWASP LLM06).")}},Di=[ic,ac,cc,lc,uc,dc];var pc=/\b(?:curl|wget|ncat|telnet|scp)\b|\bnc\s|Invoke-WebRequest|\bfetch\s*\(|\baxios\b|http\.request|urllib|requests\.(?:get|post|put|patch)/i,fc=/localhost|127\.0\.0\.1|0\.0\.0\.0|::1/i;function Fs(e){let t=[];for(let n of e.content.split(/\r?\n/)){let s=n.trim();pc.test(s)&&!fc.test(s)&&t.push(s)}return t}var mc=new Set(["Bash","Write","Edit","MultiEdit","NotebookEdit"]);function _s(e){let t=e.trim();if(t==="")return!1;if(t==="*")return!0;if(t.startsWith("mcp__"))return t.includes("*");let n=t.match(/^([A-Za-z_][\w-]*)(?:\((.*)\))?$/);if(n===null)return!1;let[,s="",r]=n;if(!mc.has(s))return!1;if(r===void 0)return!0;let o=r.trim();return o===""||o==="*"||o===":*"}var gc=/^[0-9a-f]{40}$/i;function Ns(e){let t=new Set,n=/^\s*-?\s*uses:\s*['"]?([^'"\s#]+)['"]?/gm;for(let s of e.matchAll(n)){let[,r]=s;if(r===void 0||r.startsWith("./")||r.startsWith("docker://"))continue;let o=r.includes("@")?r.slice(r.lastIndexOf("@")+1):"";gc.test(o)||t.add(r)}return[...t]}var G={findings:[],records:[]},hc=new Set(["bypassPermissions","acceptEdits"]),yc="stop_hook_active";function ne(e){return e.security??null}var Sc={id:"no-dangerous-auto-approve",title:"No dangerous auto-approve permissions",severity:"error",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ne(e);if(t===null)return G;let n=[];for(let s of t.claudeSettings){s.defaultMode!==null&&hc.has(s.defaultMode)&&n.push({ruleId:"no-dangerous-auto-approve",severity:"error",message:`${s.path} sets permissions.defaultMode "${s.defaultMode}", auto-approving actions without prompting.`,file:s.path,line:null,harnesses:["claude"],hint:'Use "default" or "plan" mode and allow-list specific commands instead of bypassing prompts.'});for(let r of s.allow.filter(_s))n.push({ruleId:"no-dangerous-auto-approve",severity:"error",message:`${s.path} auto-approves "${r}", a blanket grant over a dangerous capability.`,file:s.path,line:null,harnesses:["claude"],hint:"Scope allow-list entries to specific commands, e.g. Bash(npm run test:*) instead of Bash(*)."})}return{findings:n,records:[]}}},kc={id:"hook-no-network-exfil",title:"Hooks do not exfiltrate over the network",severity:"error",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ne(e);if(t===null)return G;let n=[];for(let s of t.hookScripts){let[r]=Fs(s);r!==void 0&&n.push({ruleId:"hook-no-network-exfil",severity:"error",message:`${s.source} makes a network call (\`${r.slice(0,80)}\`); hooks run automatically and can exfiltrate repo data.`,file:s.path,line:null,harnesses:[],hint:"Remove the network call or restrict it to localhost; move outbound calls into explicit, reviewable steps."})}return{findings:n,records:[]}}},xc={id:"hook-stop-circuit-breaker",title:"Stop hooks guard against infinite loops",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ne(e);if(t===null)return G;let n=[];for(let s of t.hookScripts)!s.isStop||s.content.includes(yc)||n.push({ruleId:"hook-stop-circuit-breaker",severity:"warn",message:`${s.source} is a Stop hook that never checks stop_hook_active; a blocking Stop hook can loop the agent indefinitely.`,file:s.path,line:null,harnesses:[],hint:"Read stop_hook_active from the hook input and exit without blocking when it is true."});return{findings:n,records:[]}}},wc={id:"env-files-gitignored",title:"Env files are gitignored",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ne(e);if(t===null)return G;let s=t.gitignore!==null&&/^\s*!?[*.]*\.env(?:[.*]|\b|\/)?/m.test(t.gitignore)?[]:t.envFilesPresent;if(s.length===0)return G;let r=t.usesKeyringSecrets?"This repo uses keyring-managed secrets; delete the committed .env file rather than relying on it.":"Gitignore `.env`/`.env.*`, or move secrets to an OS keyring (the run-with-env pattern) so they never touch disk.";return{findings:[{ruleId:"env-files-gitignored",severity:"warn",message:`${s.join(", ")} present but not gitignored; secrets risk being committed.`,file:s[0]??null,line:null,harnesses:[],hint:r}],records:[]}}};function Rc(e){return e.some(t=>/gitleaks|trufflehog|detect-secrets|ggshield/i.test(t.content))}var bc={id:"secret-scanning-configured",title:"Secret scanning is configured",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ne(e);if(t===null)return G;let n=e.intelligenceLayer?.workflows??[];return t.secretScanningFiles.length>0||Rc(n)?G:{findings:[{ruleId:"secret-scanning-configured",severity:"warn",message:"No secret-scanning configuration found (gitleaks, trufflehog, detect-secrets, or a pre-commit secret hook).",file:null,line:null,harnesses:[],hint:"Add a gitleaks/trufflehog CI step or a detect-secrets pre-commit hook so committed credentials are caught."}],records:[]}}},Cc={id:"no-pull-request-target",title:"No risky pull_request_target workflows",severity:"error",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=e.intelligenceLayer?.workflows??[],n=[];for(let s of t)/\bpull_request_target\b/.test(s.content)&&n.push({ruleId:"no-pull-request-target",severity:"error",message:`${s.path} triggers on pull_request_target, which runs with repo secrets against untrusted PR code.`,file:s.path,line:null,harnesses:[],hint:"Prefer pull_request; if pull_request_target is required, never check out or execute PR head code with secrets in scope."});return{findings:n,records:[]}}},Ac={id:"actions-sha-pinned",title:"GitHub Actions pinned to commit SHAs",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=e.intelligenceLayer?.workflows??[],n=[];for(let s of t){let r=Ns(s.content);r.length!==0&&n.push({ruleId:"actions-sha-pinned",severity:"warn",message:`${s.path} uses actions pinned to mutable refs: ${r.join(", ")}.`,file:s.path,line:null,harnesses:[],hint:"Pin each action to a full 40-character commit SHA (e.g. actions/checkout@<sha>) to prevent tag-hijack supply-chain attacks."})}return{findings:n,records:[]}}},Ic={id:"claude-hooks-valid",title:"Claude hooks config is valid",severity:"error",category:"hooks",dimension:"guardrails",harnesses:["claude"],check(e){let t=ne(e);if(t===null)return G;let n=[];for(let s of t.claudeSettings){if(!s.valid){n.push({ruleId:"claude-hooks-valid",severity:"error",message:`${s.path} is not valid JSON.`,file:s.path,line:null,harnesses:["claude"],hint:"Fix the JSON syntax; an unparseable settings file disables every configured hook silently."});continue}s.hooksMalformed&&n.push({ruleId:"claude-hooks-valid",severity:"error",message:`${s.path} has a malformed hooks block; entries must be { matcher?, hooks: [{ type, command }] }.`,file:s.path,line:null,harnesses:["claude"],hint:"Match the documented hooks schema so the configured commands actually run."})}for(let s of t.referencedClaudeScripts.filter(r=>!r.exists))n.push({ruleId:"claude-hooks-valid",severity:"error",message:`${s.source} references missing script ${s.path}.`,file:s.path,line:null,harnesses:["claude"],hint:"Create the script or fix the path; a missing hook command fails open and skips the check."});return{findings:n,records:[]}}},Ec={id:"codex-hooks-valid",title:"Codex hooks config is valid",severity:"error",category:"hooks",dimension:"guardrails",harnesses:["codex"],check(e){let t=ne(e);if(t===null||t.codexHooks===null)return G;let n=t.codexHooks,s=[];n.valid||s.push({ruleId:"codex-hooks-valid",severity:"error",message:`${n.path} is not valid JSON.`,file:n.path,line:null,harnesses:["codex"],hint:"Fix the JSON syntax so the configured codex hooks load."});for(let r of n.referencedScripts.filter(o=>!o.exists))s.push({ruleId:"codex-hooks-valid",severity:"error",message:`${n.path} references missing script ${r.path}.`,file:r.path,line:null,harnesses:["codex"],hint:"Create the script or fix the path so the hook command runs."});return{findings:s,records:[]}}},Oi=[Sc,kc,xc,wc,bc,Cc,Ac,Ic,Ec];var vc={id:"shared-agents-md",title:"Shared AGENTS.md entry point",severity:"warn",category:"structure",dimension:"layering",harnesses:[],check(e){return E(e,"AGENTS.md")?{findings:[],records:[]}:{findings:[{ruleId:"shared-agents-md",severity:"warn",message:"AGENTS.md is missing.",file:null,line:null,harnesses:[],hint:"Add AGENTS.md as the repo-wide AI entry point with workflow, safety, and pointers to canonical docs."}],records:[]}}},Tc={id:"shared-rules-doc",title:"Canonical rules doc",severity:"warn",category:"structure",dimension:"layering",harnesses:[],check(e){return E(e,"docs/ai/rules.md")?{findings:[],records:[]}:{findings:[{ruleId:"shared-rules-doc",severity:"warn",message:"docs/ai/rules.md is missing.",file:null,line:null,harnesses:[],hint:"Add docs/ai/rules.md as the canonical coding-rules reference."}],records:[]}}},Lc={id:"adapter-thin-claude",title:"Thin CLAUDE.md adapter",severity:"warn",category:"adapter",dimension:"layering",harnesses:["claude"],check(e){let t=U(e,"CLAUDE.md");return t===null||t<=W?{findings:[],records:[]}:{findings:[Ne("adapter-thin-claude","CLAUDE.md",t,"claude")],records:[]}}},Fc={id:"adapter-thin-gemini",title:"Thin GEMINI.md adapter",severity:"warn",category:"adapter",dimension:"layering",harnesses:["gemini"],check(e){let t=U(e,"GEMINI.md");return t===null||t<=W?{findings:[],records:[]}:{findings:[Ne("adapter-thin-gemini","GEMINI.md",t,"gemini")],records:[]}}},_c={id:"adapter-thin-copilot",title:"Thin Copilot instructions",severity:"warn",category:"adapter",dimension:"layering",harnesses:["copilot"],check(e){let t=".github/copilot-instructions.md",n=U(e,t);return n===null||n<=W?{findings:[],records:[]}:{findings:[Ne("adapter-thin-copilot",t,n,"copilot")],records:[]}}},Nc={id:"adapter-points-to-shared",title:"Adapters reference shared layers",severity:"warn",category:"adapter",dimension:"layering",harnesses:[],check:hs},Pc={id:"skill-frontmatter",title:"Skill frontmatter",severity:"error",category:"skills",dimension:"maintainability",harnesses:[],check:Cs},Hc={id:"skill-line-count",title:"Skill line budget",severity:"warn",category:"skills",dimension:"maintainability",harnesses:[],check:As},Mc={id:"agent-frontmatter",title:"Agent frontmatter",severity:"error",category:"agents",dimension:"maintainability",harnesses:[],check:ys},Dc={id:"skills-index",title:"Skill slug index",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:[],check:Is},Oc={id:"claude-agent-routing",title:"Claude agent routing table",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:["claude"],check:ks},$c={id:"agents-md-mentions-skills",title:"AGENTS.md skill discovery",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:[],check:Ss},Gc={id:"skill-doc-deep-links",title:"Skills deep-link into docs",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:[],check:bs},$i=[vc,Tc,Lc,Fc,_c,Nc,Pc,Hc,Mc,Dc,Oc,$c,Gc,...Ci,...Oi,...hi,...Di];function Ps(e){let t=e.contextBudget;if(t===void 0)return{findings:[],records:[]};let n=[],s=[];for(let r of t.harnesses)if(r.detected)for(let o of r.files)s.push({checkId:"adapter-context-budget",dimension:"maintainability",curve:"asymptoticDecay",measuredValue:o.lines,referenceValue:t.maxRecommendedFileLines}),!(o.lines<=t.maxRecommendedFileLines)&&n.push({ruleId:"adapter-context-budget",severity:"info",message:`${o.path} contributes ${String(o.lines)} always-loaded lines for ${r.harness}; recommended maximum per file is ${String(t.maxRecommendedFileLines)}.`,file:o.path,line:null,harnesses:[r.harness],hint:"Split detailed guidance into linked docs and keep always-loaded instruction files compact."});return{findings:n,records:s}}function Hs(e){let t=e.contextBudget;if(t===void 0)return{findings:[],records:[]};let n=[],s=[];for(let r of t.harnesses)r.detected&&(s.push({checkId:"always-loaded-budget",dimension:"maintainability",curve:"asymptoticDecay",measuredValue:r.totalLines,referenceValue:r.maxRecommendedLines}),r.status!=="ok"&&n.push({ruleId:"always-loaded-budget",severity:"info",message:`${r.harness} always-loaded context is ${String(r.totalLines)} lines; recommended maximum is ${String(r.maxRecommendedLines)}.`,file:null,line:null,harnesses:[r.harness],hint:"Keep root adapters as short indexes and move deep guidance into linked docs, skills, agents, or workflows."}));return{findings:n,records:s}}async function Ms(e){return e.files.some(n=>n.path.startsWith("agents/"))?await le(e.repoRoot,".github/agents")?{findings:[{ruleId:"no-duplicate-agent-trees",severity:"error",message:".github/agents/ duplicates root agents/; use agents/ only.",file:".github/agents",line:null,harnesses:[],hint:"Remove .github/agents/ and keep canonical agents/ at the repo root."}],records:[]}:{findings:[],records:[]}:{findings:[],records:[]}}async function Ds(e){if(!e.files.some(r=>r.path.startsWith("skills/")))return{findings:[],records:[]};let n=[],s=[".github/skills",".cursor/skills"];for(let r of s)await le(e.repoRoot,r)&&n.push({ruleId:"no-duplicate-skill-trees",severity:"error",message:`${r}/ duplicates root skills/; use skills/ only.`,file:r,line:null,harnesses:[],hint:"Remove the shadow tree and keep canonical skills/ at the repo root."});return{findings:n,records:[]}}var jc=["docs/","skills/","agents/",".cursor/",".github/",".codex/",".agent/",".claude/"],Wc=new Set(["AGENTS.md","CLAUDE.md","GEMINI.md","README.md",".github/copilot-instructions.md"]);function Gi(e){let t=e.replaceAll("\\","/").replace(/\/+$/,"");return Wc.has(t)?!0:jc.some(n=>t===n.slice(0,-1)||t.startsWith(n))}function Oe(e,t){let n=e.split(`
167
- `);for(let s=0;s<n.length;s+=1){let r=n[s];if(r!==void 0&&r.includes(t))return s+1}return null}var Uc=["",".md","/README.md","/index.md"];async function ji(e,t){for(let n of Uc){let s=`${t}${n}`.replaceAll("\\","/");if(await le(e,s))return!0}return!1}function Os(e){return/my-doc\.md|example\.spec\.|\/example\//i.test(e)}function $s(e){return e.endsWith("/")?!0:e.endsWith(".md")||e.endsWith(".mdc")}var Bc=8;async function Gs(e){let t=[];for(let n of e.files){if(!n.path.endsWith(".md")&&!n.path.endsWith(".mdc"))continue;let s=h(e,n.path);if(s===null)continue;let r=0;for(let o of ee(s)){if(He(o.href))continue;let i=Me(n.path,o.href);if(!(i===null||!Gi(i)||!$s(i)||Os(i)||await ji(e.repoRoot,i))&&(t.push({ruleId:"guidance-links-resolve",severity:"warn",message:`Broken link in ${n.path}: (${o.href}) does not resolve.`,file:n.path,line:Oe(s,o.href),harnesses:[],hint:"Fix the path or add the missing guidance file."}),r+=1,r>=Bc))break}}return{findings:t,records:[]}}import{readFile as Vc}from"node:fs/promises";import zc from"node:path";async function js(e){try{let t=await Vc(zc.join(e,"package.json"),"utf8"),n=JSON.parse(t);if(y(n)&&"scripts"in n){let{scripts:s}=n;if(y(s))return s}return null}catch{return null}}function Ws(e){return e===null?!1:Object.entries(e).some(([t,n])=>t.toLowerCase().includes("qmd")||typeof n=="string"&&n.toLowerCase().includes("qmd"))}async function Us(e){let t=N(e),n=e.files.filter(r=>r.path.startsWith("docs/ai/")).length;if(!t&&n<2)return{findings:[],records:[]};let s=await js(e.repoRoot);return Ws(s)?{findings:[],records:[]}:{findings:[{ruleId:"qmd-script-present",severity:"info",message:'package.json is missing a "qmd" (or equivalent) script for skill/doc search.',file:"package.json",line:null,harnesses:[],hint:'Add something like "qmd": "bun run ./scripts/qmd/qmd.bun.ts" and document usage in AGENTS.md.'}],records:[]}}async function Bs(e){let t=await Z(e.repoRoot);return t.hooksDirExists?t.settings?.["chat.useCustomAgentHooks"]===!0?{findings:[],records:[]}:{findings:[{ruleId:"vscode-custom-hooks",severity:"warn",message:".github/hooks/ exists but chat.useCustomAgentHooks is not true in .vscode/settings.json.",file:".vscode/settings.json",line:null,harnesses:["cursor","copilot"],hint:'Set "chat.useCustomAgentHooks": true so Cursor and Copilot load workspace hooks.'}],records:[]}:{findings:[],records:[]}}async function Vs(e){let t=await Z(e.repoRoot),n=[];return v(t,"chat.agentSkillsLocations","skills")||n.push({ruleId:"vscode-skills-location",severity:"warn",message:"chat.agentSkillsLocations should point at skills/ in .vscode/settings.json.",file:".vscode/settings.json",line:null,harnesses:["cursor","copilot"],hint:'Set "chat.agentSkillsLocations": { "skills/": true }.'}),v(t,"chat.agentFilesLocations","agents")||n.push({ruleId:"vscode-agents-location",severity:"warn",message:"chat.agentFilesLocations should point at agents/ in .vscode/settings.json.",file:".vscode/settings.json",line:null,harnesses:["cursor","copilot"],hint:'Set "chat.agentFilesLocations": { "agents/": true }.'}),{findings:n,records:[]}}function z(e,t,n,s,r){e.push(...r.findings),t.push(...r.records),r.records.length===0&&t.push({checkId:n,dimension:s,rawScore:r.findings.length>0?0:1})}function $e(e,t){return e.length===0?!0:e.some(n=>t.includes(n))}function zs(e,t,n){return $e(n,e.harnesses)?t===null||t.length===0?!0:n.some(s=>t.includes(s)):!1}function qs(e,t,n){return $e(e.harnesses,t.harnesses)?n===null||n.length===0||e.harnesses.length===0?!0:e.harnesses.some(s=>n.includes(s)):!1}function se(e){return e.trim().replaceAll(/\s+/g," ")}function Ks(e){let t=se(e);return!(t.length<20||/^#{1,6}\s/.test(t)||/^[-*]\s/.test(t)&&t.length<40||t.includes("AGENTS.md")||t.includes("docs/ai/rules.md"))}function ft(e){return e.map(t=>se(t)).filter(t=>t.length>0).join(`
168
- `)}var mt=3,qc=80;function Ys(e,t){let n=e.split(`
169
- `),s=ft(t.split(`
170
- `)),r=[],o=new Set;for(let i=0;i<=n.length-mt;i+=1){if(o.has(i))continue;let a=n.slice(i,i+mt);if(!a.every(l=>Ks(l)))continue;let c=ft(a);if(!(c.length<qc)&&s.includes(c)){r.push({startLine:i+1,lineCount:mt,sample:se(a[0]??"")}),o.add(i);for(let l=1;l<mt;l+=1)o.add(i+l)}}return r}var Js="docs/ai/rules.md";function Xs(e){let t=h(e,Js);if(t===null)return{findings:[],records:[]};let n=[];for(let s of Ue){let r=h(e,s);if(r===null)continue;let o=Ys(r,t);for(let i of o)n.push({ruleId:"adapter-content-duplication",severity:"warn",message:`${s} duplicates ${String(i.lineCount)} lines from ${Js} near line ${String(i.startLine)}.`,file:s,line:i.startLine,harnesses:[],hint:`Replace duplicated rules with a pointer to ${Js}.`})}return{findings:n,records:[]}}function b(e){return e.intelligenceLayer??null}function ge(e){return Object.entries(e.packageJson.scripts).map(([t,n])=>({name:t,command:n}))}function he(e,t,n){return ge(e).some(s=>t.test(s.name)||n.test(s.command))}function Wi(e,t){return ge(e).filter(n=>t.test(n.name)||t.test(n.command)).map(n=>n.name).toSorted()}function ye(e){return e.workflows.map(t=>t.commands.join(`
149
+ `);else{let t=[...e.findings].sort((n,r)=>{let s=Vt.indexOf(n.severity)-Vt.indexOf(r.severity);return s!==0?s:n.ruleId.localeCompare(r.ruleId)});for(let n of t)process.stdout.write(`${zt(n)}
150
+
151
+ `)}process.stdout.write(ho)}import Vl from"node:path";function gn(){return{copilot:{files:0,lines:0,bytes:0},cursor:{files:0,lines:0,bytes:0},codex:{files:0,lines:0,bytes:0},antigravity:{files:0,lines:0,bytes:0},claude:{files:0,lines:0,bytes:0},gemini:{files:0,lines:0,bytes:0}}}function hn(e,t){return e.harness!==void 0?t.includes(e.harness)?[e.harness]:[]:Jt.has(e.layer)?t:e.path.startsWith(".cursor/")?t.includes("cursor")?["cursor"]:[]:e.path.startsWith(".codex/")?t.includes("codex")?["codex"]:[]:e.path.startsWith(".agent/")?t.includes("antigravity")?["antigravity"]:[]:e.path==="AGENTS.md"||e.path.startsWith("docs/ai/")?t:[]}function Z(e,t){return t===0?0:Math.round(e/t*1e3)/10}function yn(e,t){let n={files:0,lines:0,bytes:0},r=gn(),s={files:0,lines:0,bytes:0},o={files:0,lines:0,bytes:0},i=[];for(let a of e){let c=hn(a,t);if(c.length===0)continue;o.files+=1,o.lines+=a.lines,o.bytes+=a.bytes;let l=yo(a,c),m=l?"shared":"unique";if(i.push({path:a.path,lines:a.lines,scope:m,harnesses:c}),l)n.files+=1,n.lines+=a.lines,n.bytes+=a.bytes;else{let[u]=c;u!==void 0&&(r[u].files+=1,r[u].lines+=a.lines,r[u].bytes+=a.bytes),s.files+=1,s.lines+=a.lines,s.bytes+=a.bytes}}return{totals:o,shared:{...n,percentLines:Z(n.lines,o.lines)},unique:{byHarness:r,totals:{...s,percentLines:Z(s.lines,o.lines)}},files:i}}import L from"node:path";import{access as Aa}from"node:fs/promises";async function R(e){try{return await Aa(e),!0}catch{return!1}}function Sn(e){return e===null?!1:e["chat.agentSkillsLocations"]!==void 0||e["chat.agentFilesLocations"]!==void 0||e["chat.useCustomAgentHooks"]===!0}import{readFile as Ia}from"node:fs/promises";function kn(e){if(e==="true")return!0;if(e==="false")return!1;if(e==="null")return null;if(e.startsWith('"')&&e.endsWith('"'))return e.slice(1,-1);let t=Number(e);return Number.isNaN(t)?e:t}function xn(e){let t={},n=/"([^"]+)"\s*:\s*(true|false|null|\d+(?:\.\d+)?|"[^"]*")/g;for(let[,r,s]of e.matchAll(n))r===void 0||s===void 0||(t[r]=kn(s));return Object.keys(t).length===0?null:t}function Ie(e){try{let t=JSON.parse(e);if(x(t))return t}catch{}return xn(e)}async function Rn(e){try{let t=await Ia(e,"utf8");return Ie(t)}catch{return null}}async function Ee(e){let t=new Set;await R(L.join(e,".github/copilot-instructions.md"))&&t.add("copilot"),await R(L.join(e,".github/hooks"))&&t.add("copilot");let n=await Rn(L.join(e,".vscode/settings.json"));return Sn(n)&&(t.add("cursor"),t.add("copilot")),await R(L.join(e,".cursor"))&&t.add("cursor"),await R(L.join(e,".codex/config.toml"))&&t.add("codex"),await R(L.join(e,".codex/hooks.json"))&&t.add("codex"),await R(L.join(e,".codex/agents"))&&t.add("codex"),await R(L.join(e,".agent/workflows"))&&t.add("antigravity"),await R(L.join(e,".agent/README.md"))&&t.add("antigravity"),await R(L.join(e,"CLAUDE.md"))&&t.add("claude"),await R(L.join(e,".claude/settings.json"))&&t.add("claude"),await R(L.join(e,"GEMINI.md"))&&t.add("gemini"),[...t].sort()}function ve(e){return Math.ceil(e/4)}function H(e,t){return{path:e.path,lines:e.lines,bytes:e.bytes,estimatedTokens:ve(e.bytes),reason:t}}function wn(e,t){let n=e.fileContents.get(t.path);return n===void 0?!1:/^alwaysApply:\s*true\s*$/im.test(n)||/^always_apply:\s*true\s*$/im.test(n)}function ee(e,t){return e.files.find(n=>n.path===t)??null}function bn(e,t){let n=[];if(t==="copilot"){let r=ee(e,".github/copilot-instructions.md");r!==null&&n.push(H(r,"Copilot workspace instructions are loaded by Copilot Chat."))}if(t==="cursor")for(let r of e.files)r.path.startsWith(".cursor/rules/")&&wn(e,r)&&n.push(H(r,"Cursor rule declares alwaysApply: true."));if(t==="codex"){let r=ee(e,"AGENTS.md");r!==null&&n.push(H(r,"Root AGENTS.md is the Codex repo instruction entry."));for(let s of e.files)s.path.startsWith(".codex/")&&s.layer==="adapter"&&n.push(H(s,"Codex adapter guidance under .codex/."))}if(t==="antigravity"){let r=ee(e,".agent/README.md");r!==null&&n.push(H(r,"Antigravity workspace adapter README."))}if(t==="claude"){let r=ee(e,"CLAUDE.md");r!==null&&n.push(H(r,"Claude Code root instruction file."))}if(t==="gemini"){let r=ee(e,"GEMINI.md");r!==null&&n.push(H(r,"Gemini root instruction file."))}return n.toSorted((r,s)=>r.path.localeCompare(s.path))}function Cn(e,t){if(!e.harnesses.includes(t))return{harness:t,detected:!1,files:[],totalLines:0,totalBytes:0,estimatedTokens:0,maxRecommendedLines:250,status:"ok"};let r=bn(e,t),s=r.reduce((i,a)=>i+a.lines,0),o=r.reduce((i,a)=>i+a.bytes,0);return{harness:t,detected:!0,files:r,totalLines:s,totalBytes:o,estimatedTokens:ve(o),maxRecommendedLines:250,status:s>250?"high":"ok"}}function An(e){return{harnesses:Q.map(t=>Cn(e,t)),maxRecommendedLines:250,maxRecommendedFileLines:150}}var In=["Memory","Reflection","Planning","Action","System Operation"];function En(e){let t=new Map(In.map(i=>[i,{dimension:i,findingCount:0,error:0,warn:0,info:0,ruleIds:[]}])),n=new Map(In.map(i=>[i,new Set])),r=0,s=0;for(let i of e){let a=et(i.ruleId);if(a.length===0){s+=1;continue}r+=1;for(let c of a){let l=t.get(c),m=n.get(c);l===void 0||m===void 0||(l.findingCount+=1,l[i.severity]+=1,m.has(i.ruleId)||(m.add(i.ruleId),l.ruleIds.push(i.ruleId)))}}return{byDimension:In.map(i=>t.get(i)).filter(i=>i.findingCount>0),taggedFindings:r,untaggedFindings:s}}function vn(e,t){let n={sharedLines:0,uniqueLines:0,totalLines:0,sharedPercent:0,uniquePercent:0},r={copilot:{...n},cursor:{...n},codex:{...n},antigravity:{...n},claude:{...n},gemini:{...n}};for(let s of t){let o=e.unique.byHarness[s].lines,i=e.shared.lines,a=i+o;r[s]={sharedLines:i,uniqueLines:o,totalLines:a,sharedPercent:Z(i,a),uniquePercent:Z(o,a)}}return r}function Tn(e,t){let n={error:0,warn:0,info:0};for(let r of e)r.harnesses.includes(t)&&(r.severity==="error"?n.error+=1:r.severity==="warn"?n.warn+=1:n.info+=1);return n}var bo=[{min:85,grade:"excellent"},{min:70,grade:"good"},{min:50,grade:"fair"},{min:0,grade:"poor"}],st={error:12,warn:5,info:1},Co=40;function Ln(e){let t=e.error*st.error+e.warn*st.warn+e.info*st.info;return Math.min(t,Co)}import Le from"node:path";function M(e,t){return e.files.some(n=>n.path===t)}function _n(e,t){return e.fileContents.get(t)??null}function Ea(e,t){return e.files.find(r=>r.path===t)?.lines??null}function va(e){return e.includes("AGENTS.md")||e.includes("docs/ai/rules.md")}function te(e){return e.files.some(t=>t.path.startsWith("skills/"))}function Te(e){return e.files.some(t=>t.path.startsWith("agents/"))}function Fn(e,t){return e.settings?.[t]===!0}function ot(e,t){let n=Ea(e,t);return n===null?!1:n<=W}function it(e,t){let n=_n(e,t);return n===null?!1:va(n)}function Nn(e){let t=_n(e,".agent/README.md");return t===null?!1:/\.agent\/workflows\/|workflows\//i.test(t)&&/(workflow|playbook|slash command|mission|turbo)/i.test(t)}function ne(e,t,n){let r=e.settings?.[t];if(x(r)&&Object.keys(r).some(a=>a.startsWith(n)))return!0;if(e.settingsRaw===null)return!1;let s=t.replaceAll(".",String.raw`\.`);return new RegExp(`"${s}"\\s*:\\s*\\{[^}]*"${n}[^"]*"`).test(e.settingsRaw)}var Ao={copilot:[{id:"copilot-instructions",label:"Copilot instructions file present",weight:15,run:({context:e})=>M(e,".github/copilot-instructions.md")},{id:"copilot-references-shared",label:"Copilot instructions reference shared layers",weight:15,run:({context:e})=>it(e,".github/copilot-instructions.md")},{id:"copilot-adapter-thin",label:"Copilot instructions stay thin",weight:10,run:({context:e})=>ot(e,".github/copilot-instructions.md")},{id:"copilot-skills-location",label:"chat.agentSkillsLocations points at skills/",weight:15,run:({vscode:e})=>ne(e,"chat.agentSkillsLocations","skills")},{id:"copilot-agents-location",label:"chat.agentFilesLocations points at agents/",weight:15,run:({vscode:e})=>ne(e,"chat.agentFilesLocations","agents")},{id:"copilot-hooks-enabled",label:"Custom agent hooks enabled when .github/hooks/ exists",weight:15,run:({vscode:e})=>!e.hooksDirExists||Fn(e,"chat.useCustomAgentHooks")},{id:"copilot-shared-skills",label:"Shared skills/ tree present",weight:8,run:({context:e})=>te(e)},{id:"copilot-shared-agents",label:"Shared agents/ tree present",weight:7,run:({context:e})=>Te(e)}],cursor:[{id:"cursor-rules-or-settings",label:"Cursor rules or VS Code agent settings present",weight:20,run:({context:e,vscode:t})=>e.files.some(n=>n.path.startsWith(".cursor/rules/"))||ne(t,"chat.agentSkillsLocations","skills")},{id:"cursor-skills-location",label:"chat.agentSkillsLocations points at skills/",weight:20,run:({vscode:e})=>ne(e,"chat.agentSkillsLocations","skills")},{id:"cursor-agents-location",label:"chat.agentFilesLocations points at agents/",weight:20,run:({vscode:e})=>ne(e,"chat.agentFilesLocations","agents")},{id:"cursor-hooks-enabled",label:"Custom agent hooks enabled when .github/hooks/ exists",weight:15,run:({vscode:e})=>!e.hooksDirExists||Fn(e,"chat.useCustomAgentHooks")},{id:"cursor-shared-skills",label:"Shared skills/ tree present",weight:13,run:({context:e})=>te(e)},{id:"cursor-shared-agents",label:"Shared agents/ tree present",weight:12,run:({context:e})=>Te(e)}],codex:[{id:"codex-config-surface",label:"Codex config surface present (.codex/ or nested AGENTS.md)",weight:25,run:async({context:e})=>e.files.some(t=>t.path.startsWith(".codex/"))?!0:await R(Le.join(e.repoRoot,"api/AGENTS.md"))||await R(Le.join(e.repoRoot,"react/AGENTS.md"))||await R(Le.join(e.repoRoot,"shared/AGENTS.md"))},{id:"codex-hooks",label:"Codex hooks.json present",weight:20,run:({context:e})=>R(Le.join(e.repoRoot,".codex/hooks.json"))},{id:"codex-agents-wrappers",label:"Codex agent wrappers present",weight:20,run:({context:e})=>R(Le.join(e.repoRoot,".codex/agents"))},{id:"codex-shared-entry",label:"Root AGENTS.md present",weight:20,run:({context:e})=>M(e,"AGENTS.md")},{id:"codex-shared-skills",label:"Shared skills/ tree present",weight:8,run:({context:e})=>te(e)},{id:"codex-shared-rules",label:"Canonical rules doc present",weight:7,run:({context:e})=>M(e,"docs/ai/rules.md")}],antigravity:[{id:"antigravity-workflows",label:"Workflow playbooks present (.agent/workflows/)",weight:35,run:({context:e})=>e.files.some(t=>t.path.startsWith(".agent/workflows/"))},{id:"antigravity-readme",label:".agent/README.md documents workflow layout",weight:15,run:({context:e})=>Nn(e)},{id:"antigravity-shared-entry",label:"Root AGENTS.md present",weight:20,run:({context:e})=>M(e,"AGENTS.md")},{id:"antigravity-shared-skills",label:"Shared skills/ tree present",weight:15,run:({context:e})=>te(e)},{id:"antigravity-ai-system-doc",label:"AI system layout doc present",weight:15,run:({context:e})=>M(e,"docs/ai/ai-system.md")}],claude:[{id:"claude-adapter",label:"CLAUDE.md adapter present",weight:25,run:({context:e})=>M(e,"CLAUDE.md")},{id:"claude-references-shared",label:"CLAUDE.md references shared layers",weight:25,run:({context:e})=>it(e,"CLAUDE.md")},{id:"claude-adapter-thin",label:"CLAUDE.md stays thin",weight:20,run:({context:e})=>ot(e,"CLAUDE.md")},{id:"claude-shared-skills",label:"Shared skills/ tree present",weight:15,run:({context:e})=>te(e)},{id:"claude-skills-index",label:"Skill index doc for prose discovery",weight:8,run:({context:e})=>M(e,"docs/ai/available-skills.md")},{id:"claude-shared-agents",label:"Shared agents/ tree present",weight:7,run:({context:e})=>Te(e)}],gemini:[{id:"gemini-adapter",label:"GEMINI.md adapter present",weight:30,run:({context:e})=>M(e,"GEMINI.md")},{id:"gemini-references-shared",label:"GEMINI.md references shared layers",weight:25,run:({context:e})=>it(e,"GEMINI.md")},{id:"gemini-adapter-thin",label:"GEMINI.md stays thin",weight:20,run:({context:e})=>ot(e,"GEMINI.md")},{id:"gemini-shared-skills",label:"Shared skills/ tree present",weight:15,run:({context:e})=>te(e)},{id:"gemini-shared-agents",label:"Shared agents/ tree present",weight:10,run:({context:e})=>Te(e)}]};async function Pn(e,t){let n=Ao[e],r=[];for(let s of n){let o=await s.run(t);r.push({id:s.id,label:s.label,passed:o,weight:s.weight})}return r}function Hn(e){let t=e.reduce((r,s)=>r+s.weight,0);if(t===0)return 0;let n=e.filter(r=>r.passed).reduce((r,s)=>r+s.weight,0);return Math.round(n/t*100)}function Mn(e){for(let{min:t,grade:n}of bo)if(e>=t)return n;return"poor"}async function Dn(e,t,n,r,s,o){if(!t.harnesses.includes(e))return{harness:e,detected:!1,score:null,grade:"not-detected",checks:[],findingsCount:{error:0,warn:0,info:0},loadProfile:null};let c=await Pn(e,{context:t,vscode:n,harness:e}),l=Tn(r,e),m=Hn(c),u=Ln(l),f=Math.max(0,Math.min(100,m-u));return{harness:e,detected:!0,score:f,grade:Mn(f),checks:c,findingsCount:l,loadProfile:o[e]??null}}async function On(e,t,n,r){let s=vn(r,e.harnesses),o=[];for(let i of Q){let a=await Dn(i,e,t,n,r,s);o.push(a)}return o}import{readFileSync as Ta}from"node:fs";import{dirname as La,join as Io}from"node:path";import{fileURLToPath as _a}from"node:url";var Fa=_a(import.meta.url),Eo=La(Fa);function at(e){return typeof e=="object"&&e!==null}function Na(e){return at(e)&&at(e.dimensions)&&at(e.check_weights)}function Pa(e){return at(e)}function vo(e,t){let n=JSON.parse(Ta(e,"utf8"));if(!t(n))throw new Error(`Invalid standards file: ${e}`);return n}var $n=vo(Io(Eo,"standards","weights.json"),Na),Gn=vo(Io(Eo,"standards","reference-thresholds.json"),Pa);function jn(e){return!Number.isFinite(e)||e<0?0:e<=1?e:e<=10?e/10:e<=100?e/100:1}function To(e,t){return e>=t?1:0}function Lo(e,t){return e<=t?1:e===0?0:t/e}function _o(e,t){if(t<=0)return 0;let n=e/t;return Math.max(0,Math.min(1,n))}function Wn(e,t,n){return e>=t&&e<=n?1:e<t?t===0?0:e/t:e===0?0:n/e}function B(e){if(e.curve===void 0)return jn(e.rawScore??0);let t=e.measuredValue??0,n=e.referenceValue,r=typeof n=="number"?n:0;switch(e.curve){case"binary":return To(t,r);case"asymptoticDecay":return Lo(t,r);case"ratio":return _o(t,r);case"goldilocks":{let[s,o]=Array.isArray(n)?n:[0,r];return Wn(t,s??0,o??0)}}}function Un(e,t){let n={};for(let s of Object.keys(t.dimensions))n[s]={weightedSum:0,weightSum:0,ran:!1,passedRules:0,applicableRules:0};for(let s of e){let o=n[s.dimension];if(!o)continue;o.ran=!0,o.applicableRules+=1;let i=B(s);i===1&&(o.passedRules+=1);let a=s.weight??t.check_weights[s.checkId]??1;!Number.isFinite(a)||a<=0||(o.weightedSum+=i*a,o.weightSum+=a)}let r={};for(let[s,o]of Object.entries(t.dimensions)){let i=n[s];if(!i||!i.ran){r[s]={status:"not_run",score:null,grade:"not-run",passedRules:0,applicableRules:0};continue}let a=i.weightSum>0?i.weightedSum/i.weightSum*o.max_score:0,c=Number.isFinite(a)?Math.round(a):0;r[s]={status:"run",score:c,grade:be(c),passedRules:i.passedRules,applicableRules:i.applicableRules}}return r}function Bn(e,t){let n=0,r=0;for(let[s,o]of Object.entries(t.dimensions)){let i=e[s];if(!i||i.status!=="run"||i.score===null)continue;let a=Number(o.weight);!Number.isFinite(a)||a<=0||(n+=i.score/o.max_score*a,r+=a)}return r===0?0:Math.round(n/r*100)}function Vn(e){return e.contextBudget!==void 0&&e.contextBudget.harnesses.length>0}function V(e){return e.intelligenceLayer??null}function z(e){return e.packageJson.path!==null||e.workflows.length>0||e.prTemplates.length>0}function zn(e){let t=V(e);return t!==null&&z(t)}function w(e){return e.intelligenceLayer??null}function ye(e){return Object.entries(e.packageJson.scripts).map(([t,n])=>({name:t,command:n}))}function Se(e,t,n){return ye(e).some(r=>t.test(r.name)||n.test(r.command))}function Fo(e,t){return ye(e).filter(n=>t.test(n.name)||t.test(n.command)).map(n=>n.name).toSorted()}function ke(e){return e.workflows.map(t=>t.commands.join(`
171
152
  `)).join(`
172
- `)}function C(e){return e.packageJson.path!==null||e.configs.length>0||e.workflows.length>0}function k(e,t,n,s){return{ruleId:e,severity:"info",message:t,file:s,line:null,harnesses:[],hint:n}}function Qs(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=ye(t);return/(typecheck|tsc\s+--noEmit|lint|oxlint|eslint|biome|ruff|check:md|lint:md)/i.test(n)?{findings:[],records:[]}:{findings:[k("ci-enforcement-gates","CI workflow enforcement gates were not detected.","Wire typecheck, lint, or static-analysis scripts into CI so AI-facing standards stay enforced.",t.workflows[0]?.path??t.packageJson.path)],records:[]}}function Se(e){return e.intelligenceLayer??null}function ke(e){return e.packageJson.path!==null||e.workflows.length>0||e.prTemplates.length>0}function Zs(e){let t=Se(e);return t===null||!ke(t)?{findings:[],records:[]}:t.guidanceCiWorkflows.length>0?{findings:[],records:[]}:{findings:[k("ci-guidance-lint","No CI guidance-maintenance gate was detected.","Run lint:md, check:ai-system, check:links, scan:self, or an equivalent guidance check in CI.",t.workflows[0]?.path??t.packageJson.path)],records:[]}}function er(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=ye(t);return/(npm\s+test|npm\s+run\s+test|vitest|jest|playwright|cypress|pytest|cargo\s+test|go\s+test)/i.test(n)?{findings:[],records:[]}:{findings:[k("ci-validation-gates","CI workflow validation gates were not detected.","Wire test scripts into CI so generated changes are checked by the same validation loop humans use.",t.workflows[0]?.path??t.packageJson.path)],records:[]}}function tr(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=ge(t).map(a=>`${a.name} ${a.command}`).join(`
173
- `),s=ye(t),r=/(scan:self|check:ai-system|lint:md|check:links|qmd)/i.test(n),o=t.prTemplates.length>0,i=/(scan:self|check:ai-system|lint:md|check:links)/i.test(s);return r&&(o||i)?{findings:[],records:[]}:{findings:[k("correction-loop-documented","No durable AI correction-loop signal was detected.","Document when repeated AI mistakes should become rules, docs, skills, tests, hooks, or CI checks, and wire guidance checks into routine validation.",t.prTemplates[0]??t.packageJson.path)],records:[]}}function nr(e){let t=b(e);return t===null||!C(t)?{findings:[],records:[]}:Wi(t,/(^|:)(test|e2e).*(file|focused|changed|related|unit|integration|watch|grep)|(--grep|--filter|--testNamePattern|--findRelatedTests)/i).length>0?{findings:[],records:[]}:{findings:[k("focused-test-commands-present","No focused validation command was detected.","Add targeted test scripts for common changed areas or file/grep-based workflows so agents do not over-run broad suites.",t.packageJson.path)],records:[]}}function sr(e,t){return t.lastIndex=0,t.test(e)}function rr(e){return/do not|don't|not create|instead of|removed|never use|avoid|legacy|not use|no longer|there is no|\(not `|not `\.cursor\/skills|use \/skills\/|use \/agents\//i.test(e)}function or(e,t){let n=e.split(`
174
- `);for(let s=0;s<n.length;s+=1){let r=n[s]??"";if(!rr(r)&&(t.lastIndex=0,t.test(r)))return s+1}return null}var Kc=[{id:"github-skills-shadow",pattern:/\.github\/skills\//,message:"use skills/ instead of the removed .github/skills/ path"},{id:"github-agents-shadow",pattern:/\.github\/agents\//,message:"use agents/ instead of the removed .github/agents/ path"},{id:"github-hooks-scripts",pattern:/\.github\/hooks\/scripts\//,message:"use agents/scripts/ instead of .github/hooks/scripts/"},{id:"cursor-skills-shadow",pattern:/\.cursor\/skills\//,message:"use skills/ instead of .cursor/skills/"},{id:"legacy-agent-docs",pattern:/\.agent\/(rules|codebase-map|troubleshooting)\.md/,message:"move legacy .agent docs to docs/ai/ equivalents"}];function ir(e){let t=[];for(let n of e.files){if(!n.path.endsWith(".md")&&!n.path.endsWith(".mdc"))continue;let s=h(e,n.path);if(s!==null)for(let r of Kc){let o=or(s,r.pattern);if(o!==null){t.push({ruleId:"forbidden-legacy-paths",severity:"warn",message:`${n.path} references a legacy guidance path (${r.id}).`,file:n.path,line:o,harnesses:[],hint:r.message});continue}for(let i of ee(s))sr(i.href,r.pattern)&&t.push({ruleId:"forbidden-legacy-paths",severity:"warn",message:`${n.path} links to a legacy guidance path (${r.id}).`,file:n.path,line:Oe(s,i.href),harnesses:[],hint:r.message})}}return{findings:t,records:[]}}function ar(e){let t=Se(e);return t===null||!ke(t)?{findings:[],records:[]}:t.guidanceMaintenanceScripts.length>0?{findings:[],records:[]}:{findings:[k("guidance-maintenance-script","No guidance maintenance script was detected.","Expose a script such as check:ai-system, lint:md, check:links, or scan:self so agents and CI can validate AI guidance drift.",t.packageJson.path)],records:[]}}function cr(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=t.jsdocEnforcement;return[n.customChecker,n.packageScript,n.lintRules,n.stopHook].filter(Boolean).length>=2&&n.guidance||n.customChecker&&n.lintRules?{findings:[],records:[]}:{findings:[k("jsdoc-enforcement-present","JSDoc comment enforcement was not detected.","Wire oxlint jsdoc rules, a code-comment guidance doc or skill, and a custom find-missing-jsdoc checker or Stop hook so agents get deterministic JSDoc feedback.",t.packageJson.path)],records:[]}}function lr(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=he(t,/(^|:)(lint|check:lint)(:|$)/i,/\b(eslint|oxlint|biome|ruff)\b/i),s=t.configs.some(r=>r.kind==="lint");return n||s?{findings:[],records:[]}:{findings:[k("lint-gate-present","No lint/static-analysis gate was detected.","Expose a lint script or static-analysis config so agents get deterministic correction messages.",t.packageJson.path)],records:[]}}function ur(e,t){return e.files.some(n=>n.path==="AGENTS.md"||n.path.startsWith("docs/ai/")||n.path.startsWith("skills/")||n.path.startsWith("agents/"))||t.memoryDocs.length>0||t.nestedAgentsFiles.length>0}function dr(e){let t=e.intelligenceLayer;if(t===void 0||!ur(e,t))return{findings:[],records:[]};let n=t.localContextConventions.join(`
175
- `),s=/naming|codebase-map|local-context/i.test(n),r=/comment|codebase-map|local-context/i.test(n);return t.nestedAgentsFiles.length>0||s&&r?{findings:[],records:[]}:{findings:[{ruleId:"local-context-patterns",severity:"info",message:"Local context conventions for AI-readable code were not detected.",file:"docs/ai",line:null,harnesses:[],hint:'Document naming conventions and useful "why" comment patterns, or add nested AGENTS.md files for subprojects.'}],records:[]}}function pr(e){let t=e.intelligenceLayer;if(t===void 0||t.memoryDocs.length===0)return{findings:[],records:[]};let n=t.memoryIndexes.length>0,r=!(t.packageJson.path!==null)||Object.entries(t.packageJson.scripts).some(([o,i])=>/qmd|search/i.test(o)||/qmd|search/i.test(i));return n&&r?{findings:[],records:[]}:{findings:[{ruleId:"memory-docs-indexed",severity:"info",message:"Durable memory docs should be indexed and searchable.",file:t.memoryDocs[0]??null,line:null,harnesses:[],hint:"Add a memory index such as docs/ai/codebase-map.md or docs/ai/ai-system.md, and expose a qmd/search script when package.json exists."}],records:[]}}function fr(e){let t=Se(e);return t===null||!ke(t)?{findings:[],records:[]}:t.aiHarnessPrTemplates.length>0?{findings:[],records:[]}:{findings:[k("pr-template-ai-harness-check","No PR template reminder for durable AI harness updates was detected.","Add a PR checklist item for recurring AI mistakes: update rules, docs, skills, tests, or diagnostics when needed.",t.prTemplates[0]??".github/PULL_REQUEST_TEMPLATE.md")],records:[]}}function mr(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=he(t,/(^|:)(typecheck|check:types)(:|$)/i,/\b(tsc\s+--noEmit|vue-tsc|svelte-check|mypy|pyright|cargo\s+check)\b/i),s=t.configs.some(o=>o.capabilities.includes("strict-typecheck")),r=ge(t).some(o=>/\b(mypy|pyright|cargo\s+check)\b/i.test(o.command));return n&&(s||r)?{findings:[],records:[]}:{findings:[k("strict-typecheck-present","No strict typecheck/static-analysis gate was detected.","Expose a discoverable typecheck script and strict type/static-analysis config so agents can verify structural correctness.",t.packageJson.path)],records:[]}}function gr(e){let t=b(e);if(t===null||!C(t))return{findings:[],records:[]};let n=he(t,/(^|:)(test|e2e|integration)(:|$)/i,/\b(vitest|jest|playwright|cypress|pytest|cargo\s+test|go\s+test)\b/i),s=t.configs.some(r=>r.kind==="test");return n||s?{findings:[],records:[]}:{findings:[k("test-gates-present","No validation test gate was detected.","Expose discoverable unit, integration, or E2E test scripts so agents can choose a safe verification loop.",t.packageJson.path)],records:[]}}var Yc=[Xs,ir,mr,lr,cr,gr,nr,Qs,er,tr,ar,fr,Zs,pr,dr];function Ui(e){let t=[],n=[];for(let s of Yc){let r=s(e);if(t.push(...r.findings),n.push(...r.records),r.records.length===0){let[o]=r.findings,i=o===void 0?s.name.replace(/^check/,"").replaceAll(/[A-Z]/g,a=>`-${a.toLowerCase()}`).replace(/^-/,""):o.ruleId;n.push({checkId:i,dimension:"maintainability",rawScore:r.findings.length>0?0:1})}}return{findings:t,records:n}}async function gt(e,t){let n=[],s=[],r=$i.filter(c=>qs(c,e,t)),o=await Promise.all(r.map(async c=>({rule:c,result:await c.check(e)})));for(let{rule:c,result:l}of o)z(n,s,c.id,c.dimension,l);if(zs(e,t,["cursor","copilot"])){let c=await Vs(e);n.push(...c.findings),s.push(...c.records),c.records.length===0&&(s.push({checkId:"vscode-skills-location",dimension:"harnessWiring",rawScore:c.findings.some(l=>l.ruleId==="vscode-skills-location")?0:1}),s.push({checkId:"vscode-agents-location",dimension:"harnessWiring",rawScore:c.findings.some(l=>l.ruleId==="vscode-agents-location")?0:1})),z(n,s,"vscode-custom-hooks","harnessWiring",await Bs(e))}z(n,s,"no-duplicate-skill-trees","layering",await Ds(e)),z(n,s,"no-duplicate-agent-trees","layering",await Ms(e)),z(n,s,"qmd-script-present","discoverability",await Us(e)),z(n,s,"guidance-links-resolve","maintainability",await Gs(e));let i=Ui(e);n.push(...i.findings),s.push(...i.records);let a=[...Ps(e).findings,...Hs(e).findings];if(t===null||t.length===0)n.push(...a);else{let c=a.filter(l=>l.harnesses.some(p=>t.includes(p)));n.push(...c)}return{findings:n,records:s}}function hr(e){let t=0,n=0,s=0;for(let r of e)r.severity==="error"?t+=1:r.severity==="warn"?n+=1:s+=1;return{error:t,warn:n,info:s}}import Jc from"node:path";var re="AGENTS.md",Bi=[re,"docs/ai/rules.md"],ht=["CLAUDE.md","GEMINI.md",".github/copilot-instructions.md",".agent/README.md"];function yr(e){let t=h(e,re);if(t===null)return[];let n=w["AI2-adapter-fidelity"],s=[];for(let r of ht){let o=h(e,r);if(o===null||o.trim().length===0)continue;let i=`You are checking whether a thin per-tool adapter stays faithful to the shared guidance it points at.
153
+ `)}function b(e){return e.packageJson.path!==null||e.configs.length>0||e.workflows.length>0}function qn(e){let t=w(e);return t!==null&&b(t)}var Ha=["AGENTS.md","CLAUDE.md","GEMINI.md",".github/copilot-instructions.md",".agent/README.md"],No=["IMPORTANT","CRITICAL","MANDATORY","REQUIRED","MUST NOT","MUST","NEVER","ALWAYS","SHALL","DO NOT"],Po=.03,Ho=40,Mo=[{pattern:/\byou are an? (?:expert|senior|world[- ]class|10x|highly skilled|seasoned|professional)\b/i,label:"identity framing (\u201Cyou are a/an \u2026\u201D)"},{pattern:/\bact as an?\b/i,label:"roleplay framing (\u201Cact as a \u2026\u201D)"},{pattern:/\bas an ai (?:language model|assistant)\b/i,label:"AI self-reference"},{pattern:/\bworld[- ]class\b/i,label:"superlative filler (\u201Cworld-class\u201D)"}];function ct(e){return e.replaceAll(/```[\s\S]*?```/g," ")}function Do(e){let t=e.match(/\S+/g);return t===null?0:t.length}function q(e){return Ha.filter(t=>h(e,t)!==null)}function Kn(e){return q(e).length>0}function _e(e,t){return e.files.some(n=>n.path==="AGENTS.md"||n.path.startsWith("docs/ai/")||n.path.startsWith("skills/")||n.path.startsWith("agents/"))||t.memoryDocs.length>0||t.nestedAgentsFiles.length>0}function Yn(e){let t=e.intelligenceLayer;return t===void 0?!1:_e(e,t)}function Jn(e){let t=e.intelligenceLayer;return t!==void 0&&t.memoryDocs.length>0}function Xn(e){return I(e)?!0:e.files.filter(n=>n.path.startsWith("docs/ai/")).length>=2}var Ma=new Set(["skills-index","agents-md-mentions-skills","skill-doc-deep-links"]),Da=new Set(["strict-typecheck-present","lint-gate-present","jsdoc-enforcement-present","test-gates-present","focused-test-commands-present","ci-enforcement-gates","ci-validation-gates","correction-loop-documented"]),Oa=new Set(["emphasis-keyword-density","identity-language-absent"]),$a=new Set(["adapter-context-budget","always-loaded-budget"]),Ga=new Set(["guidance-maintenance-script","pr-template-ai-harness-check","ci-guidance-lint"]);function re(e,t){return Ma.has(e)?I(t):e==="qmd-script-present"?Xn(t):e==="claude-agent-routing"?t.harnesses.includes("claude")&&S(t,"CLAUDE.md"):Da.has(e)?qn(t):Oa.has(e)?Kn(t):$a.has(e)?Vn(t):Ga.has(e)?zn(t):e==="memory-docs-indexed"?Jn(t):e==="local-context-patterns"?Yn(t):!0}var lt={"strict-typecheck-present":"repo","lint-gate-present":"repo","jsdoc-enforcement-present":"repo","test-gates-present":"repo","focused-test-commands-present":"repo","ci-enforcement-gates":"repo","ci-validation-gates":"repo","env-files-gitignored":"repo","secret-scanning-configured":"repo","actions-sha-pinned":"repo","no-pull-request-target":"repo","llm-output-schema-validated":"repo","model-interface-pinned":"repo","tool-contract-tests-present":"repo","untrusted-input-action-boundary":"repo","high-impact-action-confirmation":"repo","memory-write-provenance":"repo","shared-agents-md":"aspirational","adapter-thin-claude":"harness-core","adapter-thin-gemini":"harness-core","adapter-thin-copilot":"harness-core","adapter-points-to-shared":"harness-core","adapter-content-duplication":"harness-core","adapter-context-budget":"harness-core","always-loaded-budget":"harness-core","skills-index":"harness-core","claude-agent-routing":"harness-core","agents-md-mentions-skills":"harness-core","skill-doc-deep-links":"harness-core","skill-frontmatter":"harness-core","skill-line-count":"harness-core","agent-frontmatter":"harness-core","no-duplicate-skill-trees":"harness-core","no-duplicate-agent-trees":"harness-core","forbidden-legacy-paths":"harness-core","guidance-links-resolve":"harness-core","emphasis-keyword-density":"harness-core","identity-language-absent":"harness-core","vscode-skills-location":"harness-core","vscode-agents-location":"harness-core","vscode-custom-hooks":"harness-core","codex-hooks-valid":"harness-core","claude-hooks-valid":"harness-core","hook-stop-circuit-breaker":"harness-core","hook-no-network-exfil":"harness-core","no-dangerous-auto-approve":"harness-core","escalation-protocol-discoverability":"harness-core","agent-resource-budget-caps":"harness-core","tool-allowlist-inventory":"harness-core","shared-rules-doc":"aspirational","correction-loop-documented":"aspirational","guidance-maintenance-script":"aspirational","pr-template-ai-harness-check":"aspirational","ci-guidance-lint":"aspirational","qmd-script-present":"aspirational","local-context-patterns":"aspirational","memory-docs-indexed":"aspirational"};function Qn(e,t){let n=0,r=0,s=new Set;for(let o of e)lt[o.checkId]!=="repo"||s.has(o.checkId)||!re(o.checkId,t)||(s.add(o.checkId),r+=1,B(o)===1&&(n+=1));return r===0?null:Math.round(n/r*100)}var Oo={error:8,warn:3,info:1},$o=4,Go=1;var jo=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".json",".jsonc",".yaml",".yml",".toml"]),Wo=new Set(["package-lock.json","npm-shrinkwrap.json","yarn.lock","pnpm-lock.yaml","bun.lock","bun.lockb","cargo.lock","poetry.lock","uv.lock","composer.lock","gemfile.lock"]),Uo=512*1024,Zn=/(?:\.(?:test|spec)\.[a-z]+$|(?:^|\/)(?:__tests__|__fixtures__|fixtures|test|tests)\/)/i,Bo=/\b(?:claude|gpt|chatgpt|gemini|mistral|codestral|llama|grok|deepseek|command|qwen|o1|o3|o4)[a-z0-9.]*(?:-[a-z0-9.]+)*-latest\b/i,Fe=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py"]),Vo=/\b(?:anthropic|openai|mistralai|cohere|generativeai|langchain|chat\.completions|messages\.create|responses\.create|generateobject|generatetext|streamtext|generate_content)\b/i,zo=/\.choices\s*\[|tool_?calls?\b|function_?call|\.content\s*\[|\bJSON\.parse\s*\(|\bjson\.loads\s*\(/i,qo=/\b(?:zod|valibot|superstruct|typebox|class-validator|ajv|yup|pydantic|basemodel|model_validate|parse_obj|typeadapter|jsonschema|marshmallow)\b|\.safeparse\s*\(|\bz\.object\s*\(/i,ut=/\btools\s*:\s*\[|\btool_choice\s*[:=]|\bfunction_?declarations\s*[:=]|\b(?:defineTool|zodFunction|registerTool)\s*\(|\bserver\.tool\s*\(|\binput_?schema\s*[:=]|^\s*@tool\b/im,Ko=/\btool\b|\barguments?\b|\bfunction_?call|\bparameters?\b|\binput_?schema\b/i,Yo=/\btothrow\b|\.rejects\b|\bassert_?raises\b|pytest\.raises|\binvalid\b|\bmalformed\b|\bmissing\b|\bsafeparse\b|\berrors?\b/i;var Jo=/\bask\s+(?:the\s+)?(?:user|human|maintainer)\b|\bask\s+for\s+clarif|\brequest\s+clarification|\bseek\s+clarification|\bclarifying\s+questions?|\bwhen\s+(?:in\s+doubt|unsure|uncertain)\b|\bstop\s+and\s+ask\b|\bask\s+before\s+(?:assum|guess|proceed)|\bescalat(?:e|ion)\b|\b(?:ambiguous|unclear|contradictory|conflicting|incomplete)\b[^.\n]{0,40}\b(?:ask|clarif|escalat|confirm)/i,Xo=/\bmax[_\s-]?(?:iterations?|steps?|turns?|calls?|requests?|attempts?|retries|tokens?|cost|budget)\b|\bmax_calls_per_minute\b|\bcurrency_limits?\b|\brate[_\s-]?limit|\bbudget[_\s-]?(?:cap|limit)|\biteration[_\s-]?(?:cap|limit)|\bcost[_\s-]?(?:cap|limit)/i,Qo=/\blanggraph\b|\bcrewai\b|\bautogen\b|\bAgentExecutor\b|\bcreateReactAgent\b|@modelcontextprotocol|\bmcp\.server\b|\bserver\.tool\s*\(/i;function se(e){return[...e.fileContents.values()].join(`
154
+ `)}function Ne(e){return(e.boundary?.sourceFiles??[]).map(t=>t.content).join(`
155
+ `)}var Zo=/\bmcpservers\b|\.mcp\.json\b|\bmcp__|modelcontextprotocol|\bmcp\s+servers?\b/i,ei=/\ballow[\s_-]?list\b|\bmcpservers\b|allowed[_\s-]?tools|permitted[_\s-]?tools|"allow"\s*:|pinned\s+(?:tool|server|mcp)/i,ti=/\bmem0\b|memory\.(?:add|write|store|save|upsert)\b|vector[\s_-]?(?:store|db|database)|\bupsert\s*\(|\bembeddings?\b|\bpinecone\b|\bweaviate\b|\bchroma(?:db)?\b|\bqdrant\b|persistent\s+memory/i,ni=/\bprovenance\b|\bquarantin|\buntrusted\b|\btaint(?:ed)?\b|trust[\s_-]?(?:level|tag|boundary)|source[\s_-]?tag|re-?validat/i,ri=/\bfetch\s*\(|\bwebfetch\b|\baxios\b|requests?\.get\b|\burllib\b|\bhttpx\b|\bscrap(?:e|ing)\b|\bcrawl|retriev(?:e|al)|web[\s_-]?search/i,si=/\bexec(?:Sync)?\s*\(|child_process|\bspawn\s*\(|\bsubprocess\b|os\.system|writeFileSync|\bfs\.write|\bunlink\s*\(|\brm\s+-rf\b/i,oi=/saniti[sz]|\bvalidat|\ballow[\s_-]?list\b|\bescape\b|\bconfirm|\bapproval\b|\bguard(?:rail)?\b/i,ii=/force[\s_-]?push|push\s+--force|\brm\s+-rf\b|delete\s+from\b|\.delete\s*\(|\bdestroy\s*\(|\bstripe\b|\bpayment|\bcharge\s*\(|wire\s+transfer|send[_\s-]?email|\bsendmail\b|\bdeploy\b|drop\s+table/i,ai=/human[\s_-]?in[\s_-]?the[\s_-]?loop|\bconfirm(?:ation)?\b|\bapproval\b|\bescalat|requires?\s+(?:approval|confirmation)|dry[\s_-]?run|are\s+you\s+sure/i;function Pe(e){return e.files.some(n=>n.layer==="agents")?!0:(e.boundary?.sourceFiles??[]).some(n=>ut.test(n.content)||Qo.test(n.content))}var ci=new Set(["shared-agents-md","shared-rules-doc","adapter-thin-claude","adapter-thin-gemini","adapter-thin-copilot","adapter-points-to-shared","adapter-context-budget","always-loaded-budget","skills-index","claude-agent-routing","agents-md-mentions-skills","skill-doc-deep-links","skill-frontmatter","skill-line-count","agent-frontmatter","vscode-skills-location","vscode-agents-location","vscode-custom-hooks","codex-hooks-valid","claude-hooks-valid","correction-loop-documented","guidance-maintenance-script","pr-template-ai-harness-check","ci-guidance-lint","qmd-script-present","local-context-patterns","memory-docs-indexed"]),li=new Set(["strict-typecheck-present","lint-gate-present","jsdoc-enforcement-present","test-gates-present","focused-test-commands-present","ci-enforcement-gates","ci-validation-gates","secret-scanning-configured"]),ja=["CLAUDE.md","GEMINI.md",".github/copilot-instructions.md"];function er(e,t){if(!re(e,t))return!1;switch(e){case"skill-frontmatter":case"skill-line-count":return I(t);case"agent-frontmatter":return Pe(t);case"adapter-thin-claude":return S(t,"CLAUDE.md");case"adapter-thin-gemini":return S(t,"GEMINI.md");case"adapter-thin-copilot":return S(t,".github/copilot-instructions.md");case"adapter-points-to-shared":return ja.some(n=>S(t,n));case"claude-hooks-valid":return S(t,".claude/settings.json");case"codex-hooks-valid":return S(t,".codex/hooks.json");case"vscode-skills-location":case"vscode-agents-location":case"vscode-custom-hooks":return S(t,".vscode/settings.json");default:return!0}}var ui={error:3,warn:2,info:1};function tr(e,t,n){let r=Qn(e,n),s=e.some(u=>u.checkId==="shared-agents-md"&&B(u)===1),o=n.harnesses.length===0&&!s?"implicit-only":"scored",i=new Map;for(let u of t){if(lt[u.ruleId]!=="harness-core")continue;let f=i.get(u.ruleId);(f===void 0||ui[u.severity]>ui[f])&&i.set(u.ruleId,u.severity)}let a=[],c=new Set;for(let u of e){let f=ci.has(u.checkId),d=li.has(u.checkId);if(!f&&!d||c.has(u.checkId)||(c.add(u.checkId),f&&(i.has(u.checkId)||!er(u.checkId,n)))||d&&!re(u.checkId,n))continue;let y=Math.round((f?2:Go)*B(u)*10)/10;y>0&&a.push({signal:u.checkId,points:y})}let l=[];for(let[u,f]of i)l.push({signal:u,points:-Oo[f]});for(let u of n.contextBudget?.harnesses??[])u.status==="high"&&l.push({signal:`context-budget-high:${u.harness}`,points:-$o});let m=a.reduce((u,f)=>u+f.points,0)+l.reduce((u,f)=>u+f.points,0);return{status:o,score:Math.round(m),repoReadiness:r,contributions:a,liabilities:l}}var dt=new Set(["deep","session"]);function nr(e){let t=0,n=0,r=0,s=[];for(let[o,i]of Object.entries(e))dt.has(o)||(r+=1,i.status==="run"?(n+=1,t+=i.applicableRules):s.push(o));return{rulesApplied:t,dimensionsRun:n,dimensionsTotal:r,level:n===r?"full":"partial",dimensionsNotRun:s}}function rr(e){for(let[t,n]of Object.entries(e))if(dt.has(t)&&n.status==="run")return"core+extended";return"core"}function sr(e,t,n,r,s){if(n.totals.lines>0){let u=typeof Gn.sharing_target_percent=="number"?Gn.sharing_target_percent:65;e.push({checkId:"sharing-percent",dimension:"sharing",curve:"ratio",measuredValue:n.shared.percentLines,referenceValue:u})}let o=r.filter(u=>u.detected&&u.score!==null);if(o.length>0){let u=o.reduce((f,d)=>f+(d.score??0),0)/o.length;e.push({checkId:"harness-optimization-avg",dimension:"harnessWiring",curve:"ratio",measuredValue:u,referenceValue:100})}let i=Un(e,$n),a=Bn(i,$n),c=rr(i),l=nr(i),m=tr(e,t,s);return{profile:"meta-harness",total_score:a,score_scope:c,coverage:l,harnessNet:m,dimensions:i}}import{readFile as Ka}from"node:fs/promises";import ar from"node:path";import{readdir as Ua}from"node:fs/promises";import Ba from"node:path";async function pt(e){let t=[".md",".mdc"];function n(o){return t.some(i=>o.endsWith(i))}let r=[],s=[];try{s=await Ua(e,{withFileTypes:!0})}catch{return r}for(let o of s){if(o.isSymbolicLink())continue;let i=Ba.join(e,o.name);o.isDirectory()?r.push(...await pt(i)):o.isFile()&&n(i)&&r.push(i)}return r}import{readFile as Va,stat as za}from"node:fs/promises";import qa from"node:path";function or(e){return e.length===0?0:e.split(`
156
+ `).length}async function ir(e,t,n,r){let s=qa.join(e,t);try{if(!(await za(s)).isFile())return null;let i=await Va(s,"utf8"),a=or(i),c={path:t,layer:n,lines:a,bytes:Buffer.byteLength(i,"utf8")};return r!==void 0&&(c.harness=r),c}catch{return null}}var Ya=["AGENTS.md","docs/ai/rules.md","docs/ai/ai-system.md","docs/ai/available-skills.md","docs/ai/hooks.md"],Ja=[{path:"CLAUDE.md",harness:"claude"},{path:"GEMINI.md",harness:"gemini"},{path:".github/copilot-instructions.md",harness:"copilot"},{path:".agent/README.md",harness:"antigravity"}],Xa=[{dir:"skills",layer:"skills"},{dir:"agents",layer:"agents"},{dir:".cursor/rules",layer:"adapter",harness:"cursor"},{dir:".agent/workflows",layer:"workflows",harness:"antigravity"},{dir:".codex",layer:"adapter",harness:"codex"},{dir:"docs/ai",layer:"shared"}];async function He(e){let t=[],n=new Map,r=new Set;async function s(o,i,a){let c=o.replaceAll("\\","/");if(r.has(c))return;let l=await ir(e,c,i,a);if(l===null)return;r.add(c),t.push(l);let m=ar.join(e,c);try{let u=await Ka(m,"utf8");n.set(c,u)}catch{}}for(let o of Ya)await s(o,"shared");for(let o of Ja)await s(o.path,"adapter",o.harness);for(let{dir:o,layer:i,harness:a}of Xa){let c=ar.join(e,o),l=await pt(c);for(let m of l){let u=ar.relative(e,m).replaceAll("\\","/");await s(u,i,a)}}return t.sort((o,i)=>o.path.localeCompare(i.path)),{files:t,contents:n}}import{readFile as Qa}from"node:fs/promises";import di from"node:path";import{fileURLToPath as Za}from"node:url";function cr(e){return typeof e=="object"&&e!==null&&"version"in e&&typeof e.version=="string"}async function lr(){let e=di.resolve(di.dirname(Za(import.meta.url)),"../package.json"),t=await Qa(e,"utf8"),n=JSON.parse(t);if(!cr(n))throw new Error("package.json is missing a string version field");return{version:n.version}}var pi=null;function mi(){return pi??=lr(),pi}import{extname as sc}from"node:path";import{readdir as ec}from"node:fs/promises";import Ri from"node:path";var fi=new Set([".git","node_modules","dist","coverage"]),gi=[/^tsconfig(?:\..+)?\.json$/],hi=[/^eslint\.config\.[cm]?[jt]s$/,/^\.eslintrc(?:\..+)?$/,/^\.oxlintrc(?:\..+)?$/,/^biome\.jsonc?$/,/^ruff\.toml$/,/^\.ruff\.toml$/],yi=[/^\.prettierrc(?:\..+)?$/,/^\.markdownlint(?:rc)?(?:\..+)?$/],Si=[/^vitest\.config\.[cm]?[jt]s$/,/^jest\.config\.[cm]?[jt]s$/,/^playwright\.config\.[cm]?[jt]s$/,/^cypress\.config\.[cm]?[jt]s$/],ki=[/^package\.json$/,/^pyproject\.toml$/,/^Cargo\.toml$/,/^go\.mod$/],ur=/(scan:self|check:ai-system|check:md|lint:md|check:links|qmd|markdownlint|textlint|remark|cspell|paniolo-scan)/i,xi=/(correction loop|intelligence layer|diagnostic rule|rules catalog|canonical rules|paired skill|guidance hygiene|adapters stayed thin|json output keys are stable)/i;async function xe(e,t=""){let n=Ri.join(e,t),r=[];try{r=await ec(n,{withFileTypes:!0})}catch{return[]}let s=[];for(let o of r){if(o.isSymbolicLink()||fi.has(o.name))continue;let i=Ri.join(t,o.name).replaceAll("\\","/");o.isDirectory()?s.push(...await xe(e,i)):o.isFile()&&s.push(i)}return s}import wi from"node:path";function dr(e){let t=wi.basename(e).toLowerCase();return Wo.has(t)?!1:jo.has(wi.extname(t))}import{readFile as tc,stat as nc}from"node:fs/promises";import rc from"node:path";async function pr(e,t){let n=rc.join(e,t);try{return(await nc(n)).size>Uo?null:{path:t,content:await tc(n,"utf8")}}catch{return null}}async function mr(e){let n=(await xe(e)).filter(o=>dr(o)),s=(await Promise.all(n.map(o=>pr(e,o)))).filter(o=>o!==null);return{sourceFiles:s.filter(o=>!Zn.test(o.path)).toSorted((o,i)=>o.path.localeCompare(i.path)),testFiles:s.filter(o=>Zn.test(o.path)&&Fe.has(sc(o.path))).toSorted((o,i)=>o.path.localeCompare(i.path))}}async function fr(e){let{sourceFiles:t,testFiles:n}=await mr(e);return{sourceFiles:t,testFiles:n}}import ac from"node:path";import{readFile as oc,stat as ic}from"node:fs/promises";import bi from"node:path";function Ci(e){return e.length===0?0:e.split(`
157
+ `).length}async function Ai(e,t){try{return(await ic(bi.join(e,t))).isFile()}catch{return!1}}async function D(e,t){try{return await oc(bi.join(e,t),"utf8")}catch{return null}}function mt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Re(e,t){return t.some(n=>n.test(e))}function Ii(e){return/^\.github\/workflows\/.+\.ya?ml$/.test(e)}function Ei(e){return e===".github/PULL_REQUEST_TEMPLATE.md"||/^\.github\/PULL_REQUEST_TEMPLATE\/.+\.md$/.test(e)||/^docs\/pull_request_template\.md$/i.test(e)}function ft(e,t){return ur.test(`${e}
158
+ ${t}`)}function gt(e){return ur.test(e.commands.join(`
159
+ `))}function vi(e){return xi.test(e)}function Ti(e){let t=e.toLowerCase();return t.includes("naming")||t.includes("comment")||t.includes("local-context")||t.includes("codebase-map")}function gr(e){let t=ac.posix.basename(e);return Re(t,gi)?{path:e,kind:"typecheck",capabilities:["typecheck"]}:Re(t,hi)?{path:e,kind:"lint",capabilities:["lint"]}:Re(t,yi)?{path:e,kind:"format",capabilities:["format"]}:Re(t,Si)?{path:e,kind:"test",capabilities:["test"]}:Re(t,ki)?{path:e,kind:"manifest",capabilities:["project-manifest"]}:null}function hr(e){let t=e.toLowerCase();return t==="docs/architecture.md"||t==="docs/overview.md"||t==="docs/meta-harness.md"||t==="docs/ai/codebase-map.md"||t==="docs/ai/ai-system.md"||t.includes("/adr")||t.includes("architecture")||t.includes("codebase-map")||t.includes("design")}function yr(e){let t=e.toLowerCase();return t==="docs/ai/codebase-map.md"||t==="docs/ai/ai-system.md"||t==="docs/overview.md"||t.endsWith("/adr/index.md")||t.endsWith("/adrs/index.md")}function Me(e){if(!mt(e))return{};let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&(t[n]=r);return t}function Sr(e){if(e===null)return{path:null,scripts:{},dependencies:[],devDependencies:[]};try{let t=JSON.parse(e);if(!mt(t))return{path:"package.json",scripts:{},dependencies:[],devDependencies:[]};let n=Me(t.scripts),r=Object.keys(Me(t.dependencies)).toSorted(),s=Object.keys(Me(t.devDependencies)).toSorted();return{path:"package.json",scripts:n,dependencies:r,devDependencies:s}}catch{return{path:"package.json",scripts:{},dependencies:[],devDependencies:[]}}}import{stat as cc}from"node:fs/promises";import lc from"node:path";async function K(e,t,n,r,s){let o=lc.join(e,t),i=await cc(o),a=await D(e,t),c={path:t,kind:n,layer:r,capabilities:s,bytes:i.size};return a!==null&&(c.lines=Ci(a)),c}function kr(e){let t=[],n=/^\s*-\s*run:\s*(.+)$/,r=/^\s*-\s*run:\s*[>|]/,s=!1;for(let o of e.split(/\r?\n/)){let i=o.match(n);if(i!==null){t.push(i[1]?.trim()??""),s=!1;continue}if(r.test(o)){s=!0;continue}s&&(/^\s{6,}\S/.test(o)?t.push(o.trim()):/^\s*-\s/.test(o)&&(s=!1))}return t.filter(o=>o.length>0)}async function xr(e,t){let n=await D(e,t);return n===null?null:{path:t,commands:kr(n),content:n}}function ht(e){let t=Object.keys(e.packageJson.scripts),n=t.filter(i=>/(^|:)(typecheck|lint|format|check)(:|$)/i.test(i)),r=t.filter(i=>/(^|:)(test|e2e)(:|$)/i.test(i)),s=t.filter(i=>ft(i,e.packageJson.scripts[i]??"")),o=e.workflows.filter(gt).map(i=>i.path).toSorted();return{surfaces:e.surfaces,enforcement:{scripts:n.toSorted(),configs:e.configs.filter(i=>i.kind==="typecheck"||i.kind==="lint").map(i=>i.path).toSorted(),ciWorkflows:e.workflows.filter(i=>/(typecheck|lint|format|check)/i.test(i.commands.join(`
160
+ `))).map(i=>i.path).toSorted()},validation:{scripts:r.toSorted(),configs:e.configs.filter(i=>i.kind==="test").map(i=>i.path).toSorted(),ciWorkflows:e.workflows.filter(i=>/(npm test|npm run test|vitest|jest|playwright|cypress)/i.test(i.commands.join(`
161
+ `))).map(i=>i.path).toSorted()},memory:{docs:e.memoryDocs.toSorted(),indexes:e.memoryIndexes.toSorted()},localContext:{conventions:e.localContextConventions.toSorted(),nestedAgentsFiles:e.nestedAgentsFiles.toSorted()},correctionLoop:{scripts:s.toSorted(),prTemplates:e.prTemplates.toSorted(),ciWorkflows:o,maintenanceScripts:e.guidanceMaintenanceScripts.toSorted(),prTemplateChecks:e.aiHarnessPrTemplates.toSorted(),guidanceCiWorkflows:o}}}async function Rr(e){let t=await xe(e),n=Sr(await D(e,"package.json")),r=[],s=[],o=[],i=[],a=[],c=[],l=[],m=[],u=[],f={customChecker:!1,packageScript:!1,lintRules:!1,stopHook:!1,guidance:!1};f.packageScript=Object.entries(n.scripts).some(([d,g])=>/(^|:)(lint:jsdoc|check:jsdoc)(:|$)/i.test(d)||/find-missing-jsdoc|check-jsdoc-files/i.test(g));for(let d of t){let g=gr(d);if(g!==null){let y={...g},E=await D(e,d);g.kind==="typecheck"&&E!==null&&/"strict"\s*:\s*true/.test(E)&&(y.capabilities=[...g.capabilities,"strict-typecheck"]),g.kind==="lint"&&E!==null&&/jsdoc\/require-(returns|param)/i.test(E)&&(f.lintRules=!0),r.push(y),u.push(await K(e,d,"enforcement","config",y.capabilities))}if(Ii(d)){let y=await xr(e,d);if(y!==null){s.push(y);let E=await K(e,d,"workflow","automation",["ci-workflow"]);u.push(E)}}if(Ei(d)){o.push(d);let y=await D(e,d);y!==null&&vi(y)&&i.push(d);let E=await K(e,d,"automation","pull-request",["pr-template"]);u.push(E)}if(d.endsWith(".md")&&hr(d)&&(a.push(d),yr(d)&&c.push(d),u.push(await K(e,d,"memory","docs",["memory"]))),d.endsWith(".md")&&Ti(d)&&l.push(d),(d==="scripts/find-missing-jsdoc/analyzeFile.ts"||d==="scripts/find-missing-jsdoc/check-jsdoc-files.bun.ts")&&(f.customChecker=!0),(d==="docs/ai/code-comment-best-practices.md"||d==="skills/code-comment-best-practices/SKILL.md")&&(f.guidance=!0),d.startsWith(".github/hooks/")&&d.endsWith(".json")){let y=await D(e,d);y!==null&&/lint-on-stop|find-missing-jsdoc|jsdoc/i.test(y)&&(f.stopHook=!0)}if(d.endsWith("/AGENTS.md")){m.push(d);let y=await K(e,d,"local-context","nested-entry",["nested-agents-md"]);u.push(y)}}return n.path!==null&&await Ai(e,n.path)&&u.push(await K(e,n.path,"automation","project",["package-scripts"])),{packageJson:n,configs:r.toSorted((d,g)=>d.path.localeCompare(g.path)),workflows:s.toSorted((d,g)=>d.path.localeCompare(g.path)),prTemplates:o,guidanceMaintenanceScripts:Object.entries(n.scripts).filter(([d,g])=>ft(d,g)).map(([d])=>d).toSorted(),aiHarnessPrTemplates:i.toSorted(),guidanceCiWorkflows:s.filter(d=>gt(d)).map(d=>d.path).toSorted(),memoryDocs:a,memoryIndexes:c.toSorted(),localContextConventions:l.toSorted(),nestedAgentsFiles:m,surfaces:u.toSorted((d,g)=>d.path.localeCompare(g.path)),jsdocEnforcement:f}}import fc from"node:path";import{readdir as uc}from"node:fs/promises";import dc from"node:path";async function wr(e,t){let n=[];try{n=await uc(dc.join(e,t),{withFileTypes:!0})}catch{return[]}return n.filter(r=>r.isFile()).map(r=>`${t}/${r.name}`)}import{readFile as pc,stat as mc}from"node:fs/promises";import Di from"node:path";var Li=[".claude/settings.json",".claude/settings.local.json"],_i=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local",".env.test"],Fi=[".gitleaks.toml",".github/gitleaks.toml",".github/secret_scanning.yml",".github/secret_scanning.yaml"],Ni=[".pre-commit-config.yaml",".pre-commit-config.yml"],Pi=["config/worker-vars.list","config/env-secrets.dev.list","config/env-secrets.staging.list","config/env-secrets.production.list","scripts/env/run-with-env/run-with-env.bun.ts"],Hi=/gitleaks|trufflehog|detect-secrets|ggshield/i,Mi=/(?:\.\/)?(?:[\w.-]+\/)+[\w.-]+\.(?:tsx?|mts|cts|mjs|cjs|js|sh|bash|py)/g;async function F(e,t){try{return await pc(Di.join(e,t),"utf8")}catch{return null}}async function O(e,t){try{return(await mc(Di.join(e,t))).isFile()}catch{return!1}}function Y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function yt(e){try{return{ok:!0,value:JSON.parse(e)}}catch{return{ok:!1,value:null}}}function Oi(e){let{permissions:t}=e;return!Y(t)||!Array.isArray(t.allow)?[]:t.allow.filter(n=>typeof n=="string")}function $i(e){let{permissions:t}=e;return!Y(t)||typeof t.defaultMode!="string"?null:t.defaultMode}function St(e){let t=e.match(Mi)??[];return[...new Set(t.map(n=>n.replace(/^\.\//,"")))]}async function Gi(e,t,n){let r=await O(e,n),s=r?await F(e,n):null;return{reference:{source:t,path:n,exists:r},content:s}}async function br(e,t){for(let n of await wr(e,".claude/hooks")){let r=await F(e,n);r!==null&&t.push({source:n,path:n,isStop:/stop/i.test(fc.posix.basename(n)),content:r})}}async function Cr(e){for(let t of Pi)if(await O(e,t))return!0;return!1}function Ar(e){let t=e.hooks;if(t===void 0)return{hooks:[],malformed:!1};if(!Y(t))return{hooks:[],malformed:!0};let n=[],r=!1;for(let[s,o]of Object.entries(t)){if(!Array.isArray(o)){r=!0;continue}for(let i of o){if(!Y(i)||!Array.isArray(i.hooks)){r=!0;continue}for(let a of i.hooks){if(!Y(a)||typeof a.command!="string"){r=!0;continue}n.push({event:s,command:a.command})}}}return{hooks:n,malformed:r}}async function Ir(e,t){let n=await F(e,t);if(n===null)return null;let{ok:r,value:s}=yt(n);if(!r||!Y(s))return{path:t,valid:!1,allow:[],defaultMode:null,hooks:[],hooksMalformed:!1};let{hooks:o,malformed:i}=Ar(s);return{path:t,valid:!0,allow:Oi(s),defaultMode:$i(s),hooks:o,hooksMalformed:i}}async function Er(e){let t=".codex/hooks.json",n=await F(e,t);if(n===null)return null;let{ok:r,value:s}=yt(n);if(!r)return{path:t,valid:!1,referencedScripts:[]};let o=[];for(let i of St(JSON.stringify(s))){let a=await O(e,i);o.push({source:t,path:i,exists:a})}return{path:t,valid:!0,referencedScripts:o}}async function vr(e){let t=[];for(let n of _i)await O(e,n)&&t.push(n);return t}async function Tr(e,t){let n=[],r=[],s=t.flatMap(o=>o.hooks.map(i=>({surface:o,hook:i})));for(let{surface:o,hook:i}of s){let a=`${o.path} (${i.event} hook)`,c=[i.command];for(let l of St(i.command)){let{reference:m,content:u}=await Gi(e,a,l);r.push(m),u!==null&&c.push(u)}n.push({source:a,path:null,isStop:i.event==="Stop",content:c.join(`
162
+ `)})}return{hookScripts:n,referencedClaudeScripts:r}}async function Lr(e){let t=[];for(let n of Fi)await O(e,n)&&t.push(n);for(let n of Ni){let r=await F(e,n);r!==null&&Hi.test(r)&&t.push(n)}return t}async function De(e){let t=[];for(let l of Li){let m=await Ir(e,l);m!==null&&t.push(m)}let{hookScripts:n,referencedClaudeScripts:r}=await Tr(e,t);await br(e,n);let[s,o,i,a,c]=await Promise.all([Er(e),F(e,".gitignore"),vr(e),Lr(e),Cr(e)]);return{claudeSettings:t,referencedClaudeScripts:r,hookScripts:n,codexHooks:s,gitignore:o,envFilesPresent:i,secretScanningFiles:a,usesKeyringSecrets:c}}import{readFile as gc,stat as hc}from"node:fs/promises";import ji from"node:path";async function oe(e){let t=ji.join(e,".github/hooks"),n=!1;try{n=(await hc(t)).isDirectory()}catch{n=!1}let r=ji.join(e,".vscode/settings.json"),s=null,o=null;try{let i=await gc(r,"utf8");o=i,s=Ie(i)}catch{s=null,o=null}return{settings:s,settingsRaw:o,hooksDirExists:n}}function Oe(e,t,n,r){return{ruleId:e,severity:"warn",message:`${t} has ${String(n)} lines; keep root adapters thin (max ${String(W)}).`,file:t,line:null,harnesses:[r],hint:"Move detailed guidance to docs/ai/ and skills/; keep the adapter as a pointer."}}import{extname as Wi}from"node:path";function _r(e){let t=[],n=e.split(`
163
+ `);for(let r=0;r<n.length;r+=1){let s=Bo.exec(n[r]??"");s!==null&&t.push({line:r+1,alias:s[0]})}return t}function Fr(e){if(!Vo.test(e)||qo.test(e))return null;let t=e.split(`
164
+ `);for(let n=0;n<t.length;n+=1)if(zo.test(t[n]??""))return n+1;return null}var $e={findings:[],records:[]},yc={id:"model-interface-pinned",title:"Model interface pinned",severity:"warn",category:"reliability",dimension:"guardrails",harnesses:[],check(e){let t=e.boundary?.sourceFiles;if(t===void 0)return $e;let n=[];for(let r of t)for(let{line:s,alias:o}of _r(r.content))n.push({ruleId:"model-interface-pinned",severity:"warn",message:`${r.path} references the floating model alias "${o}"; the model behind a "latest" tag can change without notice.`,file:r.path,line:s,harnesses:[],hint:"Pin a dated/versioned model snapshot (e.g. a -YYYYMMDD or explicit-version id) so model upgrades are a deliberate, reviewable change."});return{findings:n,records:[]}}},Sc={id:"llm-output-schema-validated",title:"LLM output schema-validated",severity:"warn",category:"reliability",dimension:"guardrails",harnesses:[],check(e){let t=e.boundary?.sourceFiles;if(t===void 0)return $e;let n=[];for(let r of t){if(!Fe.has(Wi(r.path)))continue;let s=Fr(r.content);s!==null&&n.push({ruleId:"llm-output-schema-validated",severity:"warn",message:`${r.path} consumes LLM/tool output (line ${String(s)}) without a schema validator; a shape change in the model response surfaces as a downstream type error.`,file:r.path,line:s,harnesses:[],hint:"Validate the parsed response against a Zod/Pydantic/JSON-Schema schema at the boundary before reading its fields."})}return{findings:n,records:[]}}},kc={id:"tool-contract-tests-present",title:"Tool contract tests present",severity:"info",category:"reliability",dimension:"guardrails",harnesses:[],check(e){let{boundary:t}=e;if(t===void 0)return $e;let n=t.sourceFiles.find(s=>Fe.has(Wi(s.path))&&ut.test(s.content));return n===void 0||t.testFiles.some(s=>Ko.test(s.content)&&Yo.test(s.content))?$e:{findings:[{ruleId:"tool-contract-tests-present",severity:"info",message:`${n.path} declares model-callable tools, but no test exercises tool-call argument validation or error responses \u2014 only happy-path behavior is covered.`,file:n.path,line:null,harnesses:[],hint:"Add tests that feed malformed or missing tool-call arguments and assert the error path, per declared tool."}],records:[]}}},Ui=[yc,Sc,kc];function Nr(e){let t=[];for(let n of Ke){if(!S(e,n))continue;let r=h(e,n);r===null||so(r)||t.push({ruleId:"adapter-points-to-shared",severity:"warn",message:`${n} should reference AGENTS.md and docs/ai/rules.md.`,file:n,line:null,harnesses:[],hint:"Keep adapters thin; point at shared layers instead of duplicating rules."})}return{findings:t,records:[]}}function Pr(e){let t=[];for(let n of ge(e,"agents/")){if(!n.endsWith(".agent.md"))continue;let r=h(e,n);if(r===null)continue;let s=Ye(r);if(s===null){t.push({ruleId:"agent-frontmatter",severity:"error",message:`${n} is missing YAML frontmatter.`,file:n,line:null,harnesses:[]});continue}me(s,"name")||t.push({ruleId:"agent-frontmatter",severity:"error",message:`${n} is missing a name field in frontmatter.`,file:n,line:null,harnesses:[]}),me(s,"description")||t.push({ruleId:"agent-frontmatter",severity:"error",message:`${n} is missing a description field in frontmatter.`,file:n,line:null,harnesses:[]})}return{findings:t,records:[]}}function Hr(e){if(!I(e)||!S(e,"AGENTS.md"))return{findings:[],records:[]};let t=h(e,"AGENTS.md");return t!==null&&Je(t)?{findings:[],records:[]}:{findings:[{ruleId:"agents-md-mentions-skills",severity:"info",message:"AGENTS.md should point at docs/ai/available-skills.md or the qmd search workflow.",file:"AGENTS.md",line:null,harnesses:[],hint:"Document how agents discover skills (index doc or npm run qmd -- search)."}],records:[]}}function Mr(e){if(!e.harnesses.includes("claude")||!S(e,"CLAUDE.md"))return{findings:[],records:[]};let t=h(e,"CLAUDE.md");return t!==null&&Xe(t)?{findings:[],records:[]}:{findings:[{ruleId:"claude-agent-routing",severity:"info",message:"CLAUDE.md should include an Agent Routing table pointing at agents/*.agent.md.",file:"CLAUDE.md",line:null,harnesses:["claude"],hint:"Add a markdown table mapping task types to shared agents/*.agent.md files."}],records:[]}}var Bi=/!?\[([^\]]*)\]\(([^)]+)\)/g;function ie(e){let t=[],n=Bi.exec(e);for(;n!==null;){let[r]=n;r.startsWith("!")||t.push({label:n[1]??"",href:(n[2]??"").trim()}),n=Bi.exec(e)}return t}var xc=new Set(["url","path","href","link","..."]);function Ge(e){return e.length===0||xc.has(e.toLowerCase())||e.startsWith("http://")||e.startsWith("https://")||e.startsWith("mailto:")||e.startsWith("tel:")?!0:(e.split("#")[0]??"").length===0}function Dr(e){let t=e.replaceAll("\\","/").split("/"),n=[];for(let r of t)if(!(r===""||r===".")){if(r===".."){n.pop();continue}n.push(r)}return n.join("/")}function je(e,t){let n=(t.split("#")[0]??"").trim();if(n.length===0)return null;let r=n;try{r=decodeURIComponent(n)}catch{r=n}if(r.startsWith("/"))return r.slice(1).replaceAll("\\","/");let s=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"",o=s.length===0?r:`${s}/${r}`;return Dr(o)}function Or(e){return!e.endsWith(".md")&&!e.endsWith(".mdc")?!1:e.startsWith("docs/")||e.includes("/docs/")}function $r(e,t){for(let n of ie(t)){if(Ge(n.href))continue;let r=je(e,n.href);if(r!==null&&Or(r))return!0}return!1}var Rc=50;function Gr(e){let t=[];for(let n of e.files){if(!n.path.startsWith("skills/")||!n.path.endsWith("SKILL.md")||(n.lines??0)<=Rc)continue;let r=h(e,n.path);r===null||$r(n.path,r)||t.push({ruleId:"skill-doc-deep-links",severity:"info",message:`${n.path} does not deep-link into a durable doc under docs/.`,file:n.path,line:null,harnesses:[],hint:"Pair the skill with a docs/ reference and link it (for example a **Details:** link to a docs/ page) instead of inlining all detail."})}return{findings:t,records:[]}}function jr(e){let t=[];for(let n of ge(e,"skills/")){if(!n.endsWith("/SKILL.md")&&!n.endsWith("SKILL.md"))continue;let r=h(e,n);if(r===null)continue;let s=Ye(r);if(s===null){t.push({ruleId:"skill-frontmatter",severity:"error",message:`${n} is missing YAML frontmatter.`,file:n,line:null,harnesses:[]});continue}me(s,"name")||t.push({ruleId:"skill-frontmatter",severity:"error",message:`${n} is missing a name field in frontmatter.`,file:n,line:null,harnesses:[]}),me(s,"description")||t.push({ruleId:"skill-frontmatter",severity:"error",message:`${n} is missing a description field in frontmatter.`,file:n,line:null,harnesses:[]})}return{findings:t,records:[]}}function Wr(e){let t=[];for(let n of ge(e,"skills/")){if(!n.endsWith("SKILL.md"))continue;let r=U(e,n);r!==null&&r>Lt&&t.push({ruleId:"skill-line-count",severity:"warn",message:`${n} has ${String(r)} lines; keep skills under ${String(Lt)}.`,file:n,line:null,harnesses:[],hint:"Move detail to docs/; keep SKILL.md as a pointer."})}return{findings:t,records:[]}}var Vi="docs/ai/available-skills.md";function Ur(e){return I(e)?S(e,Vi)?{findings:[],records:[]}:{findings:[{ruleId:"skills-index",severity:"info",message:`${Vi} is missing; add a skill slug index when using skills/.`,file:null,line:null,harnesses:[],hint:"List each skills/<slug>/ folder so agents can pick a minimal skill set."}],records:[]}:{findings:[],records:[]}}function Br(e){let t=0;for(let n of No){let r=e.match(new RegExp(`\\b${n}\\b`,"g"));r!==null&&(t+=r.length)}return t}function Vr(e){let t=[];for(let n of q(e)){let r=h(e,n);if(r===null)continue;let s=ct(r),o=Do(s);if(o<Ho)continue;let i=Br(s),a=i/o;if(a<=Po)continue;let c=(a*100).toFixed(1);t.push({ruleId:"emphasis-keyword-density",severity:"info",message:`${n} uses ${String(i)} all-caps emphasis keyword(s) across ${String(o)} words (${c}%); emphasis loses force when overused.`,file:n,line:null,harnesses:[],hint:"Reserve IMPORTANT/MUST/NEVER for the few rules that truly need them; rewrite the rest as plain, action-oriented instructions."})}return{findings:t,records:[]}}function zr(e){let t=[];for(let n of q(e)){let r=h(e,n);if(r===null)continue;let s=ct(r),o=Mo.filter(({pattern:i})=>i.test(s)).map(({label:i})=>i);o.length!==0&&t.push({ruleId:"identity-language-absent",severity:"info",message:`${n} contains identity/roleplay filler: ${o.join(", ")}.`,file:n,line:null,harnesses:[],hint:"Drop identity framing; state what to do, not who to be. Action-oriented rules outperform persona prompts."})}return{findings:t,records:[]}}var zi=[{id:"emphasis-keyword-density",title:"Emphasis-keyword density",severity:"info",category:"instruction-quality",dimension:"maintainability",harnesses:[],check:Vr},{id:"identity-language-absent",title:"No identity-language filler",severity:"info",category:"instruction-quality",dimension:"maintainability",harnesses:[],check:zr}];function kt(e,t,n,r){return{findings:[{ruleId:e,severity:t,message:n,file:null,line:null,harnesses:[],hint:r}],records:[]}}var $={findings:[],records:[]},wc={id:"escalation-protocol-discoverability",title:"Escalation protocol discoverable",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=q(e);return t.length===0||Jo.test(se(e))?$:{findings:[{ruleId:"escalation-protocol-discoverability",severity:"info",message:"No discoverable escalation protocol in guidance: nothing documents when or how the agent should ask for clarification on missing, ambiguous, or contradictory specs.",file:t[0]??null,line:null,harnesses:[],hint:"Document an 'ask before guessing' protocol in AGENTS.md or the rules doc \u2014 the epistemic counterpart to action confirmation (HiL-Bench's 53-82pp finding)."}],records:[]}}},bc={id:"agent-resource-budget-caps",title:"Agent resource budget caps",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){if(!Pe(e))return $;let t=(e.boundary?.sourceFiles??[]).map(n=>n.content).join(`
165
+ `);return Xo.test(`${se(e)}
166
+ ${t}`)?$:{findings:[{ruleId:"agent-resource-budget-caps",severity:"info",message:"An agent/tool surface is present but no resource caps are declared (max iterations, cost, or rate limit); an unbounded loop is a resource-drain (R7) risk.",file:null,line:null,harnesses:[],hint:"Declare max-iteration, max-cost, or rate-limit caps, mirroring OAP's max_calls_per_minute / currency_limits."}],records:[]}}},Cc={id:"tool-allowlist-inventory",title:"Tool allowlist inventory",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=`${se(e)}
167
+ ${Ne(e)}`;return!Zo.test(t)||ei.test(t)?$:kt("tool-allowlist-inventory","info","Repo references MCP/tool servers but declares no explicit, pinned tool allowlist; arbitrary tool discovery widens the attack surface (R1/R3).","Declare an explicit allowlist of tools/MCP servers with pinned versions instead of allowing arbitrary discovery.")}},Ac={id:"untrusted-input-action-boundary",title:"Untrusted input / action boundary",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=Ne(e);if(!(ri.test(t)&&si.test(t)))return $;let r=`${se(e)}
168
+ ${t}`;return oi.test(r)?$:kt("untrusted-input-action-boundary","warn","Source ingests external/untrusted content and takes actions (exec, file write) with no sanitization, validation, or confirmation in evidence (R2/R3 unconstrained data flow).","Sanitize, allow-list, or confirm untrusted content before it reaches shell exec, file writes, or tool dispatch.")}},Ic={id:"memory-write-provenance",title:"Memory write provenance",severity:"info",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=`${se(e)}
169
+ ${Ne(e)}`;return!ti.test(t)||ni.test(t)?$:kt("memory-write-provenance","info","Repo writes to persistent agent memory but shows no provenance/trust tagging or re-validation; memory writes from untrusted sources can later be read as trusted (R6).","Tag or quarantine memory writes derived from untrusted sources and re-validate them before trusted reads.")}},Ec={id:"high-impact-action-confirmation",title:"High-impact action confirmation",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=Ne(e);if(!ii.test(t))return $;let n=`${se(e)}
170
+ ${t}`;return ai.test(n)?$:kt("high-impact-action-confirmation","warn","Source performs high-impact actions (deletion, payment, force-push, deploy, external send) with no human-in-the-loop confirmation or escalation in evidence (R6/R7).","Gate high-impact actions behind an explicit confirmation/escalation step, not just allow/deny (OWASP LLM06).")}},qi=[wc,bc,Cc,Ac,Ic,Ec];var vc=/\b(?:curl|wget|ncat|telnet|scp)\b|\bnc\s|Invoke-WebRequest|\bfetch\s*\(|\baxios\b|http\.request|urllib|requests\.(?:get|post|put|patch)/i,Tc=/localhost|127\.0\.0\.1|0\.0\.0\.0|::1/i;function qr(e){let t=[];for(let n of e.content.split(/\r?\n/)){let r=n.trim();vc.test(r)&&!Tc.test(r)&&t.push(r)}return t}var Lc=new Set(["Bash","Write","Edit","MultiEdit","NotebookEdit"]);function Kr(e){let t=e.trim();if(t==="")return!1;if(t==="*")return!0;if(t.startsWith("mcp__"))return t.includes("*");let n=t.match(/^([A-Za-z_][\w-]*)(?:\((.*)\))?$/);if(n===null)return!1;let[,r="",s]=n;if(!Lc.has(r))return!1;if(s===void 0)return!0;let o=s.trim();return o===""||o==="*"||o===":*"}var _c=/^[0-9a-f]{40}$/i;function Yr(e){let t=new Set,n=/^\s*-?\s*uses:\s*['"]?([^'"\s#]+)['"]?/gm;for(let r of e.matchAll(n)){let[,s]=r;if(s===void 0||s.startsWith("./")||s.startsWith("docker://"))continue;let o=s.includes("@")?s.slice(s.lastIndexOf("@")+1):"";_c.test(o)||t.add(s)}return[...t]}var G={findings:[],records:[]},Fc=new Set(["bypassPermissions","acceptEdits"]),Nc="stop_hook_active";function ae(e){return e.security??null}var Pc={id:"no-dangerous-auto-approve",title:"No dangerous auto-approve permissions",severity:"error",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ae(e);if(t===null)return G;let n=[];for(let r of t.claudeSettings){r.defaultMode!==null&&Fc.has(r.defaultMode)&&n.push({ruleId:"no-dangerous-auto-approve",severity:"error",message:`${r.path} sets permissions.defaultMode "${r.defaultMode}", auto-approving actions without prompting.`,file:r.path,line:null,harnesses:["claude"],hint:'Use "default" or "plan" mode and allow-list specific commands instead of bypassing prompts.'});for(let s of r.allow.filter(Kr))n.push({ruleId:"no-dangerous-auto-approve",severity:"error",message:`${r.path} auto-approves "${s}", a blanket grant over a dangerous capability.`,file:r.path,line:null,harnesses:["claude"],hint:"Scope allow-list entries to specific commands, e.g. Bash(npm run test:*) instead of Bash(*)."})}return{findings:n,records:[]}}},Hc={id:"hook-no-network-exfil",title:"Hooks do not exfiltrate over the network",severity:"error",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ae(e);if(t===null)return G;let n=[];for(let r of t.hookScripts){let[s]=qr(r);s!==void 0&&n.push({ruleId:"hook-no-network-exfil",severity:"error",message:`${r.source} makes a network call (\`${s.slice(0,80)}\`); hooks run automatically and can exfiltrate repo data.`,file:r.path,line:null,harnesses:[],hint:"Remove the network call or restrict it to localhost; move outbound calls into explicit, reviewable steps."})}return{findings:n,records:[]}}},Mc={id:"hook-stop-circuit-breaker",title:"Stop hooks guard against infinite loops",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ae(e);if(t===null)return G;let n=[];for(let r of t.hookScripts)!r.isStop||r.content.includes(Nc)||n.push({ruleId:"hook-stop-circuit-breaker",severity:"warn",message:`${r.source} is a Stop hook that never checks stop_hook_active; a blocking Stop hook can loop the agent indefinitely.`,file:r.path,line:null,harnesses:[],hint:"Read stop_hook_active from the hook input and exit without blocking when it is true."});return{findings:n,records:[]}}},Dc={id:"env-files-gitignored",title:"Env files are gitignored",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ae(e);if(t===null)return G;let r=t.gitignore!==null&&/^\s*!?[*.]*\.env(?:[.*]|\b|\/)?/m.test(t.gitignore)?[]:t.envFilesPresent;if(r.length===0)return G;let s=t.usesKeyringSecrets?"This repo uses keyring-managed secrets; delete the committed .env file rather than relying on it.":"Gitignore `.env`/`.env.*`, or move secrets to an OS keyring (the run-with-env pattern) so they never touch disk.";return{findings:[{ruleId:"env-files-gitignored",severity:"warn",message:`${r.join(", ")} present but not gitignored; secrets risk being committed.`,file:r[0]??null,line:null,harnesses:[],hint:s}],records:[]}}};function Oc(e){return e.some(t=>/gitleaks|trufflehog|detect-secrets|ggshield/i.test(t.content))}var $c={id:"secret-scanning-configured",title:"Secret scanning is configured",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=ae(e);if(t===null)return G;let n=e.intelligenceLayer?.workflows??[];return t.secretScanningFiles.length>0||Oc(n)?G:{findings:[{ruleId:"secret-scanning-configured",severity:"warn",message:"No secret-scanning configuration found (gitleaks, trufflehog, detect-secrets, or a pre-commit secret hook).",file:null,line:null,harnesses:[],hint:"Add a gitleaks/trufflehog CI step or a detect-secrets pre-commit hook so committed credentials are caught."}],records:[]}}},Gc={id:"no-pull-request-target",title:"No risky pull_request_target workflows",severity:"error",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=e.intelligenceLayer?.workflows??[],n=[];for(let r of t)/\bpull_request_target\b/.test(r.content)&&n.push({ruleId:"no-pull-request-target",severity:"error",message:`${r.path} triggers on pull_request_target, which runs with repo secrets against untrusted PR code.`,file:r.path,line:null,harnesses:[],hint:"Prefer pull_request; if pull_request_target is required, never check out or execute PR head code with secrets in scope."});return{findings:n,records:[]}}},jc={id:"actions-sha-pinned",title:"GitHub Actions pinned to commit SHAs",severity:"warn",category:"security",dimension:"guardrails",harnesses:[],check(e){let t=e.intelligenceLayer?.workflows??[],n=[];for(let r of t){let s=Yr(r.content);s.length!==0&&n.push({ruleId:"actions-sha-pinned",severity:"warn",message:`${r.path} uses actions pinned to mutable refs: ${s.join(", ")}.`,file:r.path,line:null,harnesses:[],hint:"Pin each action to a full 40-character commit SHA (e.g. actions/checkout@<sha>) to prevent tag-hijack supply-chain attacks."})}return{findings:n,records:[]}}},Wc={id:"claude-hooks-valid",title:"Claude hooks config is valid",severity:"error",category:"hooks",dimension:"guardrails",harnesses:["claude"],check(e){let t=ae(e);if(t===null)return G;let n=[];for(let r of t.claudeSettings){if(!r.valid){n.push({ruleId:"claude-hooks-valid",severity:"error",message:`${r.path} is not valid JSON.`,file:r.path,line:null,harnesses:["claude"],hint:"Fix the JSON syntax; an unparseable settings file disables every configured hook silently."});continue}r.hooksMalformed&&n.push({ruleId:"claude-hooks-valid",severity:"error",message:`${r.path} has a malformed hooks block; entries must be { matcher?, hooks: [{ type, command }] }.`,file:r.path,line:null,harnesses:["claude"],hint:"Match the documented hooks schema so the configured commands actually run."})}for(let r of t.referencedClaudeScripts.filter(s=>!s.exists))n.push({ruleId:"claude-hooks-valid",severity:"error",message:`${r.source} references missing script ${r.path}.`,file:r.path,line:null,harnesses:["claude"],hint:"Create the script or fix the path; a missing hook command fails open and skips the check."});return{findings:n,records:[]}}},Uc={id:"codex-hooks-valid",title:"Codex hooks config is valid",severity:"error",category:"hooks",dimension:"guardrails",harnesses:["codex"],check(e){let t=ae(e);if(t===null||t.codexHooks===null)return G;let n=t.codexHooks,r=[];n.valid||r.push({ruleId:"codex-hooks-valid",severity:"error",message:`${n.path} is not valid JSON.`,file:n.path,line:null,harnesses:["codex"],hint:"Fix the JSON syntax so the configured codex hooks load."});for(let s of n.referencedScripts.filter(o=>!o.exists))r.push({ruleId:"codex-hooks-valid",severity:"error",message:`${n.path} references missing script ${s.path}.`,file:s.path,line:null,harnesses:["codex"],hint:"Create the script or fix the path so the hook command runs."});return{findings:r,records:[]}}},Ki=[Pc,Hc,Mc,Dc,$c,Gc,jc,Wc,Uc];var Bc={id:"shared-agents-md",title:"Shared AGENTS.md entry point",severity:"warn",category:"structure",dimension:"layering",harnesses:[],check(e){return S(e,"AGENTS.md")?{findings:[],records:[]}:{findings:[{ruleId:"shared-agents-md",severity:"warn",message:"AGENTS.md is missing.",file:null,line:null,harnesses:[],hint:"Add AGENTS.md as the repo-wide AI entry point with workflow, safety, and pointers to canonical docs."}],records:[]}}},Vc={id:"shared-rules-doc",title:"Canonical rules doc",severity:"warn",category:"structure",dimension:"layering",harnesses:[],check(e){return S(e,"docs/ai/rules.md")?{findings:[],records:[]}:{findings:[{ruleId:"shared-rules-doc",severity:"warn",message:"docs/ai/rules.md is missing.",file:null,line:null,harnesses:[],hint:"Add docs/ai/rules.md as the canonical coding-rules reference."}],records:[]}}},zc={id:"adapter-thin-claude",title:"Thin CLAUDE.md adapter",severity:"warn",category:"adapter",dimension:"layering",harnesses:["claude"],check(e){let t=U(e,"CLAUDE.md");return t===null||t<=W?{findings:[],records:[]}:{findings:[Oe("adapter-thin-claude","CLAUDE.md",t,"claude")],records:[]}}},qc={id:"adapter-thin-gemini",title:"Thin GEMINI.md adapter",severity:"warn",category:"adapter",dimension:"layering",harnesses:["gemini"],check(e){let t=U(e,"GEMINI.md");return t===null||t<=W?{findings:[],records:[]}:{findings:[Oe("adapter-thin-gemini","GEMINI.md",t,"gemini")],records:[]}}},Kc={id:"adapter-thin-copilot",title:"Thin Copilot instructions",severity:"warn",category:"adapter",dimension:"layering",harnesses:["copilot"],check(e){let t=".github/copilot-instructions.md",n=U(e,t);return n===null||n<=W?{findings:[],records:[]}:{findings:[Oe("adapter-thin-copilot",t,n,"copilot")],records:[]}}},Yc={id:"adapter-points-to-shared",title:"Adapters reference shared layers",severity:"warn",category:"adapter",dimension:"layering",harnesses:[],check:Nr},Jc={id:"skill-frontmatter",title:"Skill frontmatter",severity:"error",category:"skills",dimension:"maintainability",harnesses:[],check:jr},Xc={id:"skill-line-count",title:"Skill line budget",severity:"warn",category:"skills",dimension:"maintainability",harnesses:[],check:Wr},Qc={id:"agent-frontmatter",title:"Agent frontmatter",severity:"error",category:"agents",dimension:"maintainability",harnesses:[],check:Pr},Zc={id:"skills-index",title:"Skill slug index",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:[],check:Ur},el={id:"claude-agent-routing",title:"Claude agent routing table",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:["claude"],check:Mr},tl={id:"agents-md-mentions-skills",title:"AGENTS.md skill discovery",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:[],check:Hr},nl={id:"skill-doc-deep-links",title:"Skills deep-link into docs",severity:"info",category:"discoverability",dimension:"discoverability",harnesses:[],check:Gr},Yi=[Bc,Vc,zc,qc,Kc,Yc,Jc,Xc,Qc,Zc,el,tl,nl,...zi,...Ki,...Ui,...qi];function Jr(e){let t=e.contextBudget;if(t===void 0)return{findings:[],records:[]};let n=[],r=[];for(let s of t.harnesses)if(s.detected)for(let o of s.files)r.push({checkId:"adapter-context-budget",dimension:"maintainability",curve:"asymptoticDecay",measuredValue:o.lines,referenceValue:t.maxRecommendedFileLines}),!(o.lines<=t.maxRecommendedFileLines)&&n.push({ruleId:"adapter-context-budget",severity:"info",message:`${o.path} contributes ${String(o.lines)} always-loaded lines for ${s.harness}; recommended maximum per file is ${String(t.maxRecommendedFileLines)}.`,file:o.path,line:null,harnesses:[s.harness],hint:"Split detailed guidance into linked docs and keep always-loaded instruction files compact."});return{findings:n,records:r}}function Xr(e){let t=e.contextBudget;if(t===void 0)return{findings:[],records:[]};let n=[],r=[];for(let s of t.harnesses)s.detected&&(r.push({checkId:"always-loaded-budget",dimension:"maintainability",curve:"asymptoticDecay",measuredValue:s.totalLines,referenceValue:s.maxRecommendedLines}),s.status!=="ok"&&n.push({ruleId:"always-loaded-budget",severity:"info",message:`${s.harness} always-loaded context is ${String(s.totalLines)} lines; recommended maximum is ${String(s.maxRecommendedLines)}.`,file:null,line:null,harnesses:[s.harness],hint:"Keep root adapters as short indexes and move deep guidance into linked docs, skills, agents, or workflows."}));return{findings:n,records:r}}async function Qr(e){return e.files.some(n=>n.path.startsWith("agents/"))?await fe(e.repoRoot,".github/agents")?{findings:[{ruleId:"no-duplicate-agent-trees",severity:"error",message:".github/agents/ duplicates root agents/; use agents/ only.",file:".github/agents",line:null,harnesses:[],hint:"Remove .github/agents/ and keep canonical agents/ at the repo root."}],records:[]}:{findings:[],records:[]}:{findings:[],records:[]}}async function Zr(e){if(!e.files.some(s=>s.path.startsWith("skills/")))return{findings:[],records:[]};let n=[],r=[".github/skills",".cursor/skills"];for(let s of r)await fe(e.repoRoot,s)&&n.push({ruleId:"no-duplicate-skill-trees",severity:"error",message:`${s}/ duplicates root skills/; use skills/ only.`,file:s,line:null,harnesses:[],hint:"Remove the shadow tree and keep canonical skills/ at the repo root."});return{findings:n,records:[]}}var rl=["docs/","skills/","agents/",".cursor/",".github/",".codex/",".agent/",".claude/"],sl=new Set(["AGENTS.md","CLAUDE.md","GEMINI.md","README.md",".github/copilot-instructions.md"]);function Ji(e){let t=e.replaceAll("\\","/").replace(/\/+$/,"");return sl.has(t)?!0:rl.some(n=>t===n.slice(0,-1)||t.startsWith(n))}function We(e,t){let n=e.split(`
171
+ `);for(let r=0;r<n.length;r+=1){let s=n[r];if(s!==void 0&&s.includes(t))return r+1}return null}var ol=["",".md","/README.md","/index.md"];async function Xi(e,t){for(let n of ol){let r=`${t}${n}`.replaceAll("\\","/");if(await fe(e,r))return!0}return!1}function es(e){return/my-doc\.md|example\.spec\.|\/example\//i.test(e)}function ts(e){return e.endsWith("/")?!0:e.endsWith(".md")||e.endsWith(".mdc")}var il=8;async function ns(e){let t=[];for(let n of e.files){if(!n.path.endsWith(".md")&&!n.path.endsWith(".mdc"))continue;let r=h(e,n.path);if(r===null)continue;let s=0;for(let o of ie(r)){if(Ge(o.href))continue;let i=je(n.path,o.href);if(!(i===null||!Ji(i)||!ts(i)||es(i)||await Xi(e.repoRoot,i))&&(t.push({ruleId:"guidance-links-resolve",severity:"warn",message:`Broken link in ${n.path}: (${o.href}) does not resolve.`,file:n.path,line:We(r,o.href),harnesses:[],hint:"Fix the path or add the missing guidance file."}),s+=1,s>=il))break}}return{findings:t,records:[]}}import{readFile as al}from"node:fs/promises";import cl from"node:path";async function rs(e){try{let t=await al(cl.join(e,"package.json"),"utf8"),n=JSON.parse(t);if(x(n)&&"scripts"in n){let{scripts:r}=n;if(x(r))return r}return null}catch{return null}}function ss(e){return e===null?!1:Object.entries(e).some(([t,n])=>t.toLowerCase().includes("qmd")||typeof n=="string"&&n.toLowerCase().includes("qmd"))}async function os(e){let t=I(e),n=e.files.filter(s=>s.path.startsWith("docs/ai/")).length;if(!t&&n<2)return{findings:[],records:[]};let r=await rs(e.repoRoot);return ss(r)?{findings:[],records:[]}:{findings:[{ruleId:"qmd-script-present",severity:"info",message:'package.json is missing a "qmd" (or equivalent) script for skill/doc search.',file:"package.json",line:null,harnesses:[],hint:'Add something like "qmd": "bun run ./scripts/qmd/qmd.bun.ts" and document usage in AGENTS.md.'}],records:[]}}async function is(e){let t=await oe(e.repoRoot);return t.hooksDirExists?t.settings?.["chat.useCustomAgentHooks"]===!0?{findings:[],records:[]}:{findings:[{ruleId:"vscode-custom-hooks",severity:"warn",message:".github/hooks/ exists but chat.useCustomAgentHooks is not true in .vscode/settings.json.",file:".vscode/settings.json",line:null,harnesses:["cursor","copilot"],hint:'Set "chat.useCustomAgentHooks": true so Cursor and Copilot load workspace hooks.'}],records:[]}:{findings:[],records:[]}}async function as(e){let t=await oe(e.repoRoot),n=[];return T(t,"chat.agentSkillsLocations","skills")||n.push({ruleId:"vscode-skills-location",severity:"warn",message:"chat.agentSkillsLocations should point at skills/ in .vscode/settings.json.",file:".vscode/settings.json",line:null,harnesses:["cursor","copilot"],hint:'Set "chat.agentSkillsLocations": { "skills/": true }.'}),T(t,"chat.agentFilesLocations","agents")||n.push({ruleId:"vscode-agents-location",severity:"warn",message:"chat.agentFilesLocations should point at agents/ in .vscode/settings.json.",file:".vscode/settings.json",line:null,harnesses:["cursor","copilot"],hint:'Set "chat.agentFilesLocations": { "agents/": true }.'}),{findings:n,records:[]}}function J(e,t,n,r,s){e.push(...s.findings),t.push(...s.records),s.records.length===0&&t.push({checkId:n,dimension:r,rawScore:s.findings.length>0?0:1})}function Ue(e,t){return e.length===0?!0:e.some(n=>t.includes(n))}function cs(e,t,n){return Ue(n,e.harnesses)?t===null||t.length===0?!0:n.some(r=>t.includes(r)):!1}function ls(e,t,n){return Ue(e.harnesses,t.harnesses)?n===null||n.length===0||e.harnesses.length===0?!0:e.harnesses.some(r=>n.includes(r)):!1}function ce(e){return e.trim().replaceAll(/\s+/g," ")}function us(e){let t=ce(e);return!(t.length<20||/^#{1,6}\s/.test(t)||/^[-*]\s/.test(t)&&t.length<40||t.includes("AGENTS.md")||t.includes("docs/ai/rules.md"))}function xt(e){return e.map(t=>ce(t)).filter(t=>t.length>0).join(`
172
+ `)}var Rt=3,ll=80;function ds(e,t){let n=e.split(`
173
+ `),r=xt(t.split(`
174
+ `)),s=[],o=new Set;for(let i=0;i<=n.length-Rt;i+=1){if(o.has(i))continue;let a=n.slice(i,i+Rt);if(!a.every(l=>us(l)))continue;let c=xt(a);if(!(c.length<ll)&&r.includes(c)){s.push({startLine:i+1,lineCount:Rt,sample:ce(a[0]??"")}),o.add(i);for(let l=1;l<Rt;l+=1)o.add(i+l)}}return s}var ps="docs/ai/rules.md";function ms(e){let t=h(e,ps);if(t===null)return{findings:[],records:[]};let n=[];for(let r of Ke){let s=h(e,r);if(s===null)continue;let o=ds(s,t);for(let i of o)n.push({ruleId:"adapter-content-duplication",severity:"warn",message:`${r} duplicates ${String(i.lineCount)} lines from ${ps} near line ${String(i.startLine)}.`,file:r,line:i.startLine,harnesses:[],hint:`Replace duplicated rules with a pointer to ${ps}.`})}return{findings:n,records:[]}}function k(e,t,n,r){return{ruleId:e,severity:"info",message:t,file:r,line:null,harnesses:[],hint:n}}function fs(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=ke(t);return/(typecheck|tsc\s+--noEmit|lint|oxlint|eslint|biome|ruff|check:md|lint:md)/i.test(n)?{findings:[],records:[]}:{findings:[k("ci-enforcement-gates","CI workflow enforcement gates were not detected.","Wire typecheck, lint, or static-analysis scripts into CI so AI-facing standards stay enforced.",t.workflows[0]?.path??t.packageJson.path)],records:[]}}function gs(e){let t=V(e);return t===null||!z(t)?{findings:[],records:[]}:t.guidanceCiWorkflows.length>0?{findings:[],records:[]}:{findings:[k("ci-guidance-lint","No CI guidance-maintenance gate was detected.","Run lint:md, check:ai-system, check:links, scan:self, or an equivalent guidance check in CI.",t.workflows[0]?.path??t.packageJson.path)],records:[]}}function hs(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=ke(t);return/(npm\s+test|npm\s+run\s+test|vitest|jest|playwright|cypress|pytest|cargo\s+test|go\s+test)/i.test(n)?{findings:[],records:[]}:{findings:[k("ci-validation-gates","CI workflow validation gates were not detected.","Wire test scripts into CI so generated changes are checked by the same validation loop humans use.",t.workflows[0]?.path??t.packageJson.path)],records:[]}}function ys(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=ye(t).map(a=>`${a.name} ${a.command}`).join(`
175
+ `),r=ke(t),s=/(scan:self|check:ai-system|lint:md|check:links|qmd)/i.test(n),o=t.prTemplates.length>0,i=/(scan:self|check:ai-system|lint:md|check:links)/i.test(r);return s&&(o||i)?{findings:[],records:[]}:{findings:[k("correction-loop-documented","No durable AI correction-loop signal was detected.","Document when repeated AI mistakes should become rules, docs, skills, tests, hooks, or CI checks, and wire guidance checks into routine validation.",t.prTemplates[0]??t.packageJson.path)],records:[]}}function Ss(e){let t=w(e);return t===null||!b(t)?{findings:[],records:[]}:Fo(t,/(^|:)(test|e2e).*(file|focused|changed|related|unit|integration|watch|grep)|(--grep|--filter|--testNamePattern|--findRelatedTests)/i).length>0?{findings:[],records:[]}:{findings:[k("focused-test-commands-present","No focused validation command was detected.","Add targeted test scripts for common changed areas or file/grep-based workflows so agents do not over-run broad suites.",t.packageJson.path)],records:[]}}function ks(e,t){return t.lastIndex=0,t.test(e)}function xs(e){return/do not|don't|not create|instead of|removed|never use|avoid|legacy|not use|no longer|there is no|\(not `|not `\.cursor\/skills|use \/skills\/|use \/agents\//i.test(e)}function Rs(e,t){let n=e.split(`
176
+ `);for(let r=0;r<n.length;r+=1){let s=n[r]??"";if(!xs(s)&&(t.lastIndex=0,t.test(s)))return r+1}return null}var ul=[{id:"github-skills-shadow",pattern:/\.github\/skills\//,message:"use skills/ instead of the removed .github/skills/ path"},{id:"github-agents-shadow",pattern:/\.github\/agents\//,message:"use agents/ instead of the removed .github/agents/ path"},{id:"github-hooks-scripts",pattern:/\.github\/hooks\/scripts\//,message:"use agents/scripts/ instead of .github/hooks/scripts/"},{id:"cursor-skills-shadow",pattern:/\.cursor\/skills\//,message:"use skills/ instead of .cursor/skills/"},{id:"legacy-agent-docs",pattern:/\.agent\/(rules|codebase-map|troubleshooting)\.md/,message:"move legacy .agent docs to docs/ai/ equivalents"}];function ws(e){let t=[];for(let n of e.files){if(!n.path.endsWith(".md")&&!n.path.endsWith(".mdc"))continue;let r=h(e,n.path);if(r!==null)for(let s of ul){let o=Rs(r,s.pattern);if(o!==null){t.push({ruleId:"forbidden-legacy-paths",severity:"warn",message:`${n.path} references a legacy guidance path (${s.id}).`,file:n.path,line:o,harnesses:[],hint:s.message});continue}for(let i of ie(r))ks(i.href,s.pattern)&&t.push({ruleId:"forbidden-legacy-paths",severity:"warn",message:`${n.path} links to a legacy guidance path (${s.id}).`,file:n.path,line:We(r,i.href),harnesses:[],hint:s.message})}}return{findings:t,records:[]}}function bs(e){let t=V(e);return t===null||!z(t)?{findings:[],records:[]}:t.guidanceMaintenanceScripts.length>0?{findings:[],records:[]}:{findings:[k("guidance-maintenance-script","No guidance maintenance script was detected.","Expose a script such as check:ai-system, lint:md, check:links, or scan:self so agents and CI can validate AI guidance drift.",t.packageJson.path)],records:[]}}function Cs(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=t.jsdocEnforcement;return[n.customChecker,n.packageScript,n.lintRules,n.stopHook].filter(Boolean).length>=2&&n.guidance||n.customChecker&&n.lintRules?{findings:[],records:[]}:{findings:[k("jsdoc-enforcement-present","JSDoc comment enforcement was not detected.","Wire oxlint jsdoc rules, a code-comment guidance doc or skill, and a custom find-missing-jsdoc checker or Stop hook so agents get deterministic JSDoc feedback.",t.packageJson.path)],records:[]}}function As(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=Se(t,/(^|:)(lint|check:lint)(:|$)/i,/\b(eslint|oxlint|biome|ruff)\b/i),r=t.configs.some(s=>s.kind==="lint");return n||r?{findings:[],records:[]}:{findings:[k("lint-gate-present","No lint/static-analysis gate was detected.","Expose a lint script or static-analysis config so agents get deterministic correction messages.",t.packageJson.path)],records:[]}}function Is(e){let t=e.intelligenceLayer;if(t===void 0||!_e(e,t))return{findings:[],records:[]};let n=t.localContextConventions.join(`
177
+ `),r=/naming|codebase-map|local-context/i.test(n),s=/comment|codebase-map|local-context/i.test(n);return t.nestedAgentsFiles.length>0||r&&s?{findings:[],records:[]}:{findings:[{ruleId:"local-context-patterns",severity:"info",message:"Local context conventions for AI-readable code were not detected.",file:"docs/ai",line:null,harnesses:[],hint:'Document naming conventions and useful "why" comment patterns, or add nested AGENTS.md files for subprojects.'}],records:[]}}function Es(e){let t=e.intelligenceLayer;if(t===void 0||t.memoryDocs.length===0)return{findings:[],records:[]};let n=t.memoryIndexes.length>0,s=!(t.packageJson.path!==null)||Object.entries(t.packageJson.scripts).some(([o,i])=>/qmd|search/i.test(o)||/qmd|search/i.test(i));return n&&s?{findings:[],records:[]}:{findings:[{ruleId:"memory-docs-indexed",severity:"info",message:"Durable memory docs should be indexed and searchable.",file:t.memoryDocs[0]??null,line:null,harnesses:[],hint:"Add a memory index such as docs/ai/codebase-map.md or docs/ai/ai-system.md, and expose a qmd/search script when package.json exists."}],records:[]}}function vs(e){let t=V(e);return t===null||!z(t)?{findings:[],records:[]}:t.aiHarnessPrTemplates.length>0?{findings:[],records:[]}:{findings:[k("pr-template-ai-harness-check","No PR template reminder for durable AI harness updates was detected.","Add a PR checklist item for recurring AI mistakes: update rules, docs, skills, tests, or diagnostics when needed.",t.prTemplates[0]??".github/PULL_REQUEST_TEMPLATE.md")],records:[]}}function Ts(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=Se(t,/(^|:)(typecheck|check:types)(:|$)/i,/\b(tsc\s+--noEmit|vue-tsc|svelte-check|mypy|pyright|cargo\s+check)\b/i),r=t.configs.some(o=>o.capabilities.includes("strict-typecheck")),s=ye(t).some(o=>/\b(mypy|pyright|cargo\s+check)\b/i.test(o.command));return n&&(r||s)?{findings:[],records:[]}:{findings:[k("strict-typecheck-present","No strict typecheck/static-analysis gate was detected.","Expose a discoverable typecheck script and strict type/static-analysis config so agents can verify structural correctness.",t.packageJson.path)],records:[]}}function Ls(e){let t=w(e);if(t===null||!b(t))return{findings:[],records:[]};let n=Se(t,/(^|:)(test|e2e|integration)(:|$)/i,/\b(vitest|jest|playwright|cypress|pytest|cargo\s+test|go\s+test)\b/i),r=t.configs.some(s=>s.kind==="test");return n||r?{findings:[],records:[]}:{findings:[k("test-gates-present","No validation test gate was detected.","Expose discoverable unit, integration, or E2E test scripts so agents can choose a safe verification loop.",t.packageJson.path)],records:[]}}var Qi={"shared-agents-md":"layering","shared-rules-doc":"layering","adapter-thin-claude":"layering","adapter-thin-gemini":"layering","adapter-thin-copilot":"layering","adapter-points-to-shared":"layering","skill-frontmatter":"maintainability","skill-line-count":"maintainability","agent-frontmatter":"maintainability","no-duplicate-skill-trees":"maintainability","no-duplicate-agent-trees":"maintainability","vscode-skills-location":"harnessWiring","vscode-agents-location":"harnessWiring","vscode-custom-hooks":"guardrails","skills-index":"discoverability","claude-agent-routing":"discoverability","agents-md-mentions-skills":"discoverability","skill-doc-deep-links":"discoverability","qmd-script-present":"discoverability","guidance-links-resolve":"maintainability","adapter-content-duplication":"sharing","forbidden-legacy-paths":"maintainability","strict-typecheck-present":"guardrails","lint-gate-present":"guardrails","jsdoc-enforcement-present":"guardrails","test-gates-present":"guardrails","focused-test-commands-present":"discoverability","ci-enforcement-gates":"guardrails","ci-validation-gates":"guardrails","correction-loop-documented":"maintainability","guidance-maintenance-script":"maintainability","pr-template-ai-harness-check":"maintainability","ci-guidance-lint":"guardrails","adapter-context-budget":"sharing","always-loaded-budget":"sharing","memory-docs-indexed":"discoverability","local-context-patterns":"maintainability","emphasis-keyword-density":"maintainability","identity-language-absent":"maintainability","model-interface-pinned":"guardrails","llm-output-schema-validated":"guardrails","tool-contract-tests-present":"guardrails","escalation-protocol-discoverability":"guardrails","agent-resource-budget-caps":"guardrails","tool-allowlist-inventory":"guardrails","untrusted-input-action-boundary":"guardrails","memory-write-provenance":"guardrails","high-impact-action-confirmation":"guardrails"};var dl=[["adapter-content-duplication",ms],["forbidden-legacy-paths",ws],["strict-typecheck-present",Ts],["lint-gate-present",As],["jsdoc-enforcement-present",Cs],["test-gates-present",Ls],["focused-test-commands-present",Ss],["ci-enforcement-gates",fs],["ci-validation-gates",hs],["correction-loop-documented",ys],["guidance-maintenance-script",bs],["pr-template-ai-harness-check",vs],["ci-guidance-lint",gs],["memory-docs-indexed",Es],["local-context-patterns",Is]];function Zi(e){let t=[],n=[];for(let[r,s]of dl){let o=s(e);t.push(...o.findings),n.push(...o.records),o.records.length===0&&n.push({checkId:r,dimension:Qi[r]??"maintainability",rawScore:o.findings.length>0?0:1})}return{findings:t,records:n}}async function wt(e,t){let n=[],r=[],s=Yi.filter(c=>ls(c,e,t)),o=await Promise.all(s.map(async c=>({rule:c,result:await c.check(e)})));for(let{rule:c,result:l}of o)J(n,r,c.id,c.dimension,l);if(cs(e,t,["cursor","copilot"])){let c=await as(e);n.push(...c.findings),r.push(...c.records),c.records.length===0&&(r.push({checkId:"vscode-skills-location",dimension:"harnessWiring",rawScore:c.findings.some(l=>l.ruleId==="vscode-skills-location")?0:1}),r.push({checkId:"vscode-agents-location",dimension:"harnessWiring",rawScore:c.findings.some(l=>l.ruleId==="vscode-agents-location")?0:1})),J(n,r,"vscode-custom-hooks","harnessWiring",await is(e))}J(n,r,"no-duplicate-skill-trees","layering",await Zr(e)),J(n,r,"no-duplicate-agent-trees","layering",await Qr(e)),J(n,r,"qmd-script-present","discoverability",await os(e)),J(n,r,"guidance-links-resolve","maintainability",await ns(e));let i=Zi(e);n.push(...i.findings),r.push(...i.records);let a=[...Jr(e).findings,...Xr(e).findings];if(t===null||t.length===0)n.push(...a);else{let c=a.filter(l=>l.harnesses.some(m=>t.includes(m)));n.push(...c)}return{findings:n,records:r}}function _s(e){let t=0,n=0,r=0;for(let s of e)s.severity==="error"?t+=1:s.severity==="warn"?n+=1:r+=1;return{error:t,warn:n,info:r}}import pl from"node:path";var le="AGENTS.md",ea=[le,"docs/ai/rules.md"],bt=["CLAUDE.md","GEMINI.md",".github/copilot-instructions.md",".agent/README.md"];function Fs(e){let t=h(e,le);if(t===null)return[];let n=C["AI2-adapter-fidelity"],r=[];for(let s of bt){let o=h(e,s);if(o===null||o.trim().length===0)continue;let i=`You are checking whether a thin per-tool adapter stays faithful to the shared guidance it points at.
176
178
 
177
179
  The adapter should defer to the shared layer, not restate or contradict it. Find
178
180
  claims in the ADAPTER that drift from the SHARED ENTRY: instructions the shared
179
181
  layer does not support, stale pointers, or duplicated guidance that has diverged.
180
182
  Be strict: only report real fidelity problems, not harmless adapter-only setup.
181
183
 
182
- ### SHARED ENTRY: ${re}
184
+ ### SHARED ENTRY: ${le}
183
185
 
184
186
  \`\`\`markdown
185
187
  ${t}
186
188
  \`\`\`
187
189
 
188
- ### ADAPTER: ${r}
190
+ ### ADAPTER: ${s}
189
191
 
190
192
  \`\`\`markdown
191
193
  ${o}
@@ -193,13 +195,13 @@ ${o}
193
195
 
194
196
  Respond with JSON only, no prose, exactly this shape:
195
197
  { "${n.schemaKey}": [ { "claim": "<quote from adapter>", "explanation": "<how it drifts>" } ] }
196
- Return an empty array if the adapter is faithful.`;s.push({taskId:`AI2-adapter-fidelity:${r}`,checkId:n.checkId,title:`${n.title} (${r})`,targetPaths:[r,re],schemaKey:n.schemaKey,prompt:i})}return s}function Ge(e,t){let n=[];for(let s of t){let r=h(e,s);r!==null&&r.trim().length>0&&n.push({path:s,content:r})}return n}function oe(e){let t=e.files.filter(n=>n.path.startsWith("skills/")&&n.path.endsWith("SKILL.md")).map(n=>n.path);return Ge(e,[...Bi,...t])}function j(e){return e.map(t=>`### FILE: ${t.path}
198
+ Return an empty array if the adapter is faithful.`;r.push({taskId:`AI2-adapter-fidelity:${s}`,checkId:n.checkId,title:`${n.title} (${s})`,targetPaths:[s,le],schemaKey:n.schemaKey,prompt:i})}return r}function Be(e,t){let n=[];for(let r of t){let s=h(e,r);s!==null&&s.trim().length>0&&n.push({path:r,content:s})}return n}function ue(e){let t=e.files.filter(n=>n.path.startsWith("skills/")&&n.path.endsWith("SKILL.md")).map(n=>n.path);return Be(e,[...ea,...t])}function j(e){return e.map(t=>`### FILE: ${t.path}
197
199
 
198
200
  \`\`\`markdown
199
201
  ${t.content}
200
202
  \`\`\``).join(`
201
203
 
202
- `)}function Sr(e){let t=oe(e);if(t.length<2)return null;let n=w["AI1-contradiction"],s=`You are auditing one repository's AI-agent guidance for internal contradictions.
204
+ `)}function Ns(e){let t=ue(e);if(t.length<2)return null;let n=C["AI1-contradiction"],r=`You are auditing one repository's AI-agent guidance for internal contradictions.
203
205
 
204
206
  Read every file below. Find places where one rule directly contradicts another \u2014
205
207
  where an agent could not satisfy both at once. Be strict: only report clear,
@@ -209,7 +211,7 @@ ${j(t)}
209
211
 
210
212
  Respond with JSON only, no prose, exactly this shape:
211
213
  { "${n.schemaKey}": [ { "ruleA": "<quote>", "ruleB": "<quote>", "explanation": "<why they conflict>" } ] }
212
- Return an empty array if there are no clear contradictions.`;return{taskId:"AI1-contradiction",checkId:n.checkId,title:n.title,targetPaths:t.map(r=>r.path),schemaKey:n.schemaKey,prompt:s}}function kr(e){let t=oe(e);if(t.length===0)return null;let n=w["AI4-deadweight"],s=`You are auditing one repository's AI-agent guidance for dead weight.
214
+ Return an empty array if there are no clear contradictions.`;return{taskId:"AI1-contradiction",checkId:n.checkId,title:n.title,targetPaths:t.map(s=>s.path),schemaKey:n.schemaKey,prompt:r}}function Ps(e){let t=ue(e);if(t.length===0)return null;let n=C["AI4-deadweight"],r=`You are auditing one repository's AI-agent guidance for dead weight.
213
215
 
214
216
  Apply the deletion test to each rule or instruction below: if this line were
215
217
  deleted, would a competent coding agent behave any differently? Flag the lines a
@@ -221,7 +223,7 @@ ${j(t)}
221
223
 
222
224
  Respond with JSON only, no prose, exactly this shape:
223
225
  { "${n.schemaKey}": [ { "rule": "<quote>", "reason": "<why deleting it changes nothing>" } ] }
224
- Return an empty array if every line earns its place.`;return{taskId:"AI4-deadweight",checkId:n.checkId,title:n.title,targetPaths:t.map(r=>r.path),schemaKey:n.schemaKey,prompt:s}}function xr(e){let t=[re,"docs/ai/rules.md",...ht,...e.files.filter(s=>s.path.startsWith("skills/")&&s.path.endsWith("SKILL.md")).map(s=>s.path),...e.files.filter(s=>s.path.startsWith("agents/")&&s.path.endsWith(".agent.md")).map(s=>s.path)],n=Ge(e,t);for(let s of e.security?.hookScripts??[])s.content.trim().length>0&&n.push({path:s.path??s.source,content:s.content});return n}function wr(e){let t=xr(e);if(t.length===0)return null;let n=w["AI3-security-review"],s=`You are performing a security review of one repository's AI-agent configuration:
226
+ Return an empty array if every line earns its place.`;return{taskId:"AI4-deadweight",checkId:n.checkId,title:n.title,targetPaths:t.map(s=>s.path),schemaKey:n.schemaKey,prompt:r}}function Hs(e){let t=[le,"docs/ai/rules.md",...bt,...e.files.filter(r=>r.path.startsWith("skills/")&&r.path.endsWith("SKILL.md")).map(r=>r.path),...e.files.filter(r=>r.path.startsWith("agents/")&&r.path.endsWith(".agent.md")).map(r=>r.path)],n=Be(e,t);for(let r of e.security?.hookScripts??[])r.content.trim().length>0&&n.push({path:r.path??r.source,content:r.content});return n}function Ms(e){let t=Hs(e);if(t.length===0)return null;let n=C["AI3-security-review"],r=`You are performing a security review of one repository's AI-agent configuration:
225
227
  its always-loaded instructions, skills, agent definitions, and lifecycle hook
226
228
  scripts.
227
229
 
@@ -245,7 +247,7 @@ ${j(t)}
245
247
 
246
248
  Respond with JSON only, no prose, exactly this shape:
247
249
  { "${n.schemaKey}": [ { "location": "<file or area>", "risk": "<short category>", "explanation": "<quote and why it is a risk>" } ] }
248
- Return an empty array if you find no clear risks.`;return{taskId:"AI3-security-review",checkId:n.checkId,title:n.title,targetPaths:t.map(r=>r.path),schemaKey:n.schemaKey,prompt:s}}function Rr(e){let t=oe(e);if(t.length===0)return null;let n=w["AI5-vague-rules"],s=`You are auditing one repository's AI-agent guidance for vague rules.
250
+ Return an empty array if you find no clear risks.`;return{taskId:"AI3-security-review",checkId:n.checkId,title:n.title,targetPaths:t.map(s=>s.path),schemaKey:n.schemaKey,prompt:r}}function Ds(e){let t=ue(e);if(t.length===0)return null;let n=C["AI5-vague-rules"],r=`You are auditing one repository's AI-agent guidance for vague rules.
249
251
 
250
252
  Flag each rule below that lacks a clear, testable decision boundary \u2014 where an
251
253
  agent cannot determine whether it is complying. Examples: "keep files small"
@@ -257,12 +259,12 @@ ${j(t)}
257
259
 
258
260
  Respond with JSON only, no prose, exactly this shape:
259
261
  { "${n.schemaKey}": [ { "rule": "<quote>", "reason": "<what decision boundary is missing>" } ] }
260
- Return an empty array if every rule has a clear boundary.`;return{taskId:"AI5-vague-rules",checkId:n.checkId,title:n.title,targetPaths:t.map(r=>r.path),schemaKey:n.schemaKey,prompt:s}}function br(e){let t=[],n=Sr(e);n!==null&&t.push(n);let s=kr(e);s!==null&&t.push(s);let r=Rr(e);r!==null&&t.push(r),t.push(...yr(e));let o=wr(e);return o!==null&&t.push(o),t}async function yt(e){let t=Jc.resolve(e),n=await Ae(t),{files:s,contents:r}=await Te(t),o=await _e(t);return{version:1,root:t,tasks:br({repoRoot:t,harnesses:n,files:s,fileContents:r,security:o})}}import hl from"node:path";function Cr(e){let t=Array.from({length:e},(o,i)=>i),n=Array.from({length:e},()=>0);function s(o){let i=o;for(;(t[i]??i)!==i;)i=t[i]??i;let a=o;for(;a!==i;){let c=t[a]??i;t[a]=i,a=c}return i}function r(o,i){let a=s(o),c=s(i);if(a===c)return;let l=n[a]??0,p=n[c]??0;if(l<p){t[a]=c;return}if(l>p){t[c]=a;return}t[c]=a,n[a]=l+1}return{findRoot:s,union:r}}function _(e){return String(e??"").replaceAll(/\s+/g," ").trim().toLowerCase()}function Ir(e,t=20){let n=new Set,s=_(e);if(s.length<t)return n;let r=Math.max(5,Math.floor(t/4));for(let i=0;i+t<=s.length;i+=r)n.add(s.slice(i,i+t));let o=s.length-t;return o>0&&n.add(s.slice(o)),n}function Er(e){let t=null,n=0,s=0;for(let[r,o]of e.entries()){let i=o.sessions.size;(i>n||i===n&&o.occurrences>s)&&(t=r,n=i,s=o.occurrences)}return t}function ie(e,t=20,n=Number.POSITIVE_INFINITY){let s=e.map(p=>({sessionId:p.sessionId,normalized:_(p.text)})).filter(p=>p.normalized.length>=t),r=s.length;if(r<2)return[];let o=s.map(p=>Ir(p.normalized,t)),i=new Map;for(let[p,f]of o.entries())for(let m of f){let d=i.get(m);d===void 0?i.set(m,[p]):d.push(p)}let a=Cr(r);for(let p of i.values()){let[f,...m]=p;if(f!==void 0)for(let d of m)a.union(f,d)}let c=new Map;for(let p=0;p<r;p+=1){let f=a.findRoot(p),m=c.get(f)??[];m.push(p),c.set(f,m)}let l=[];for(let p of c.values()){if(p.length<2)continue;let f=new Set,m=new Map;for(let g of p){let S=s[g],A=o[g];if(!(S===void 0||A===void 0)){f.add(S.sessionId);for(let xe of A){let q=m.get(xe)??{sessions:new Set,occurrences:0};q.occurrences+=1,q.sessions.add(S.sessionId),m.set(xe,q)}}}if(f.size<2&&p.length<n)continue;let d=Er(m);d!==null&&l.push({instruction:d,occurrences:p.length,sessions:f.size})}return l.toSorted((p,f)=>f.sessions-p.sessions||f.occurrences-p.occurrences)}import{createHash as Qc}from"node:crypto";function vr(e){let t=String(e??""),n=Qc("sha256").update(t).digest("hex").slice(0,8);return`[redacted ${t.length}ch #${n}]`}function ae(e,t){return t?String(e??""):vr(e)}function je(e,t){return t.some(n=>n.test(e))}function We(e){return je(e,oo)}function Tr(e,t){let n=e.filter(l=>l.role==="user"&&We(l.text));if(n.length===0)return[];let s=new Set(n.map(l=>l.sessionId)),r=new Set(e.filter(l=>l.role==="user").map(l=>l.sessionId)).size,o=r===0?0:n.length/r,i={checkId:"SS3",name:L.SS3,detail:`${n.length} corrections across ${s.size} of ${r} sessions (${o.toFixed(2)} per session)`,sessions:s.size,occurrences:n.length,snippet:null},a=n.map(l=>({sessionId:l.sessionId,text:l.text})),c=ie(a).map(l=>{let p=ae(l.instruction,t);return{checkId:"SS3",name:L.SS3,detail:`Recurring friction ${p}: corrected in ${l.sessions} sessions (${l.occurrences} times)`,sessions:l.sessions,occurrences:l.occurrences,snippet:p}});return[i,...c]}function Lr(e,t){return e.keywords.length===0?t.includes(_(e.text)):e.keywords.some(n=>new RegExp(`\\b${n}\\b`).test(t))}function Fr(e,t){if(t.length===0)return[];let n=new Map;for(let r of e){let o=n.get(r.sessionId)??[];o.push(r),n.set(r.sessionId,o)}let s=new Map;for(let[r,o]of n.entries()){let i=o.map(a=>_(a.text));for(let[a,c]of o.entries()){if(c.role!=="user"||!We(c.text))continue;let l=[i[a-1],i[a],i[a+1]].filter(p=>typeof p=="string").join(`
261
- `);if(io.test(l))for(let p of t){if(!Lr(p,l))continue;let f=s.get(p.text)??{rule:p.text,occurrences:0,sessions:new Set};f.occurrences+=1,f.sessions.add(r),s.set(p.text,f)}}}return[...s.values()].toSorted((r,o)=>o.sessions.size-r.sessions.size||o.occurrences-r.occurrences).map(r=>({checkId:"SS2",name:L.SS2,detail:`Possibly ignored rule "${r.rule}": ${r.occurrences} corrections in tool-use context across ${r.sessions.size} sessions`,sessions:r.sessions.size,occurrences:r.occurrences,snippet:r.rule}))}function _r(e){return je(e,ro)}function Nr(e,t){let n=e.filter(s=>s.role==="user"&&_r(s.text)).map(s=>({sessionId:s.sessionId,text:s.text}));return ie(n,void 0,3).map(s=>{let r=ae(s.instruction,t),o=s.sessions>=2?`repeated across ${s.sessions} sessions (${s.occurrences} times)`:`repeated ${s.occurrences} times within a single session`;return{checkId:"SS4",name:L.SS4,detail:`Candidate missing rule ${r}: ${o} but likely not in committed guidance`,sessions:s.sessions,occurrences:s.occurrences,snippet:r}})}function Pr(e,t){let n=e.filter(s=>s.role==="user").map(s=>({sessionId:s.sessionId,text:s.text}));return ie(n).map(s=>{let r=ae(s.instruction,t);return{checkId:"SS1",name:L.SS1,detail:`Repeated prompt ${r} seen in ${s.sessions} sessions (${s.occurrences} times)`,sessions:s.sessions,occurrences:s.occurrences,snippet:r}})}function Hr(e,t,n){return[...Nr(e,n),...Fr(e,t),...Tr(e,n),...Pr(e,n)]}import{homedir as el}from"node:os";import zi from"node:path";function Mr(e){return e!==null&&e.length>0?zi.resolve(e):zi.join(el(),".claude","projects")}import qi from"node:path";import{lstatSync as tl}from"node:fs";function Dr(e){try{return tl(e).mtimeMs}catch{return null}}import{readdirSync as nl}from"node:fs";function Or(e){try{return nl(e,{withFileTypes:!0})}catch{return[]}}function $r(e,t){let n=[];for(let s of Or(e)){if(s.isSymbolicLink()||!s.isFile()||qi.extname(s.name).toLowerCase()!==".jsonl")continue;let r=qi.join(e,s.name),o=Dr(r);o!==null&&n.push({file:r,mtimeMs:o})}return n.toSorted((s,r)=>r.mtimeMs-s.mtimeMs).slice(0,Math.max(0,t)).map(s=>s.file)}import{existsSync as rl,statSync as ol}from"node:fs";import il from"node:path";import sl from"node:path";function Gr(e){return sl.resolve(e).replaceAll(/[/\\]/g,"-")}function jr(e,t){let n=il.join(e,Gr(t));return!rl(n)||!ol(n).isDirectory()?null:n}import{createReadStream as al}from"node:fs";import cl from"node:path";import{createInterface as ll}from"node:readline";function Wr(e){let{type:t,message:n}=e;return typeof t=="string"&&t.trim().length>0?t.trim().toLowerCase():y(n)&&typeof n.role=="string"?n.role.trim().toLowerCase():""}function Ur(e){let t=e.trim();return t.length<5?!0:ao.some(n=>n.test(t))}function Br(e){if(!y(e))return"";let{message:t}=e;if(!y(t))return"";let{content:n}=t,s="";if(typeof n=="string")s=n.trim();else if(Array.isArray(n)){let o=[];for(let i of n)y(i)&&i.type==="text"&&typeof i.text=="string"&&o.push(i.text);s=o.join(`
262
- `).trim()}let r=s.replaceAll(/<system-reminder>[\s\S]*?<\/system-reminder>/g,"").trim();return Ur(r)?"":r}function Vr(e){try{return JSON.parse(e)}catch{return}}async function zr(e){let t=cl.basename(e,".jsonl"),n=[],s=ll({input:al(e,{encoding:"utf8"}),crlfDelay:1/0});try{for await(let r of s){let o=r.trim();if(o.length===0)continue;let i=Vr(o);if(!y(i))continue;let a=Br(i);a.length!==0&&n.push({sessionId:t,role:Wr(i),text:a})}}catch{return n}return n}async function ul(e){let t=Mr(e.sessionRoot),n=jr(t,e.repoRoot);if(n===null)return[];let s=$r(n,e.maxSessions);return(await Promise.all(s.map(o=>zr(o)))).flat()}var dl={harness:"claude",collectMessages:ul},Ki=dl;import ml from"node:path";import{readFile as pl}from"node:fs/promises";async function qr(e){try{return await pl(e,"utf8")}catch{return null}}function Kr(e){return _(e).replaceAll(/[^a-z0-9 ]/g," ").replaceAll(/\s+/g," ").trim()}var fl=new Set(["the","and","that","with","from","this","they","have","been","were","what","just","when","where","your","you","are","was","for","not","out","into","about","them","then","than","its","our","all","any","can","has","had","but","only","still","very","well","like","use","using","should","must"]);function Yr(e){let t=[];for(let n of e.split(`
263
- `)){let s=n.trim();if(/^[-*]\s*(don't|dont|never|always|do not|important)\b[:\s-]*(.*)$/i.exec(s)===null)continue;let o=s.replace(/^[-*]\s*/,""),i=Kr(o).split(/\s+/).filter(a=>a.length>=3&&!fl.has(a));t.push({text:o,keywords:i})}return t}var gl=["CLAUDE.md","AGENTS.md"];async function Jr(e){let t=await Promise.all(gl.map(n=>qr(ml.join(e,n))));for(let n of t){if(n===null)continue;let s=Yr(n);if(s.length>0)return s}return[]}async function St(e,t=Ki){let n=hl.resolve(e.repoRoot),s=await t.collectMessages({...e,repoRoot:n}),r=new Set(s.map(a=>a.sessionId)).size;if(s.length===0)return{version:1,root:n,harness:t.harness,tier:"extended",status:"no-sessions",sessionsAnalyzed:0,redacted:!e.includeRawSnippets,findings:[]};let o=await Jr(n),i=Hr(s,o,e.includeRawSnippets);return{version:1,root:n,harness:t.harness,tier:"extended",status:"run",sessionsAnalyzed:r,redacted:!e.includeRawSnippets,findings:i}}var Yi={error:3,warn:2,info:1};function kt(e,t){let n=Yi[t];return e.some(s=>Yi[s.severity]>=n)}async function Xr(e){let t=yl.resolve(e.repoRoot),n=Fo(),s=await Ae(t),{files:r,contents:o}=await Te(t),i=await rs(t),a=await _e(t),c=await Xn(t),l={repoRoot:t,harnesses:s,files:r,fileContents:o,intelligenceLayer:i,security:a,boundary:c},p=Sn(l);l.contextBudget=p;let{findings:f,records:m}=await gt(l,e.harnessFilter),d=hr(f),g=xn(f),S=un(r,s),A=await Z(t),xe=await Fn(l,A,f,S),q=Gn(m,f,S,xe,l),Ji=await en(l,A),Xi=await n,Qi=ct(i),Zi=e.aiReviewResults===void 0?wt:qe(e.aiReviewResults);return{version:Xi.version,root:t,harnesses:s,total_score:q.total_score,score_scope:q.score_scope,inventory:{fileCount:r.length,files:r},sharing:S,metaHarness:q,harnessGapMatrix:Ji,harnessOptimization:xe,intelligenceLayer:Qi,contextBudget:p,aiReview:Zi,findings:f,failureModeExposure:g,summary:d}}async function Qr(){let e=Pt(process.argv.slice(2));if(e.help&&(Ht(),process.exit(0)),e.emitAiTasks)try{let t=await yt(e.repoRoot);process.stdout.write(`${JSON.stringify(t,null,2)}
264
- `),process.exit(0)}catch(t){let n=t instanceof Error?t.message:String(t);process.stderr.write(`error: ${n}
265
- `),process.exit(2)}if(e.sessionAnalysis)try{let t=await St({repoRoot:e.repoRoot,sessionRoot:e.sessionRoot,maxSessions:e.maxSessions,includeRawSnippets:e.includeRawSnippets});e.format==="json"?process.stdout.write(`${JSON.stringify(t,null,2)}
266
- `):Dt(t),process.exit(0)}catch(t){let n=t instanceof Error?t.message:String(t);process.stderr.write(`error: ${n}
267
- `),process.exit(2)}try{let t=e.ingestResultsPath===null?void 0:await _t(e.ingestResultsPath),n=await Xr({repoRoot:e.repoRoot,harnessFilter:e.harnessFilter,...t===void 0?{}:{aiReviewResults:t}});e.format==="json"?Mt(n):an(n),kt(n.findings,e.failOn)&&process.exit(1),process.exit(0)}catch(t){let n=t instanceof Error?t.message:String(t);process.stderr.write(`error: ${n}
268
- `),process.exit(2)}}await Qr();
262
+ Return an empty array if every rule has a clear boundary.`;return{taskId:"AI5-vague-rules",checkId:n.checkId,title:n.title,targetPaths:t.map(s=>s.path),schemaKey:n.schemaKey,prompt:r}}function Os(e){let t=[],n=Ns(e);n!==null&&t.push(n);let r=Ps(e);r!==null&&t.push(r);let s=Ds(e);s!==null&&t.push(s),t.push(...Fs(e));let o=Ms(e);return o!==null&&t.push(o),t}async function Ct(e){let t=pl.resolve(e),n=await Ee(t),{files:r,contents:s}=await He(t),o=await De(t);return{version:1,root:t,tasks:Os({repoRoot:t,harnesses:n,files:r,fileContents:s,security:o})}}import Bl from"node:path";import{homedir as ml}from"node:os";import ta from"node:path";import na from"node:path";import{lstatSync as gl}from"node:fs";import{readdirSync as yl}from"node:fs";import{existsSync as xl,statSync as Rl}from"node:fs";import wl from"node:path";import bl from"node:path";import{createReadStream as Il}from"node:fs";import El from"node:path";import{createInterface as vl}from"node:readline";function fl(e){return e!==null&&e.length>0?ta.resolve(e):ta.join(ml(),".claude","projects")}function hl(e){try{return gl(e).mtimeMs}catch{return null}}function Sl(e){try{return yl(e,{withFileTypes:!0})}catch{return[]}}function kl(e,t){let n=[];for(let r of Sl(e)){if(r.isSymbolicLink()||!r.isFile()||na.extname(r.name).toLowerCase()!==".jsonl")continue;let s=na.join(e,r.name),o=hl(s);o!==null&&n.push({file:s,mtimeMs:o})}return n.toSorted((r,s)=>s.mtimeMs-r.mtimeMs).slice(0,Math.max(0,t)).map(r=>r.file)}function Cl(e){return bl.resolve(e).replaceAll(/[/\\]/g,"-")}function Al(e,t){let n=wl.join(e,Cl(t));return!xl(n)||!Rl(n).isDirectory()?null:n}function Ve(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Tl(e){let{type:t,message:n}=e;return typeof t=="string"&&t.trim().length>0?t.trim().toLowerCase():Ve(n)&&typeof n.role=="string"?n.role.trim().toLowerCase():""}var Ll=[/^<[a-z-]+>/i,/^<\/[a-z-]+>/i,/^─{4,}/,/^={4,}/,/^-{4,}/,/^\*{4,}/,/^#{4,}\s*$/,/^UserPromptSubmit/,/^SessionStart/,/^OK$/,/^Tool loaded/];function _l(e){let t=e.trim();return t.length<5?!0:Ll.some(n=>n.test(t))}function Fl(e){if(!Ve(e))return"";let{message:t}=e;if(!Ve(t))return"";let{content:n}=t,r="";if(typeof n=="string")r=n.trim();else if(Array.isArray(n)){let o=[];for(let i of n)Ve(i)&&i.type==="text"&&typeof i.text=="string"&&o.push(i.text);r=o.join(`
263
+ `).trim()}let s=r.replaceAll(/<system-reminder>[\s\S]*?<\/system-reminder>/g,"").trim();return _l(s)?"":s}function Nl(e){try{return JSON.parse(e)}catch{return}}async function Pl(e){let t=El.basename(e,".jsonl"),n=[],r=vl({input:Il(e,{encoding:"utf8"}),crlfDelay:1/0});try{for await(let s of r){let o=s.trim();if(o.length===0)continue;let i=Nl(o);if(!Ve(i))continue;let a=Fl(i);a.length!==0&&n.push({sessionId:t,role:Tl(i),text:a})}}catch{return n}return n}async function Hl(e){let t=fl(e.sessionRoot),n=Al(t,e.repoRoot);if(n===null)return[];let r=kl(n,e.maxSessions);return(await Promise.all(r.map(o=>Pl(o)))).flat()}var Ml={harness:"claude",collectMessages:Hl},ra=Ml;function $s(e){let t=Array.from({length:e},(o,i)=>i),n=Array.from({length:e},()=>0);function r(o){let i=o;for(;(t[i]??i)!==i;)i=t[i]??i;let a=o;for(;a!==i;){let c=t[a]??i;t[a]=i,a=c}return i}function s(o,i){let a=r(o),c=r(i);if(a===c)return;let l=n[a]??0,m=n[c]??0;if(l<m){t[a]=c;return}if(l>m){t[c]=a;return}t[c]=a,n[a]=l+1}return{findRoot:r,union:s}}function N(e){return String(e??"").replaceAll(/\s+/g," ").trim().toLowerCase()}function js(e,t=20){let n=new Set,r=N(e);if(r.length<t)return n;let s=Math.max(5,Math.floor(t/4));for(let i=0;i+t<=r.length;i+=s)n.add(r.slice(i,i+t));let o=r.length-t;return o>0&&n.add(r.slice(o)),n}function Ws(e){let t=null,n=0,r=0;for(let[s,o]of e.entries()){let i=o.sessions.size;(i>n||i===n&&o.occurrences>r)&&(t=s,n=i,r=o.occurrences)}return t}function de(e,t=20,n=Number.POSITIVE_INFINITY){let r=e.map(m=>({sessionId:m.sessionId,normalized:N(m.text)})).filter(m=>m.normalized.length>=t),s=r.length;if(s<2)return[];let o=r.map(m=>js(m.normalized,t)),i=new Map;for(let[m,u]of o.entries())for(let f of u){let d=i.get(f);d===void 0?i.set(f,[m]):d.push(m)}let a=$s(s);for(let m of i.values()){let[u,...f]=m;if(u!==void 0)for(let d of f)a.union(u,d)}let c=new Map;for(let m=0;m<s;m+=1){let u=a.findRoot(m),f=c.get(u)??[];f.push(m),c.set(u,f)}let l=[];for(let m of c.values()){if(m.length<2)continue;let u=new Set,f=new Map;for(let g of m){let y=r[g],E=o[g];if(!(y===void 0||E===void 0)){u.add(y.sessionId);for(let we of E){let X=f.get(we)??{sessions:new Set,occurrences:0};X.occurrences+=1,X.sessions.add(y.sessionId),f.set(we,X)}}}if(u.size<2&&m.length<n)continue;let d=Ws(f);d!==null&&l.push({instruction:d,occurrences:m.length,sessions:u.size})}return l.toSorted((m,u)=>u.sessions-m.sessions||u.occurrences-m.occurrences)}import{createHash as Ol}from"node:crypto";function Us(e){let t=String(e??""),n=Ol("sha256").update(t).digest("hex").slice(0,8);return`[redacted ${t.length}ch #${n}]`}function pe(e,t){return t?String(e??""):Us(e)}function ze(e,t){return t.some(n=>n.test(e))}function qe(e){return ze(e,lo)}function Bs(e,t){let n=e.filter(l=>l.role==="user"&&qe(l.text));if(n.length===0)return[];let r=new Set(n.map(l=>l.sessionId)),s=new Set(e.filter(l=>l.role==="user").map(l=>l.sessionId)).size,o=s===0?0:n.length/s,i={checkId:"SS3",name:_.SS3,detail:`${n.length} corrections across ${r.size} of ${s} sessions (${o.toFixed(2)} per session)`,sessions:r.size,occurrences:n.length,snippet:null},a=n.map(l=>({sessionId:l.sessionId,text:l.text})),c=de(a).map(l=>{let m=pe(l.instruction,t);return{checkId:"SS3",name:_.SS3,detail:`Recurring friction ${m}: corrected in ${l.sessions} sessions (${l.occurrences} times)`,sessions:l.sessions,occurrences:l.occurrences,snippet:m}});return[i,...c]}function Vs(e,t){return e.keywords.length===0?t.includes(N(e.text)):e.keywords.some(n=>new RegExp(`\\b${n}\\b`).test(t))}function zs(e,t){if(t.length===0)return[];let n=new Map;for(let s of e){let o=n.get(s.sessionId)??[];o.push(s),n.set(s.sessionId,o)}let r=new Map;for(let[s,o]of n.entries()){let i=o.map(a=>N(a.text));for(let[a,c]of o.entries()){if(c.role!=="user"||!qe(c.text))continue;let l=[i[a-1],i[a],i[a+1]].filter(m=>typeof m=="string").join(`
264
+ `);if(uo.test(l))for(let m of t){if(!Vs(m,l))continue;let u=r.get(m.text)??{rule:m.text,occurrences:0,sessions:new Set};u.occurrences+=1,u.sessions.add(s),r.set(m.text,u)}}}return[...r.values()].toSorted((s,o)=>o.sessions.size-s.sessions.size||o.occurrences-s.occurrences).map(s=>({checkId:"SS2",name:_.SS2,detail:`Possibly ignored rule "${s.rule}": ${s.occurrences} corrections in tool-use context across ${s.sessions.size} sessions`,sessions:s.sessions.size,occurrences:s.occurrences,snippet:s.rule}))}function qs(e){return ze(e,co)}function Ks(e,t){let n=e.filter(r=>r.role==="user"&&qs(r.text)).map(r=>({sessionId:r.sessionId,text:r.text}));return de(n,void 0,3).map(r=>{let s=pe(r.instruction,t),o=r.sessions>=2?`repeated across ${r.sessions} sessions (${r.occurrences} times)`:`repeated ${r.occurrences} times within a single session`;return{checkId:"SS4",name:_.SS4,detail:`Candidate missing rule ${s}: ${o} but likely not in committed guidance`,sessions:r.sessions,occurrences:r.occurrences,snippet:s}})}function Ys(e,t){let n=e.filter(r=>r.role==="user").map(r=>({sessionId:r.sessionId,text:r.text}));return de(n).map(r=>{let s=pe(r.instruction,t);return{checkId:"SS1",name:_.SS1,detail:`Repeated prompt ${s} seen in ${r.sessions} sessions (${r.occurrences} times)`,sessions:r.sessions,occurrences:r.occurrences,snippet:s}})}function Js(e,t,n){return[...Ks(e,n),...zs(e,t),...Bs(e,n),...Ys(e,n)]}import Wl from"node:path";import{readFile as Gl}from"node:fs/promises";async function Xs(e){try{return await Gl(e,"utf8")}catch{return null}}function Qs(e){return N(e).replaceAll(/[^a-z0-9 ]/g," ").replaceAll(/\s+/g," ").trim()}var jl=new Set(["the","and","that","with","from","this","they","have","been","were","what","just","when","where","your","you","are","was","for","not","out","into","about","them","then","than","its","our","all","any","can","has","had","but","only","still","very","well","like","use","using","should","must"]);function Zs(e){let t=[];for(let n of e.split(`
265
+ `)){let r=n.trim();if(/^[-*]\s*(don't|dont|never|always|do not|important)\b[:\s-]*(.*)$/i.exec(r)===null)continue;let o=r.replace(/^[-*]\s*/,""),i=Qs(o).split(/\s+/).filter(a=>a.length>=3&&!jl.has(a));t.push({text:o,keywords:i})}return t}var Ul=["CLAUDE.md","AGENTS.md"];async function eo(e){let t=await Promise.all(Ul.map(n=>Xs(Wl.join(e,n))));for(let n of t){if(n===null)continue;let r=Zs(n);if(r.length>0)return r}return[]}async function At(e,t=ra){let n=Bl.resolve(e.repoRoot),r=await t.collectMessages({...e,repoRoot:n}),s=new Set(r.map(a=>a.sessionId)).size;if(r.length===0)return{version:1,root:n,harness:t.harness,tier:"extended",status:"no-sessions",sessionsAnalyzed:0,redacted:!e.includeRawSnippets,findings:[]};let o=await eo(n),i=Js(r,o,e.includeRawSnippets);return{version:1,root:n,harness:t.harness,tier:"extended",status:"run",sessionsAnalyzed:s,redacted:!e.includeRawSnippets,findings:i}}var oa={error:3,warn:2,info:1};function It(e,t){let n=oa[t];return e.some(r=>oa[r.severity]>=n)}async function to(e){let t=Vl.resolve(e.repoRoot),n=mi(),r=await Ee(t),{files:s,contents:o}=await He(t),i=await Rr(t),a=await De(t),c=await fr(t),l={repoRoot:t,harnesses:r,files:s,fileContents:o,intelligenceLayer:i,security:a,boundary:c},m=An(l);l.contextBudget=m;let{findings:u,records:f}=await wt(l,e.harnessFilter),d=_s(u),g=En(u),y=yn(s,r),E=await oe(t),we=await On(l,E,u,y),X=sr(f,u,y,we,l),ia=await cn(l,E),aa=await n,ca=ht(i),la=e.aiReviewResults===void 0?vt:Qe(e.aiReviewResults);return{version:aa.version,root:t,harnesses:r,total_score:X.total_score,score_scope:X.score_scope,inventory:{fileCount:s.length,files:s},sharing:y,metaHarness:X,harnessGapMatrix:ia,harnessOptimization:we,intelligenceLayer:ca,contextBudget:m,aiReview:la,findings:u,failureModeExposure:g,summary:d}}async function no(){let e=jt(process.argv.slice(2));if(e.help){Wt(),process.exitCode=0;return}if(e.emitAiTasks){try{let t=await Ct(e.repoRoot);process.stdout.write(`${JSON.stringify(t,null,2)}
266
+ `),process.exitCode=0}catch(t){let n=t instanceof Error?t.message:String(t);process.stderr.write(`error: ${n}
267
+ `),process.exitCode=2}return}if(e.sessionAnalysis){try{let t=await At({repoRoot:e.repoRoot,sessionRoot:e.sessionRoot,maxSessions:e.maxSessions,includeRawSnippets:e.includeRawSnippets});e.format==="json"?process.stdout.write(`${JSON.stringify(t,null,2)}
268
+ `):Bt(t),process.exitCode=0}catch(t){let n=t instanceof Error?t.message:String(t);process.stderr.write(`error: ${n}
269
+ `),process.exitCode=2}return}try{let t=e.ingestResultsPath===null?void 0:await $t(e.ingestResultsPath),n=await to({repoRoot:e.repoRoot,harnessFilter:e.harnessFilter,...t===void 0?{}:{aiReviewResults:t}});e.format==="json"?Ut(n):fn(n),process.exitCode=It(n.findings,e.failOn)?1:0}catch(t){let n=t instanceof Error?t.message:String(t);process.stderr.write(`error: ${n}
270
+ `),process.exitCode=2}}await no();