@tech-leads-club/harness-toolkit 0.10.3 → 0.10.4

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.
@@ -117,9 +117,9 @@ ${" ".repeat(4)}${Z.dim(C.bar)} ${W.detail}`:U});return[Z.heading(`LAST ${$.leng
117
117
  `))return null;let Z=$.indexOf(`
118
118
  `),Q=$.slice(Z+1),J=/^---\s*$/m.exec(Q);if(!J)return null;return{block:Q.slice(0,J.index),bodyAt:Z+1+J.index+J[0].length}}function l2($){let Z=$.trim();if(Z.length>=2){let Q=Z[0],J=Z[Z.length-1];if(Q==='"'&&J==='"'||Q==="'"&&J==="'")return Z.slice(1,-1)}return Z}function i2($){return $.replace(/\\(["'\\])/g,"$1")}function v4($){let Z=$.trim();if(Z.startsWith("[")&&Z.endsWith("]")){let Q=Z.slice(1,-1).trim();if(Q==="")return[];return Q.split(",").map((J)=>i2(l2(J)))}return i2(l2(Z))}function n2($){let Z=y4($);if(Z===null)return{doc:null,error:"missing --- frontmatter block"};let Q={},J=null;for(let q of Z.block.split(`
119
119
  `)){let X=q.trim();if(X===""||X.startsWith("#"))continue;if(X.startsWith("- ")){if(J===null)return{doc:null,error:`list item with no key above it: "${X}"`};let V=Q[J],G=i2(l2(X.slice(2)));Q[J]=Array.isArray(V)?[...V,G]:[G];continue}let z=X.indexOf(":");if(z===-1)return{doc:null,error:`unparseable frontmatter line: "${X}"`};let W=X.slice(0,z).trim();if(W==="")return{doc:null,error:`frontmatter line has an empty key: "${X}"`};let Y=X.slice(z+1);if(Y.trim()===""){Q[W]=[],J=W;continue}Q[W]=v4(Y),J=null}return{doc:{fields:Q,body:$.slice(Z.bodyAt).trim()},error:null}}function Y8($,Z){let{doc:Q}=n2($),J=Q?.fields[Z];if(typeof J!=="string"||J.trim()==="")return;return J.trim()}function O1($){if($===void 0)return[];return(Array.isArray($)?$:[$]).filter((Z)=>Z!=="")}function I1($){return V8($,"docs","decisions")}function a2($,Z){let Q=V8(I1($),Z);if(!C1(Q))return null;let J;try{J=u4(Q,"utf8")}catch{return null}let q=Y8(J,"title");if(q===void 0)return null;let X=(Z.split(/[\\/]/).pop()??Z).replace(/\.md$/,"").toUpperCase(),z=Y8(J,"migration"),W=Y8(J,"timestamp");return{id:X,title:q,path:`/decisions/${Z.split(/[\\/]/).join("/")}`,...z===void 0?{}:{migration:z},...W===void 0?{}:{timestamp:W}}}function _1($,Z){return Z.filter((Q)=>/(?:^|[\\/])ad-\d+\.md$/.test(Q)).map((Q)=>a2($,Q)).filter((Q)=>Q!==null).sort((Q,J)=>Q.id.localeCompare(J.id))}var g4="archived";function N1($){let Z=I1($),Q=[];for(let J of["",g4]){let q=J===""?Z:V8(Z,J);if(!C1(q))continue;try{for(let X of m4(q))if(/^ad-\d+\.md$/.test(X))Q.push(J===""?X:V8(J,X))}catch{}}return Q}function s2($){return $.filter((Z)=>Z.migration!==void 0)}function F1($){return $.id}function P1($){if($.length===0)return"";let Z=s2($),Q=[`Harness updated. ${$.length} decision(s) landed; doctor runs below and reports what applies here.`];if(Z.length>0){Q.push("",`Needs a change doctor cannot detect for you (${Z.length}):`);for(let q of Z)Q.push(` ${q.migration} (${F1(q)})`)}let J=$.filter((q)=>q.migration===void 0);if(J.length>0)Q.push("",`Also landed: ${J.map(F1).join(", ")} — docs/decisions/index.md`);else Q.push("","Full reasoning: docs/decisions/index.md");return Q.join(`
120
- `)}import{existsSync as h4,readFileSync as p4}from"node:fs";import{join as c4}from"node:path";function L1($){return c4(H($),"release-seen.json")}function T1($){let Z=L1($);if(!h4(Z))return null;try{let Q=JSON.parse(p4(Z,"utf8"));return typeof Q?.revision==="string"&&Q.revision!==""?Q:null}catch{return null}}async function j1($,Z){await J$(L1($),{revision:Z,updatedAt:new Date().toISOString()})}var d4={"pr-open":[{prefix:["gh","pr","create"],excludeIfAny:["--draft","-d"]},{prefix:["gh","pr","ready"]}],commit:[{prefix:["git","commit"]}],push:[{prefix:["git","push"]}]};function D1($){return k($).map((Z)=>Z.words.map((Q)=>Q.text)).filter((Z)=>Z.length>0)}function l4($,Z){return Z.every((Q,J)=>$[J]===Q)}function i4($,Z){if(!l4($,Z.prefix))return!1;return!Z.excludeIfAny?.some((Q)=>$.includes(Q))}function r2($,Z){let Q=Z.trim().split(/\s+/);if(Q.length===0)return!1;return $.some((J,q)=>Q.every((X,z)=>$[q+z]===X))}function o2($,Z){switch($.kind){case"stop":return Z.event==="stop";case"tool":return Z.toolName===$.name;case"pr-open":case"commit":case"push":{if(Z.command===void 0)return!1;let Q=d4[$.kind];return D1(Z.command).some((J)=>Q.some((q)=>i4(J,q)))}default:{if(Z.command===void 0)return!1;return D1(Z.command).some((Q)=>r2(Q,$.pattern))}}}function G8($,Z){return $.filter((Q)=>Q.enabled&&o2(Q.on,Z))}function n4($,Z){if($===Z)return!0;if($.startsWith("*"))return Z.endsWith($.slice(1));if($.endsWith("/"))return Z.startsWith($);return!1}function A1($,Z){if($.kind!==Z.kind)return!1;switch($.kind){case"command":return r2(Z.value.split(/\s+/),$.value);case"file":return n4($.value,Z.value);default:return Z.value===$.value}}function a4($,Z,Q){if($.since==="session")return Z.sessionKey===Q.sessionKey;return Q.sha!==null&&Z.sha===Q.sha}function s4($,Z,Q){return Z.some((J)=>A1($,J)&&a4($,J,Q))}function r4($,Z){if($.since==="session")return"ran, but in a different session";return Z.sha===null?"ran, but this project is not a git checkout, so since HEAD can never be satisfied":"ran, but at a different commit"}function R1($,Z,Q){return $.require.filter((J)=>!s4(J,Z,Q)).map((J)=>({proof:J,reason:Z.some((q)=>A1(J,q))?r4(J,Q):null}))}function E1($){let{proof:Z,reason:Q}=$,J=`${Z.kind}(${Z.value}) since ${Z.since==="head"?"HEAD":"session"}`;return Q===null?J:`${J} (${Q})`}function B8($,Z){return $.some((Q)=>Q.require.some((J)=>J.kind===Z))}function k1($,Z){let Q=new Set(Z.map((J)=>J.kind));return $.map((J)=>({rule:J.name,kinds:[...new Set(J.require.map((q)=>q.kind))].filter((q)=>!Q.has(q))})).filter((J)=>J.kinds.length>0)}function t2($,Z){return $==="ask"&&Z!=="paired"?"deny":$}function o4($,Z){let Q=`rule ${$.name} (${$.tier}): missing ${Z.join(", ")}`;return $.body.trim()===""?Q:`${Q}
120
+ `)}import{existsSync as h4,readFileSync as p4}from"node:fs";import{join as c4}from"node:path";function L1($){return c4(H($),"release-seen.json")}function T1($){let Z=L1($);if(!h4(Z))return null;try{let Q=JSON.parse(p4(Z,"utf8"));return typeof Q?.revision==="string"&&Q.revision!==""?Q:null}catch{return null}}async function j1($,Z){await J$(L1($),{revision:Z,updatedAt:new Date().toISOString()})}var d4={"pr-open":[{prefix:["gh","pr","create"],excludeIfAny:["--draft","-d"]},{prefix:["gh","pr","ready"]}],commit:[{prefix:["git","commit"]}],push:[{prefix:["git","push"]}]};function D1($){return k($).map((Z)=>Z.words.map((Q)=>Q.text)).filter((Z)=>Z.length>0)}function l4($,Z){return Z.every((Q,J)=>$[J]===Q)}function i4($,Z){if(!l4($,Z.prefix))return!1;return!Z.excludeIfAny?.some((Q)=>$.includes(Q))}function r2($,Z){let Q=Z.trim().split(/\s+/);if(Q.length===0)return!1;return $.some((J,q)=>Q.every((X,z)=>$[q+z]===X))}function o2($,Z){switch($.kind){case"stop":return Z.event==="stop";case"tool":return Z.toolName===$.name;case"pr-open":case"commit":case"push":{if(Z.command===void 0)return!1;let Q=d4[$.kind];return D1(Z.command).some((J)=>Q.some((q)=>i4(J,q)))}default:{if(Z.command===void 0)return!1;return D1(Z.command).some((Q)=>r2(Q,$.pattern))}}}function G8($,Z){return $.filter((Q)=>Q.enabled&&o2(Q.on,Z))}function n4($,Z){if($===Z)return!0;if($.startsWith("*"))return Z.endsWith($.slice(1));if($.endsWith("/"))return Z.startsWith($);return!1}function A1($,Z){if($.kind!==Z.kind)return!1;switch($.kind){case"command":return r2(Z.value.split(/\s+/),$.value);case"file":return n4($.value,Z.value);default:return Z.value===$.value}}function a4($,Z,Q){if($.since==="session")return Z.sessionKey===Q.sessionKey;return Q.sha!==null&&Z.sha===Q.sha}function s4($,Z,Q){return Z.some((J)=>A1($,J)&&a4($,J,Q))}function r4($,Z){if($.since==="session")return"ran, but in a different session";return Z.sha===null?"ran, but this project is not a git checkout, so since HEAD can never be satisfied":"ran, but at a different commit"}function R1($,Z,Q){return $.require.filter((J)=>!s4(J,Z,Q)).map((J)=>({proof:J,reason:Z.some((q)=>A1(J,q))?r4(J,Q):null}))}function E1($){let{proof:Z,reason:Q}=$,J=`${Z.kind}(${Z.value}) since ${Z.since==="head"?"HEAD":"session"}`;return Q===null?J:`${J} (${Q})`}function B8($,Z){return $.some((Q)=>Q.require.some((J)=>J.kind===Z))}function k1($,Z){let Q=new Set(Z.map((J)=>J.kind));return $.map((J)=>({rule:J.name,kinds:[...new Set(J.require.map((q)=>q.kind))].filter((q)=>!Q.has(q))})).filter((J)=>J.kinds.length>0)}function t2($,Z){return $==="ask"&&Z!=="paired"?"deny":$}function o4($,Z,Q,J){let q=`rule ${$.name} (${$.tier}): missing ${Z.join(", ")} — checked ${Q} at ${J??"no HEAD"}`;return $.body.trim()===""?q:`${q}
121
121
 
122
- ${$.body.trim()}`}function H8($,Z,Q){let J=[];for(let q of $){let X=R1(q,Z,Q);if(X.length===0)continue;let z=X.map(E1);J.push({rule:q,verdict:t2(q.otherwise,Q.mode),missing:z,message:o4(q,z)})}return J}var x1={warn:0,"follow-up":1,ask:2,deny:3};function K8($){return $.reduce((Z,Q)=>Z===null||x1[Q.verdict]>x1[Z.verdict]?Q:Z,null)}function U8($){let Z=`rule:${$.rule.name}`;if($.verdict==="deny")return{kind:"deny",reason:$.message,rule:Z};if($.verdict==="ask")return{kind:"ask",reason:$.message,userNote:$.message,rule:Z};return{kind:"abstain"}}function M8($){switch($.verdict){case"deny":case"ask":return{kind:"continue",text:`BLOCKED: ${$.message}`};case"follow-up":return{kind:"continue",text:`NEED: ${$.message}`};case"warn":return{kind:"context",text:`ADVISORY: ${$.message}`}}}function e2($){if($.event==="subagent.stop"){let Z=$.spawnSubagentType??$.spawnAgentLabel;return Z===void 0?null:{kind:"subagent",value:Z}}if($.event==="tool.after"||$.event==="shell.after")return $.command===void 0?null:{kind:"command",value:$.command};if($.event==="edit.after")return $.filePath===void 0?null:{kind:"file",value:$.filePath};return null}function O8($,Z){let Q=e2($);return Q===null?null:{...Q,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function F8($,Z){return{kind:"gate",value:$,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function $Z($){if($.event!=="tool.after"||!t4.has($.toolName??""))return null;let{spawnAgentLabel:Z,spawnSubagentType:Q}=$;return Z===void 0||Q===void 0||Z===Q?null:{label:Z,type:Q}}var t4=new Set(["Task","Agent"]);function S1($,Z){if($.event!=="subagent.stop"||$.spawnSubagentType!==void 0)return $;let Q=$.spawnAgentLabel;if(Q===void 0)return $;let J=Z().filter((X)=>X.label===Q),q=J[J.length-1];return q===void 0?$:{...$,spawnSubagentType:q.type}}var b1=new Set(["deny","ask","follow-up","warn"]),f1=new Set(["subagent","command","gate","file"]);var e4=new Set(["pr-open","commit","push","stop"]);function $z($){let Z=$.trim();if(e4.has(Z))return{kind:Z};let Q=/^(tool|command)\(([^)]*)\)$/.exec(Z),J=Q?.[1],q=Q?.[2]?.trim();if(J===void 0||q===void 0||q==="")return`unknown trigger "${Z}" — use one of pr-open, commit, push, stop, tool(<name>), command(<pattern>)`;return J==="tool"?{kind:"tool",name:q}:{kind:"command",pattern:q}}function Zz($){let[Z,...Q]=$.trim().split(/\s+since\s+/i),J=/^([a-z]+)\(([^)]*)\)$/.exec((Z??"").trim()),q=J?.[1],X=J?.[2]?.trim();if(q===void 0||!f1.has(q)||X===void 0||X==="")return`unknown proof "${$.trim()}" — use subagent(<type>), command(<pattern>), gate(<name>) or file(<glob>)`;let z=(Q[0]??"head").trim().toLowerCase();if(z!=="head"&&z!=="session")return`unknown window "since ${z}" in "${$.trim()}" — use since HEAD or since session`;return{kind:q,value:X,since:z}}function Qz($){let Z=(G)=>({error:{name:$.name,tier:$.tier,error:G}}),{doc:Q,error:J}=n2($.text);if(Q===null)return Z(J??"unreadable");let q=Q.fields.enabled,X=q===void 0?!0:String(q).trim()!=="false",z=Q.fields.on;if(typeof z!=="string"||z.trim()==="")return Z("no `on:` trigger");let W=$z(z);if(typeof W==="string")return Z(W);let Y=Q.fields.otherwise;if(typeof Y!=="string"||!b1.has(Y.trim()))return Z("`otherwise:` must be one of deny, ask, follow-up, warn");let V=[];for(let G of O1(Q.fields.require)){let B=Zz(G);if(typeof B==="string")return Z(B);V.push(B)}if(V.length===0&&X)return Z("no `require:` proof, so nothing could ever satisfy this rule");return{rule:{name:$.name,tier:$.tier,enabled:X,on:W,require:V,otherwise:Y.trim(),body:Q.body}}}function C8($){let Z=new Map,Q=[];for(let q of["global","project"])for(let X of $.filter((z)=>z.tier===q)){let z=Qz(X);if("error"in z){Q.push(z.error);continue}Z.set(z.rule.name,z.rule)}let J=[...Z.values()];return{rules:J.filter((q)=>q.enabled),disabled:J.filter((q)=>!q.enabled),errors:Q}}import{existsSync as Jz,readdirSync as qz,readFileSync as Xz}from"node:fs";import{basename as zz,join as C$}from"node:path";var y1=500;function v1($){return C$(H($),"rule-observations.jsonl")}function ZZ($){return C$(H($),"..","rules")}function QZ(){return C$(g(),"rules")}function w1($,Z){if(!Jz($))return[];return qz($,{withFileTypes:!0}).filter((Q)=>Q.isFile()&&Q.name.endsWith(".md")).map((Q)=>{let J=C$($,Q.name);return{name:zz(Q.name,".md"),tier:Z,text:Xz(J,"utf8")}})}function I8($){return[...w1(QZ(),"global"),...w1(ZZ($),"project")]}function m1($){return C$(H($),"rule-spawn-links.jsonl")}function u1($,Z){try{_(m1($),Z)}catch{}}function g1($){try{return T(m1($),y1)}catch{return[]}}function I$($,Z){try{_(v1($),Z)}catch{}}function _8($){try{return T(v1($),y1)}catch{return[]}}function _$($,Z){if(!Z.enabled)return{rules:[],disabled:[],errors:[]};return C8(I8($))}function p1($,Z,Q){let J=_$($,Z).rules;if($Z(Q)!==null)return B8(J,"subagent");let q=e2(Q);return q!==null&&B8(J,q.kind)}function c1($,Z,Q,J){if(!Z.enabled)return;let q=$Z(Q);if(q!==null){u1($,{...q,at:J.at});return}let X=O8(S1(Q,()=>g1($)),J);if(X!==null)I$($,X)}function d1($,Z){return B8(_$($,Z).rules,"gate")}function l1($,Z,Q,J){if(!Z.enabled)return;I$($,F8(Q,J))}var h1={decision:{kind:"abstain"},outcomes:[],errors:[]};function i1($,Z,Q,J){return a1($,Z,Q,J,U8)}function n1($,Z,Q){return a1($,Z,{event:"stop"},Q,M8)}function a1($,Z,Q,J,q){let X=_$($,Z);if(X.rules.length===0&&X.errors.length===0)return h1;let z=G8(X.rules,Q);if(z.length===0)return{...h1,errors:X.errors};let W=H8(z,_8($),J),Y=K8(W);return{decision:Y===null?{kind:"abstain"}:q(Y),outcomes:W,errors:X.errors}}import{existsSync as Wz,mkdirSync as Yz,readFileSync as Vz,writeFileSync as Gz}from"node:fs";import{join as Bz}from"node:path";function s1($){return Bz(H($),"shell-stall.json")}function r1($){let Z=s1($);if(!Wz(Z))return{};try{return JSON.parse(Vz(Z,"utf8"))}catch{return{}}}function o1($,Z){try{Yz(H($),{recursive:!0}),Gz(s1($),`${JSON.stringify(Z,null,2)}
122
+ ${$.body.trim()}`}function H8($,Z,Q){let J=[];for(let q of $){let X=R1(q,Z,Q);if(X.length===0)continue;let z=X.map(E1);J.push({rule:q,verdict:t2(q.otherwise,Q.mode),missing:z,message:o4(q,z,Q.shaRoot,Q.sha)})}return J}var x1={warn:0,"follow-up":1,ask:2,deny:3};function K8($){return $.reduce((Z,Q)=>Z===null||x1[Q.verdict]>x1[Z.verdict]?Q:Z,null)}function U8($){let Z=`rule:${$.rule.name}`;if($.verdict==="deny")return{kind:"deny",reason:$.message,rule:Z};if($.verdict==="ask")return{kind:"ask",reason:$.message,userNote:$.message,rule:Z};return{kind:"abstain"}}function M8($){switch($.verdict){case"deny":case"ask":return{kind:"continue",text:`BLOCKED: ${$.message}`};case"follow-up":return{kind:"continue",text:`NEED: ${$.message}`};case"warn":return{kind:"context",text:`ADVISORY: ${$.message}`}}}function e2($){if($.event==="subagent.stop"){let Z=$.spawnSubagentType??$.spawnAgentLabel;return Z===void 0?null:{kind:"subagent",value:Z}}if($.event==="tool.after"||$.event==="shell.after")return $.command===void 0?null:{kind:"command",value:$.command};if($.event==="edit.after")return $.filePath===void 0?null:{kind:"file",value:$.filePath};return null}function O8($,Z){let Q=e2($);return Q===null?null:{...Q,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function F8($,Z){return{kind:"gate",value:$,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function $Z($){if($.event!=="tool.after"||!t4.has($.toolName??""))return null;let{spawnAgentLabel:Z,spawnSubagentType:Q}=$;return Z===void 0||Q===void 0||Z===Q?null:{label:Z,type:Q}}var t4=new Set(["Task","Agent"]);function S1($,Z){if($.event!=="subagent.stop"||$.spawnSubagentType!==void 0)return $;let Q=$.spawnAgentLabel;if(Q===void 0)return $;let J=Z().filter((X)=>X.label===Q),q=J[J.length-1];return q===void 0?$:{...$,spawnSubagentType:q.type}}var b1=new Set(["deny","ask","follow-up","warn"]),f1=new Set(["subagent","command","gate","file"]);var e4=new Set(["pr-open","commit","push","stop"]);function $z($){let Z=$.trim();if(e4.has(Z))return{kind:Z};let Q=/^(tool|command)\(([^)]*)\)$/.exec(Z),J=Q?.[1],q=Q?.[2]?.trim();if(J===void 0||q===void 0||q==="")return`unknown trigger "${Z}" — use one of pr-open, commit, push, stop, tool(<name>), command(<pattern>)`;return J==="tool"?{kind:"tool",name:q}:{kind:"command",pattern:q}}function Zz($){let[Z,...Q]=$.trim().split(/\s+since\s+/i),J=/^([a-z]+)\(([^)]*)\)$/.exec((Z??"").trim()),q=J?.[1],X=J?.[2]?.trim();if(q===void 0||!f1.has(q)||X===void 0||X==="")return`unknown proof "${$.trim()}" — use subagent(<type>), command(<pattern>), gate(<name>) or file(<glob>)`;let z=(Q[0]??"head").trim().toLowerCase();if(z!=="head"&&z!=="session")return`unknown window "since ${z}" in "${$.trim()}" — use since HEAD or since session`;return{kind:q,value:X,since:z}}function Qz($){let Z=(G)=>({error:{name:$.name,tier:$.tier,error:G}}),{doc:Q,error:J}=n2($.text);if(Q===null)return Z(J??"unreadable");let q=Q.fields.enabled,X=q===void 0?!0:String(q).trim()!=="false",z=Q.fields.on;if(typeof z!=="string"||z.trim()==="")return Z("no `on:` trigger");let W=$z(z);if(typeof W==="string")return Z(W);let Y=Q.fields.otherwise;if(typeof Y!=="string"||!b1.has(Y.trim()))return Z("`otherwise:` must be one of deny, ask, follow-up, warn");let V=[];for(let G of O1(Q.fields.require)){let B=Zz(G);if(typeof B==="string")return Z(B);V.push(B)}if(V.length===0&&X)return Z("no `require:` proof, so nothing could ever satisfy this rule");return{rule:{name:$.name,tier:$.tier,enabled:X,on:W,require:V,otherwise:Y.trim(),body:Q.body}}}function C8($){let Z=new Map,Q=[];for(let q of["global","project"])for(let X of $.filter((z)=>z.tier===q)){let z=Qz(X);if("error"in z){Q.push(z.error);continue}Z.set(z.rule.name,z.rule)}let J=[...Z.values()];return{rules:J.filter((q)=>q.enabled),disabled:J.filter((q)=>!q.enabled),errors:Q}}import{existsSync as Jz,readdirSync as qz,readFileSync as Xz}from"node:fs";import{basename as zz,join as C$}from"node:path";var y1=500;function v1($){return C$(H($),"rule-observations.jsonl")}function ZZ($){return C$(H($),"..","rules")}function QZ(){return C$(g(),"rules")}function w1($,Z){if(!Jz($))return[];return qz($,{withFileTypes:!0}).filter((Q)=>Q.isFile()&&Q.name.endsWith(".md")).map((Q)=>{let J=C$($,Q.name);return{name:zz(Q.name,".md"),tier:Z,text:Xz(J,"utf8")}})}function I8($){return[...w1(QZ(),"global"),...w1(ZZ($),"project")]}function m1($){return C$(H($),"rule-spawn-links.jsonl")}function u1($,Z){try{_(m1($),Z)}catch{}}function g1($){try{return T(m1($),y1)}catch{return[]}}function I$($,Z){try{_(v1($),Z)}catch{}}function _8($){try{return T(v1($),y1)}catch{return[]}}function _$($,Z){if(!Z.enabled)return{rules:[],disabled:[],errors:[]};return C8(I8($))}function p1($,Z,Q){let J=_$($,Z).rules;if($Z(Q)!==null)return B8(J,"subagent");let q=e2(Q);return q!==null&&B8(J,q.kind)}function c1($,Z,Q,J){if(!Z.enabled)return;let q=$Z(Q);if(q!==null){u1($,{...q,at:J.at});return}let X=O8(S1(Q,()=>g1($)),J);if(X!==null)I$($,X)}function d1($,Z){return B8(_$($,Z).rules,"gate")}function l1($,Z,Q,J){if(!Z.enabled)return;I$($,F8(Q,J))}var h1={decision:{kind:"abstain"},outcomes:[],errors:[]};function i1($,Z,Q,J){return a1($,Z,Q,J,U8)}function n1($,Z,Q){return a1($,Z,{event:"stop"},Q,M8)}function a1($,Z,Q,J,q){let X=_$($,Z);if(X.rules.length===0&&X.errors.length===0)return h1;let z=G8(X.rules,Q);if(z.length===0)return{...h1,errors:X.errors};let W=H8(z,_8($),J),Y=K8(W);return{decision:Y===null?{kind:"abstain"}:q(Y),outcomes:W,errors:X.errors}}import{existsSync as Wz,mkdirSync as Yz,readFileSync as Vz,writeFileSync as Gz}from"node:fs";import{join as Bz}from"node:path";function s1($){return Bz(H($),"shell-stall.json")}function r1($){let Z=s1($);if(!Wz(Z))return{};try{return JSON.parse(Vz(Z,"utf8"))}catch{return{}}}function o1($,Z){try{Yz(H($),{recursive:!0}),Gz(s1($),`${JSON.stringify(Z,null,2)}
123
123
  `,"utf8")}catch{}}function Hz($){return $.trim().replace(/\s+/g," ").slice(0,300)}function t1($,Z,Q){let J=Hz(Q);if(!J)return 0;let q=r1($),X=q[Z]??{hits:0},z=X.lastCommand===J?{lastCommand:J,hits:X.hits+1}:{lastCommand:J,hits:1};return q[Z]=z,o1($,q),z.hits}function e1($,Z){let Q=r1($);Q[Z]={hits:0},o1($,Q)}var Kz=new Set(["command","doas","env","nice","nohup","sudo","time","xargs"]),Uz=new Set(["halt","poweroff","reboot","shutdown"]),Mz=new Set(["curl","ftp","gh","nc","ncat","rsync","scp","sftp","ssh","telnet","wget"]),Oz=new Set(["cp","mv","rm","rmdir","tee","truncate"]),Fz=new Set(["chmod","chown"]),Cz=/^\/dev\/(sd|nvme|vd|hd|disk)/;function Iz($){let Z=0;while(Z<$.length){let Q=$[Z];if(!Q)break;if(Kz.has(Q.text)||Q.text.startsWith("-")||Q.text.includes("=")){Z+=1;continue}let J=Q.text.split("/").pop()??Q.text,X=$.slice(Z+1).map((z)=>z.text);if(Uz.has(J)||J==="mkfs"||J.startsWith("mkfs."))return"destructive";if(J==="dd"&&X.some((z)=>z.startsWith("of=")&&Cz.test(z.slice(3))))return"destructive";if(J==="diskutil"&&X.some((z)=>z.startsWith("erase")||z.startsWith("partition")))return"destructive";if(J==="rm"&&X.some((z)=>z==="/"||z==="/*"||z.startsWith("../../")))return"destructive";if(Mz.has(J))return"network";if((J==="git"||J==="docker")&&X.includes("push"))return"network";if(Oz.has(J)||J==="sed"&&X.includes("-i"))return"write";if(Fz.has(J))return"privilege";if(X.includes(">"))return"write";return X.includes(">>")?"write-preserving":"read"}return"read"}var $7=["read","write-preserving","write","privilege","network","destructive"];function Q7($){let Z="read";for(let Q of k($)){let J=Iz(Q.words);if($7.indexOf(J)>$7.indexOf(Z))Z=J}return Z}function _z($){return Q7($)==="destructive"}function Nz($,Z){return[`BLOCKED: shell stall — the same command was attempted ${Z} times.`,`TRIED: \`${$.slice(0,160)}\``,"NEED: change approach. Do not repeat this command. Diagnose why it failed, use a different tool/path, or escalate with BLOCKED/TRIED/NEED."].join(`
124
124
  `)}var Pz=new Set(["write","privilege","network"]),JZ={catastrophic:"shell-catastrophic",posture:"shell-posture-paired",stall:"shell-stall"},Lz={network:"reaches the network, so it leaves this machine and cannot be pulled back",privilege:"changes who can reach a path, and that will not appear in any diff",write:"can overwrite or remove a path that already exists"};function Z7($){return Lz[$]??"changes something outside this turn"}function Tz($,Z){if(Z!=="paired")return null;let Q=Q7($);if(!Pz.has(Q))return null;return{kind:"ask",reason:`Posture paired: this command ${Z7(Q)}, and the operator asked to see these before they run. Wait for their answer — the posture is theirs to change, not yours.`,userNote:`Paired posture: this ${Q} command ${Z7(Q)}. Approve it, or leave the posture with \`tlc harness mode solo\`.`,rule:JZ.posture}}function J7($){let Z=$.command;if(!Z)return{kind:"allow"};if($.catastrophicAsk&&_z(Z))return{kind:"ask",reason:"The command was flagged as potentially catastrophic. Prefer scoped paths inside the repo or reversible operations.",userNote:"This shell command can destroy data outside the workspace. Approve only if you intend it.",rule:JZ.catastrophic};let Q=Tz(Z,$.mode);if(Q)return Q;if($.stallDetection){let J=t1($.projectDir,$.sessionKey,Z);if(J>=$.stallRepeatThreshold)return{kind:"deny",reason:Nz(Z,J),userNote:`Harness blocked a repeated shell command (${J}x).`,rule:JZ.stall}}return{kind:"allow"}}function jz($){return[$.command??"",...$.args??[]].join(" ")}function qZ($,Z){for(let Q of Object.values($.hooks??{}))for(let J of Q)for(let q of J.hooks??[]){let X=jz(q);if(X.includes("tlc-exec")&&new RegExp(`(^|\\s)${Z}(\\s|$)`).test(X))return!0}return!1}function q7($,Z){if($===null)return{run:!0,reason:"no user-level settings — this shim is the only hook for this event"};return qZ($,Z)?{run:!1,reason:`a user-level hook already runs ${Z} — standing down to avoid a second run`}:{run:!0,reason:`no user-level hook runs ${Z}`}}function X7($,Z,Q){let J=`${$}/skills/harness-init`;return Z.filter((q)=>Q(q)).map((q)=>({providerDir:q,source:J,target:`${q}/skills/harness-init`}))}function z7($,Z,Q){let J=Q.linkTarget($);if(J===null)return{state:"absent",target:$};if(!Q.exists(J))return{state:"dangling",target:$,resolved:J};let X=(Q.realpath??((z)=>z))(Z).replace(/\/+$/,"");return J===X||J.startsWith(`${X}/`)?{state:"ok",target:$,resolved:J}:{state:"outside-runtime",target:$,resolved:J}}function W7($){switch($.state){case"ok":return`linked → ${$.resolved}`;case"dangling":return`points at ${$.resolved}, which does not exist — re-run \`tlc harness install\``;case"outside-runtime":return`points at ${$.resolved}, outside the runtime — it will break when that path goes`;default:return"not linked — the provider cannot see the init skill"}}import{existsSync as Dz,mkdirSync as Az,readFileSync as Rz,writeFileSync as Ez}from"node:fs";import{join as kz}from"node:path";var Y7=200,xz=8;function V7($){return kz(H($),"fingerprint-resolutions.json")}function G7($){let Z=V7($);if(!Dz(Z))return{};try{let Q=JSON.parse(Rz(Z,"utf8"));return Q&&typeof Q==="object"?Q:{}}catch{return{}}}function Sz($){let Z=Object.entries($);if(Z.length<=Y7)return $;let Q=Z.sort((J,q)=>q[1].at.localeCompare(J[1].at)).slice(0,Y7);return Object.fromEntries(Q)}function B7($,Z,Q){let J=G7($);J[Z]={...Q,files:Q.files.slice(0,xz)};let q=Sz(J);try{Az(H($),{recursive:!0}),Ez(V7($),`${JSON.stringify(q,null,2)}
125
125
  `,"utf8")}catch{}return q}function H7($,Z){return G7($)[Z]??null}function K7($){return`History: this same ${$.gate} failure was resolved once before, after changes to ${$.files.join(", ")}. That is a record of what happened, not a list to edit — confirm it against this failure before acting on it.`}import{createHash as bz}from"node:crypto";function U7($){let Z=$.output.replace(/\d{4}-\d{2}-\d{2}T[\d:.]+Z/g,"<ts>").replace(/\b\d{5,}\b/g,"<n>").slice(0,1500),Q=JSON.stringify({files:[...$.files].sort(),gate:$.gate,exitCode:$.exitCode,output:Z});return bz("sha256").update(Q).digest("hex").slice(0,16)}import{existsSync as fz,mkdirSync as wz,readFileSync as yz,writeFileSync as vz}from"node:fs";import{join as mz}from"node:path";function M7($){return mz(H($),"fingerprint.json")}function XZ($){let Z=M7($);if(!fz(Z))return{};try{return JSON.parse(yz(Z,"utf8"))}catch{return{}}}function O7($,Z){try{wz(H($),{recursive:!0}),vz(M7($),`${JSON.stringify(Z,null,2)}