@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(N.bar)} ${z.detail}`:K});return[Z.heading(`LAST ${$.leng
117
117
  `))return null;let Z=$.indexOf(`
118
118
  `),J=$.slice(Z+1),Q=/^---\s*$/m.exec(J);if(!Q)return null;return{block:J.slice(0,Q.index),bodyAt:Z+1+Q.index+Q[0].length}}function dZ($){let Z=$.trim();if(Z.length>=2){let J=Z[0],Q=Z[Z.length-1];if(J==='"'&&Q==='"'||J==="'"&&Q==="'")return Z.slice(1,-1)}return Z}function lZ($){return $.replace(/\\(["'\\])/g,"$1")}function s4($){let Z=$.trim();if(Z.startsWith("[")&&Z.endsWith("]")){let J=Z.slice(1,-1).trim();if(J==="")return[];return J.split(",").map((Q)=>lZ(dZ(Q)))}return lZ(dZ(Z))}function iZ($){let Z=a4($);if(Z===null)return{doc:null,error:"missing --- frontmatter block"};let J={},Q=null;for(let q of Z.block.split(`
119
119
  `)){let X=q.trim();if(X===""||X.startsWith("#"))continue;if(X.startsWith("- ")){if(Q===null)return{doc:null,error:`list item with no key above it: "${X}"`};let V=J[Q],G=lZ(dZ(X.slice(2)));J[Q]=Array.isArray(V)?[...V,G]:[G];continue}let W=X.indexOf(":");if(W===-1)return{doc:null,error:`unparseable frontmatter line: "${X}"`};let z=X.slice(0,W).trim();if(z==="")return{doc:null,error:`frontmatter line has an empty key: "${X}"`};let Y=X.slice(W+1);if(Y.trim()===""){J[z]=[],Q=z;continue}J[z]=s4(Y),Q=null}return{doc:{fields:J,body:$.slice(Z.bodyAt).trim()},error:null}}function Y8($,Z){let{doc:J}=iZ($),Q=J?.fields[Z];if(typeof Q!=="string"||Q.trim()==="")return;return Q.trim()}function _6($){if($===void 0)return[];return(Array.isArray($)?$:[$]).filter((Z)=>Z!=="")}function N6($){return V8($,"docs","decisions")}function nZ($,Z){let J=V8(N6($),Z);if(!P6(J))return null;let Q;try{Q=t4(J,"utf8")}catch{return null}let q=Y8(Q,"title");if(q===void 0)return null;let X=(Z.split(/[\\/]/).pop()??Z).replace(/\.md$/,"").toUpperCase(),W=Y8(Q,"migration"),z=Y8(Q,"timestamp");return{id:X,title:q,path:`/decisions/${Z.split(/[\\/]/).join("/")}`,...W===void 0?{}:{migration:W},...z===void 0?{}:{timestamp:z}}}function j6($,Z){return Z.filter((J)=>/(?:^|[\\/])ad-\d+\.md$/.test(J)).map((J)=>nZ($,J)).filter((J)=>J!==null).sort((J,Q)=>J.id.localeCompare(Q.id))}var e4="archived";function L6($){let Z=N6($),J=[];for(let Q of["",e4]){let q=Q===""?Z:V8(Z,Q);if(!P6(q))continue;try{for(let X of o4(q))if(/^ad-\d+\.md$/.test(X))J.push(Q===""?X:V8(Q,X))}catch{}}return J}function rZ($){return $.filter((Z)=>Z.migration!==void 0)}function I6($){return $.id}function A6($){if($.length===0)return"";let Z=rZ($),J=[`Harness updated. ${$.length} decision(s) landed; doctor runs below and reports what applies here.`];if(Z.length>0){J.push("",`Needs a change doctor cannot detect for you (${Z.length}):`);for(let q of Z)J.push(` ${q.migration} (${I6(q)})`)}let Q=$.filter((q)=>q.migration===void 0);if(Q.length>0)J.push("",`Also landed: ${Q.map(I6).join(", ")} — docs/decisions/index.md`);else J.push("","Full reasoning: docs/decisions/index.md");return J.join(`
120
- `)}import{existsSync as $W,readFileSync as ZW}from"node:fs";import{join as JW}from"node:path";function D6($){return JW(H($),"release-seen.json")}function T6($){let Z=D6($);if(!$W(Z))return null;try{let J=JSON.parse(ZW(Z,"utf8"));return typeof J?.revision==="string"&&J.revision!==""?J:null}catch{return null}}async function R6($,Z){await q$(D6($),{revision:Z,updatedAt:new Date().toISOString()})}var QW={"pr-open":[{prefix:["gh","pr","create"],excludeIfAny:["--draft","-d"]},{prefix:["gh","pr","ready"]}],commit:[{prefix:["git","commit"]}],push:[{prefix:["git","push"]}]};function E6($){return b($).map((Z)=>Z.words.map((J)=>J.text)).filter((Z)=>Z.length>0)}function qW($,Z){return Z.every((J,Q)=>$[Q]===J)}function XW($,Z){if(!qW($,Z.prefix))return!1;return!Z.excludeIfAny?.some((J)=>$.includes(J))}function aZ($,Z){let J=Z.trim().split(/\s+/);if(J.length===0)return!1;return $.some((Q,q)=>J.every((X,W)=>$[q+W]===X))}function sZ($,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 J=QW[$.kind];return E6(Z.command).some((Q)=>J.some((q)=>XW(Q,q)))}default:{if(Z.command===void 0)return!1;return E6(Z.command).some((J)=>aZ(J,$.pattern))}}}function G8($,Z){return $.filter((J)=>J.enabled&&sZ(J.on,Z))}function WW($,Z){if($===Z)return!0;if($.startsWith("*"))return Z.endsWith($.slice(1));if($.endsWith("/"))return Z.startsWith($);return!1}function k6($,Z){if($.kind!==Z.kind)return!1;switch($.kind){case"command":return aZ(Z.value.split(/\s+/),$.value);case"file":return WW($.value,Z.value);default:return Z.value===$.value}}function zW($,Z,J){if($.since==="session")return Z.sessionKey===J.sessionKey;return J.sha!==null&&Z.sha===J.sha}function YW($,Z,J){return Z.some((Q)=>k6($,Q)&&zW($,Q,J))}function VW($,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 x6($,Z,J){return $.require.filter((Q)=>!YW(Q,Z,J)).map((Q)=>({proof:Q,reason:Z.some((q)=>k6(Q,q))?VW(Q,J):null}))}function S6($){let{proof:Z,reason:J}=$,Q=`${Z.kind}(${Z.value}) since ${Z.since==="head"?"HEAD":"session"}`;return J===null?Q:`${Q} (${J})`}function B8($,Z){return $.some((J)=>J.require.some((Q)=>Q.kind===Z))}function f6($,Z){let J=new Set(Z.map((Q)=>Q.kind));return $.map((Q)=>({rule:Q.name,kinds:[...new Set(Q.require.map((q)=>q.kind))].filter((q)=>!J.has(q))})).filter((Q)=>Q.kinds.length>0)}function oZ($,Z){return $==="ask"&&Z!=="paired"?"deny":$}function GW($,Z){let J=`rule ${$.name} (${$.tier}): missing ${Z.join(", ")}`;return $.body.trim()===""?J:`${J}
120
+ `)}import{existsSync as $W,readFileSync as ZW}from"node:fs";import{join as JW}from"node:path";function D6($){return JW(H($),"release-seen.json")}function T6($){let Z=D6($);if(!$W(Z))return null;try{let J=JSON.parse(ZW(Z,"utf8"));return typeof J?.revision==="string"&&J.revision!==""?J:null}catch{return null}}async function R6($,Z){await q$(D6($),{revision:Z,updatedAt:new Date().toISOString()})}var QW={"pr-open":[{prefix:["gh","pr","create"],excludeIfAny:["--draft","-d"]},{prefix:["gh","pr","ready"]}],commit:[{prefix:["git","commit"]}],push:[{prefix:["git","push"]}]};function E6($){return b($).map((Z)=>Z.words.map((J)=>J.text)).filter((Z)=>Z.length>0)}function qW($,Z){return Z.every((J,Q)=>$[Q]===J)}function XW($,Z){if(!qW($,Z.prefix))return!1;return!Z.excludeIfAny?.some((J)=>$.includes(J))}function aZ($,Z){let J=Z.trim().split(/\s+/);if(J.length===0)return!1;return $.some((Q,q)=>J.every((X,W)=>$[q+W]===X))}function sZ($,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 J=QW[$.kind];return E6(Z.command).some((Q)=>J.some((q)=>XW(Q,q)))}default:{if(Z.command===void 0)return!1;return E6(Z.command).some((J)=>aZ(J,$.pattern))}}}function G8($,Z){return $.filter((J)=>J.enabled&&sZ(J.on,Z))}function WW($,Z){if($===Z)return!0;if($.startsWith("*"))return Z.endsWith($.slice(1));if($.endsWith("/"))return Z.startsWith($);return!1}function k6($,Z){if($.kind!==Z.kind)return!1;switch($.kind){case"command":return aZ(Z.value.split(/\s+/),$.value);case"file":return WW($.value,Z.value);default:return Z.value===$.value}}function zW($,Z,J){if($.since==="session")return Z.sessionKey===J.sessionKey;return J.sha!==null&&Z.sha===J.sha}function YW($,Z,J){return Z.some((Q)=>k6($,Q)&&zW($,Q,J))}function VW($,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 x6($,Z,J){return $.require.filter((Q)=>!YW(Q,Z,J)).map((Q)=>({proof:Q,reason:Z.some((q)=>k6(Q,q))?VW(Q,J):null}))}function S6($){let{proof:Z,reason:J}=$,Q=`${Z.kind}(${Z.value}) since ${Z.since==="head"?"HEAD":"session"}`;return J===null?Q:`${Q} (${J})`}function B8($,Z){return $.some((J)=>J.require.some((Q)=>Q.kind===Z))}function f6($,Z){let J=new Set(Z.map((Q)=>Q.kind));return $.map((Q)=>({rule:Q.name,kinds:[...new Set(Q.require.map((q)=>q.kind))].filter((q)=>!J.has(q))})).filter((Q)=>Q.kinds.length>0)}function oZ($,Z){return $==="ask"&&Z!=="paired"?"deny":$}function GW($,Z,J,Q){let q=`rule ${$.name} (${$.tier}): missing ${Z.join(", ")} — checked ${J} at ${Q??"no HEAD"}`;return $.body.trim()===""?q:`${q}
121
121
 
122
- ${$.body.trim()}`}function U8($,Z,J){let Q=[];for(let q of $){let X=x6(q,Z,J);if(X.length===0)continue;let W=X.map(S6);Q.push({rule:q,verdict:oZ(q.otherwise,J.mode),missing:W,message:GW(q,W)})}return Q}var b6={warn:0,"follow-up":1,ask:2,deny:3};function H8($){return $.reduce((Z,J)=>Z===null||b6[J.verdict]>b6[Z.verdict]?J:Z,null)}function K8($){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 tZ($){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 F8($,Z){let J=tZ($);return J===null?null:{...J,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function C8($,Z){return{kind:"gate",value:$,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function eZ($){if($.event!=="tool.after"||!BW.has($.toolName??""))return null;let{spawnAgentLabel:Z,spawnSubagentType:J}=$;return Z===void 0||J===void 0||Z===J?null:{label:Z,type:J}}var BW=new Set(["Task","Agent"]);function y6($,Z){if($.event!=="subagent.stop"||$.spawnSubagentType!==void 0)return $;let J=$.spawnAgentLabel;if(J===void 0)return $;let Q=Z().filter((X)=>X.label===J),q=Q[Q.length-1];return q===void 0?$:{...$,spawnSubagentType:q.type}}var w6=new Set(["deny","ask","follow-up","warn"]),v6=new Set(["subagent","command","gate","file"]);var UW=new Set(["pr-open","commit","push","stop"]);function HW($){let Z=$.trim();if(UW.has(Z))return{kind:Z};let J=/^(tool|command)\(([^)]*)\)$/.exec(Z),Q=J?.[1],q=J?.[2]?.trim();if(Q===void 0||q===void 0||q==="")return`unknown trigger "${Z}" — use one of pr-open, commit, push, stop, tool(<name>), command(<pattern>)`;return Q==="tool"?{kind:"tool",name:q}:{kind:"command",pattern:q}}function KW($){let[Z,...J]=$.trim().split(/\s+since\s+/i),Q=/^([a-z]+)\(([^)]*)\)$/.exec((Z??"").trim()),q=Q?.[1],X=Q?.[2]?.trim();if(q===void 0||!v6.has(q)||X===void 0||X==="")return`unknown proof "${$.trim()}" — use subagent(<type>), command(<pattern>), gate(<name>) or file(<glob>)`;let W=(J[0]??"head").trim().toLowerCase();if(W!=="head"&&W!=="session")return`unknown window "since ${W}" in "${$.trim()}" — use since HEAD or since session`;return{kind:q,value:X,since:W}}function MW($){let Z=(G)=>({error:{name:$.name,tier:$.tier,error:G}}),{doc:J,error:Q}=iZ($.text);if(J===null)return Z(Q??"unreadable");let q=J.fields.enabled,X=q===void 0?!0:String(q).trim()!=="false",W=J.fields.on;if(typeof W!=="string"||W.trim()==="")return Z("no `on:` trigger");let z=HW(W);if(typeof z==="string")return Z(z);let Y=J.fields.otherwise;if(typeof Y!=="string"||!w6.has(Y.trim()))return Z("`otherwise:` must be one of deny, ask, follow-up, warn");let V=[];for(let G of _6(J.fields.require)){let B=KW(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:z,require:V,otherwise:Y.trim(),body:J.body}}}function O8($){let Z=new Map,J=[];for(let q of["global","project"])for(let X of $.filter((W)=>W.tier===q)){let W=MW(X);if("error"in W){J.push(W.error);continue}Z.set(W.rule.name,W.rule)}let Q=[...Z.values()];return{rules:Q.filter((q)=>q.enabled),disabled:Q.filter((q)=>!q.enabled),errors:J}}import{existsSync as FW,readdirSync as CW,readFileSync as OW}from"node:fs";import{basename as _W,join as O$}from"node:path";var g6=500;function u6($){return O$(H($),"rule-observations.jsonl")}function $2($){return O$(H($),"..","rules")}function Z2(){return O$(L$(),"rules")}function m6($,Z){if(!FW($))return[];return CW($,{withFileTypes:!0}).filter((J)=>J.isFile()&&J.name.endsWith(".md")).map((J)=>{let Q=O$($,J.name);return{name:_W(J.name,".md"),tier:Z,text:OW(Q,"utf8")}})}function _8($){return[...m6(Z2(),"global"),...m6($2($),"project")]}function h6($){return O$(H($),"rule-spawn-links.jsonl")}function p6($,Z){try{A(h6($),Z)}catch{}}function c6($){try{return T(h6($),g6)}catch{return[]}}function _$($,Z){try{A(u6($),Z)}catch{}}function I8($){try{return T(u6($),g6)}catch{return[]}}function I$($,Z){if(!Z.enabled)return{rules:[],disabled:[],errors:[]};return O8(_8($))}function l6($,Z,J){let Q=I$($,Z).rules;if(eZ(J)!==null)return B8(Q,"subagent");let q=tZ(J);return q!==null&&B8(Q,q.kind)}function i6($,Z,J,Q){if(!Z.enabled)return;let q=eZ(J);if(q!==null){p6($,{...q,at:Q.at});return}let X=F8(y6(J,()=>c6($)),Q);if(X!==null)_$($,X)}function n6($,Z){return B8(I$($,Z).rules,"gate")}function r6($,Z,J,Q){if(!Z.enabled)return;_$($,C8(J,Q))}var d6={decision:{kind:"abstain"},outcomes:[],errors:[]};function a6($,Z,J,Q){return o6($,Z,J,Q,K8)}function s6($,Z,J){return o6($,Z,{event:"stop"},J,M8)}function o6($,Z,J,Q,q){let X=I$($,Z);if(X.rules.length===0&&X.errors.length===0)return d6;let W=G8(X.rules,J);if(W.length===0)return{...d6,errors:X.errors};let z=U8(W,I8($),Q),Y=H8(z);return{decision:Y===null?{kind:"abstain"}:q(Y),outcomes:z,errors:X.errors}}import{existsSync as IW,mkdirSync as PW,readFileSync as NW,writeFileSync as jW}from"node:fs";import{join as LW}from"node:path";function t6($){return LW(H($),"shell-stall.json")}function e6($){let Z=t6($);if(!IW(Z))return{};try{return JSON.parse(NW(Z,"utf8"))}catch{return{}}}function $7($,Z){try{PW(H($),{recursive:!0}),jW(t6($),`${JSON.stringify(Z,null,2)}
122
+ ${$.body.trim()}`}function U8($,Z,J){let Q=[];for(let q of $){let X=x6(q,Z,J);if(X.length===0)continue;let W=X.map(S6);Q.push({rule:q,verdict:oZ(q.otherwise,J.mode),missing:W,message:GW(q,W,J.shaRoot,J.sha)})}return Q}var b6={warn:0,"follow-up":1,ask:2,deny:3};function H8($){return $.reduce((Z,J)=>Z===null||b6[J.verdict]>b6[Z.verdict]?J:Z,null)}function K8($){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 tZ($){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 F8($,Z){let J=tZ($);return J===null?null:{...J,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function C8($,Z){return{kind:"gate",value:$,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function eZ($){if($.event!=="tool.after"||!BW.has($.toolName??""))return null;let{spawnAgentLabel:Z,spawnSubagentType:J}=$;return Z===void 0||J===void 0||Z===J?null:{label:Z,type:J}}var BW=new Set(["Task","Agent"]);function y6($,Z){if($.event!=="subagent.stop"||$.spawnSubagentType!==void 0)return $;let J=$.spawnAgentLabel;if(J===void 0)return $;let Q=Z().filter((X)=>X.label===J),q=Q[Q.length-1];return q===void 0?$:{...$,spawnSubagentType:q.type}}var w6=new Set(["deny","ask","follow-up","warn"]),v6=new Set(["subagent","command","gate","file"]);var UW=new Set(["pr-open","commit","push","stop"]);function HW($){let Z=$.trim();if(UW.has(Z))return{kind:Z};let J=/^(tool|command)\(([^)]*)\)$/.exec(Z),Q=J?.[1],q=J?.[2]?.trim();if(Q===void 0||q===void 0||q==="")return`unknown trigger "${Z}" — use one of pr-open, commit, push, stop, tool(<name>), command(<pattern>)`;return Q==="tool"?{kind:"tool",name:q}:{kind:"command",pattern:q}}function KW($){let[Z,...J]=$.trim().split(/\s+since\s+/i),Q=/^([a-z]+)\(([^)]*)\)$/.exec((Z??"").trim()),q=Q?.[1],X=Q?.[2]?.trim();if(q===void 0||!v6.has(q)||X===void 0||X==="")return`unknown proof "${$.trim()}" — use subagent(<type>), command(<pattern>), gate(<name>) or file(<glob>)`;let W=(J[0]??"head").trim().toLowerCase();if(W!=="head"&&W!=="session")return`unknown window "since ${W}" in "${$.trim()}" — use since HEAD or since session`;return{kind:q,value:X,since:W}}function MW($){let Z=(G)=>({error:{name:$.name,tier:$.tier,error:G}}),{doc:J,error:Q}=iZ($.text);if(J===null)return Z(Q??"unreadable");let q=J.fields.enabled,X=q===void 0?!0:String(q).trim()!=="false",W=J.fields.on;if(typeof W!=="string"||W.trim()==="")return Z("no `on:` trigger");let z=HW(W);if(typeof z==="string")return Z(z);let Y=J.fields.otherwise;if(typeof Y!=="string"||!w6.has(Y.trim()))return Z("`otherwise:` must be one of deny, ask, follow-up, warn");let V=[];for(let G of _6(J.fields.require)){let B=KW(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:z,require:V,otherwise:Y.trim(),body:J.body}}}function O8($){let Z=new Map,J=[];for(let q of["global","project"])for(let X of $.filter((W)=>W.tier===q)){let W=MW(X);if("error"in W){J.push(W.error);continue}Z.set(W.rule.name,W.rule)}let Q=[...Z.values()];return{rules:Q.filter((q)=>q.enabled),disabled:Q.filter((q)=>!q.enabled),errors:J}}import{existsSync as FW,readdirSync as CW,readFileSync as OW}from"node:fs";import{basename as _W,join as O$}from"node:path";var g6=500;function u6($){return O$(H($),"rule-observations.jsonl")}function $2($){return O$(H($),"..","rules")}function Z2(){return O$(L$(),"rules")}function m6($,Z){if(!FW($))return[];return CW($,{withFileTypes:!0}).filter((J)=>J.isFile()&&J.name.endsWith(".md")).map((J)=>{let Q=O$($,J.name);return{name:_W(J.name,".md"),tier:Z,text:OW(Q,"utf8")}})}function _8($){return[...m6(Z2(),"global"),...m6($2($),"project")]}function h6($){return O$(H($),"rule-spawn-links.jsonl")}function p6($,Z){try{A(h6($),Z)}catch{}}function c6($){try{return T(h6($),g6)}catch{return[]}}function _$($,Z){try{A(u6($),Z)}catch{}}function I8($){try{return T(u6($),g6)}catch{return[]}}function I$($,Z){if(!Z.enabled)return{rules:[],disabled:[],errors:[]};return O8(_8($))}function l6($,Z,J){let Q=I$($,Z).rules;if(eZ(J)!==null)return B8(Q,"subagent");let q=tZ(J);return q!==null&&B8(Q,q.kind)}function i6($,Z,J,Q){if(!Z.enabled)return;let q=eZ(J);if(q!==null){p6($,{...q,at:Q.at});return}let X=F8(y6(J,()=>c6($)),Q);if(X!==null)_$($,X)}function n6($,Z){return B8(I$($,Z).rules,"gate")}function r6($,Z,J,Q){if(!Z.enabled)return;_$($,C8(J,Q))}var d6={decision:{kind:"abstain"},outcomes:[],errors:[]};function a6($,Z,J,Q){return o6($,Z,J,Q,K8)}function s6($,Z,J){return o6($,Z,{event:"stop"},J,M8)}function o6($,Z,J,Q,q){let X=I$($,Z);if(X.rules.length===0&&X.errors.length===0)return d6;let W=G8(X.rules,J);if(W.length===0)return{...d6,errors:X.errors};let z=U8(W,I8($),Q),Y=H8(z);return{decision:Y===null?{kind:"abstain"}:q(Y),outcomes:z,errors:X.errors}}import{existsSync as IW,mkdirSync as PW,readFileSync as NW,writeFileSync as jW}from"node:fs";import{join as LW}from"node:path";function t6($){return LW(H($),"shell-stall.json")}function e6($){let Z=t6($);if(!IW(Z))return{};try{return JSON.parse(NW(Z,"utf8"))}catch{return{}}}function $7($,Z){try{PW(H($),{recursive:!0}),jW(t6($),`${JSON.stringify(Z,null,2)}
123
123
  `,"utf8")}catch{}}function AW($){return $.trim().replace(/\s+/g," ").slice(0,300)}function Z7($,Z,J){let Q=AW(J);if(!Q)return 0;let q=e6($),X=q[Z]??{hits:0},W=X.lastCommand===Q?{lastCommand:Q,hits:X.hits+1}:{lastCommand:Q,hits:1};return q[Z]=W,$7($,q),W.hits}function J7($,Z){let J=e6($);J[Z]={hits:0},$7($,J)}var DW=new Set(["command","doas","env","nice","nohup","sudo","time","xargs"]),TW=new Set(["halt","poweroff","reboot","shutdown"]),RW=new Set(["curl","ftp","gh","nc","ncat","rsync","scp","sftp","ssh","telnet","wget"]),EW=new Set(["cp","mv","rm","rmdir","tee","truncate"]),kW=new Set(["chmod","chown"]),xW=/^\/dev\/(sd|nvme|vd|hd|disk)/;function SW($){let Z=0;while(Z<$.length){let J=$[Z];if(!J)break;if(DW.has(J.text)||J.text.startsWith("-")||J.text.includes("=")){Z+=1;continue}let Q=J.text.split("/").pop()??J.text,X=$.slice(Z+1).map((W)=>W.text);if(TW.has(Q)||Q==="mkfs"||Q.startsWith("mkfs."))return"destructive";if(Q==="dd"&&X.some((W)=>W.startsWith("of=")&&xW.test(W.slice(3))))return"destructive";if(Q==="diskutil"&&X.some((W)=>W.startsWith("erase")||W.startsWith("partition")))return"destructive";if(Q==="rm"&&X.some((W)=>W==="/"||W==="/*"||W.startsWith("../../")))return"destructive";if(RW.has(Q))return"network";if((Q==="git"||Q==="docker")&&X.includes("push"))return"network";if(EW.has(Q)||Q==="sed"&&X.includes("-i"))return"write";if(kW.has(Q))return"privilege";if(X.includes(">"))return"write";return X.includes(">>")?"write-preserving":"read"}return"read"}var Q7=["read","write-preserving","write","privilege","network","destructive"];function X7($){let Z="read";for(let J of b($)){let Q=SW(J.words);if(Q7.indexOf(Q)>Q7.indexOf(Z))Z=Q}return Z}function fW($){return X7($)==="destructive"}function bW($,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 yW=new Set(["write","privilege","network"]),J2={catastrophic:"shell-catastrophic",posture:"shell-posture-paired",stall:"shell-stall"},wW={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 q7($){return wW[$]??"changes something outside this turn"}function vW($,Z){if(Z!=="paired")return null;let J=X7($);if(!yW.has(J))return null;return{kind:"ask",reason:`Posture paired: this command ${q7(J)}, 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 ${J} command ${q7(J)}. Approve it, or leave the posture with \`tlc harness mode solo\`.`,rule:J2.posture}}function W7($){let Z=$.command;if(!Z)return{kind:"allow"};if($.catastrophicAsk&&fW(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:J2.catastrophic};let J=vW(Z,$.mode);if(J)return J;if($.stallDetection){let Q=Z7($.projectDir,$.sessionKey,Z);if(Q>=$.stallRepeatThreshold)return{kind:"deny",reason:bW(Z,Q),userNote:`Harness blocked a repeated shell command (${Q}x).`,rule:J2.stall}}return{kind:"allow"}}function mW($){return[$.command??"",...$.args??[]].join(" ")}function Q2($,Z){for(let J of Object.values($.hooks??{}))for(let Q of J)for(let q of Q.hooks??[]){let X=mW(q);if(X.includes("tlc-exec")&&new RegExp(`(^|\\s)${Z}(\\s|$)`).test(X))return!0}return!1}function z7($,Z){if($===null)return{run:!0,reason:"no user-level settings — this shim is the only hook for this event"};return Q2($,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 Y7($,Z,J){let Q=`${$}/skills/harness-init`;return Z.filter((q)=>J(q)).map((q)=>({providerDir:q,source:Q,target:`${q}/skills/harness-init`}))}function V7($,Z,J){let Q=J.linkTarget($);if(Q===null)return{state:"absent",target:$};if(!J.exists(Q))return{state:"dangling",target:$,resolved:Q};let X=(J.realpath??((W)=>W))(Z).replace(/\/+$/,"");return Q===X||Q.startsWith(`${X}/`)?{state:"ok",target:$,resolved:Q}:{state:"outside-runtime",target:$,resolved:Q}}function G7($){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 gW,mkdirSync as uW,readFileSync as hW,writeFileSync as pW}from"node:fs";import{join as cW}from"node:path";var B7=200,dW=8;function U7($){return cW(H($),"fingerprint-resolutions.json")}function H7($){let Z=U7($);if(!gW(Z))return{};try{let J=JSON.parse(hW(Z,"utf8"));return J&&typeof J==="object"?J:{}}catch{return{}}}function lW($){let Z=Object.entries($);if(Z.length<=B7)return $;let J=Z.sort((Q,q)=>q[1].at.localeCompare(Q[1].at)).slice(0,B7);return Object.fromEntries(J)}function K7($,Z,J){let Q=H7($);Q[Z]={...J,files:J.files.slice(0,dW)};let q=lW(Q);try{uW(H($),{recursive:!0}),pW(U7($),`${JSON.stringify(q,null,2)}
125
125
  `,"utf8")}catch{}return q}function M7($,Z){return H7($)[Z]??null}function F7($){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 iW}from"node:crypto";function C7($){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),J=JSON.stringify({files:[...$.files].sort(),gate:$.gate,exitCode:$.exitCode,output:Z});return iW("sha256").update(J).digest("hex").slice(0,16)}import{existsSync as nW,mkdirSync as rW,readFileSync as aW,writeFileSync as sW}from"node:fs";import{join as oW}from"node:path";function O7($){return oW(H($),"fingerprint.json")}function q2($){let Z=O7($);if(!nW(Z))return{};try{return JSON.parse(aW(Z,"utf8"))}catch{return{}}}function _7($,Z){try{rW(H($),{recursive:!0}),sW(O7($),`${JSON.stringify(Z,null,2)}
@@ -117,9 +117,9 @@ ${" ".repeat(4)}${Z.dim(L.bar)} ${z.detail}`:K});return[Z.heading(`LAST ${$.leng
117
117
  `))return null;let Z=$.indexOf(`
118
118
  `),J=$.slice(Z+1),Q=/^---\s*$/m.exec(J);if(!Q)return null;return{block:J.slice(0,Q.index),bodyAt:Z+1+Q.index+Q[0].length}}function iZ($){let Z=$.trim();if(Z.length>=2){let J=Z[0],Q=Z[Z.length-1];if(J==='"'&&Q==='"'||J==="'"&&Q==="'")return Z.slice(1,-1)}return Z}function nZ($){return $.replace(/\\(["'\\])/g,"$1")}function JW($){let Z=$.trim();if(Z.startsWith("[")&&Z.endsWith("]")){let J=Z.slice(1,-1).trim();if(J==="")return[];return J.split(",").map((Q)=>nZ(iZ(Q)))}return nZ(iZ(Z))}function rZ($){let Z=ZW($);if(Z===null)return{doc:null,error:"missing --- frontmatter block"};let J={},Q=null;for(let q of Z.block.split(`
119
119
  `)){let X=q.trim();if(X===""||X.startsWith("#"))continue;if(X.startsWith("- ")){if(Q===null)return{doc:null,error:`list item with no key above it: "${X}"`};let V=J[Q],G=nZ(iZ(X.slice(2)));J[Q]=Array.isArray(V)?[...V,G]:[G];continue}let W=X.indexOf(":");if(W===-1)return{doc:null,error:`unparseable frontmatter line: "${X}"`};let z=X.slice(0,W).trim();if(z==="")return{doc:null,error:`frontmatter line has an empty key: "${X}"`};let Y=X.slice(W+1);if(Y.trim()===""){J[z]=[],Q=z;continue}J[z]=JW(Y),Q=null}return{doc:{fields:J,body:$.slice(Z.bodyAt).trim()},error:null}}function G8($,Z){let{doc:J}=rZ($),Q=J?.fields[Z];if(typeof Q!=="string"||Q.trim()==="")return;return Q.trim()}function I6($){if($===void 0)return[];return(Array.isArray($)?$:[$]).filter((Z)=>Z!=="")}function j6($){return B8($,"docs","decisions")}function aZ($,Z){let J=B8(j6($),Z);if(!N6(J))return null;let Q;try{Q=qW(J,"utf8")}catch{return null}let q=G8(Q,"title");if(q===void 0)return null;let X=(Z.split(/[\\/]/).pop()??Z).replace(/\.md$/,"").toUpperCase(),W=G8(Q,"migration"),z=G8(Q,"timestamp");return{id:X,title:q,path:`/decisions/${Z.split(/[\\/]/).join("/")}`,...W===void 0?{}:{migration:W},...z===void 0?{}:{timestamp:z}}}function L6($,Z){return Z.filter((J)=>/(?:^|[\\/])ad-\d+\.md$/.test(J)).map((J)=>aZ($,J)).filter((J)=>J!==null).sort((J,Q)=>J.id.localeCompare(Q.id))}var XW="archived";function A6($){let Z=j6($),J=[];for(let Q of["",XW]){let q=Q===""?Z:B8(Z,Q);if(!N6(q))continue;try{for(let X of QW(q))if(/^ad-\d+\.md$/.test(X))J.push(Q===""?X:B8(Q,X))}catch{}}return J}function sZ($){return $.filter((Z)=>Z.migration!==void 0)}function P6($){return $.id}function D6($){if($.length===0)return"";let Z=sZ($),J=[`Harness updated. ${$.length} decision(s) landed; doctor runs below and reports what applies here.`];if(Z.length>0){J.push("",`Needs a change doctor cannot detect for you (${Z.length}):`);for(let q of Z)J.push(` ${q.migration} (${P6(q)})`)}let Q=$.filter((q)=>q.migration===void 0);if(Q.length>0)J.push("",`Also landed: ${Q.map(P6).join(", ")} — docs/decisions/index.md`);else J.push("","Full reasoning: docs/decisions/index.md");return J.join(`
120
- `)}import{existsSync as WW,readFileSync as zW}from"node:fs";import{join as YW}from"node:path";function T6($){return YW(H($),"release-seen.json")}function R6($){let Z=T6($);if(!WW(Z))return null;try{let J=JSON.parse(zW(Z,"utf8"));return typeof J?.revision==="string"&&J.revision!==""?J:null}catch{return null}}async function E6($,Z){await X$(T6($),{revision:Z,updatedAt:new Date().toISOString()})}var VW={"pr-open":[{prefix:["gh","pr","create"],excludeIfAny:["--draft","-d"]},{prefix:["gh","pr","ready"]}],commit:[{prefix:["git","commit"]}],push:[{prefix:["git","push"]}]};function k6($){return w($).map((Z)=>Z.words.map((J)=>J.text)).filter((Z)=>Z.length>0)}function GW($,Z){return Z.every((J,Q)=>$[Q]===J)}function BW($,Z){if(!GW($,Z.prefix))return!1;return!Z.excludeIfAny?.some((J)=>$.includes(J))}function oZ($,Z){let J=Z.trim().split(/\s+/);if(J.length===0)return!1;return $.some((Q,q)=>J.every((X,W)=>$[q+W]===X))}function tZ($,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 J=VW[$.kind];return k6(Z.command).some((Q)=>J.some((q)=>BW(Q,q)))}default:{if(Z.command===void 0)return!1;return k6(Z.command).some((J)=>oZ(J,$.pattern))}}}function U8($,Z){return $.filter((J)=>J.enabled&&tZ(J.on,Z))}function UW($,Z){if($===Z)return!0;if($.startsWith("*"))return Z.endsWith($.slice(1));if($.endsWith("/"))return Z.startsWith($);return!1}function x6($,Z){if($.kind!==Z.kind)return!1;switch($.kind){case"command":return oZ(Z.value.split(/\s+/),$.value);case"file":return UW($.value,Z.value);default:return Z.value===$.value}}function HW($,Z,J){if($.since==="session")return Z.sessionKey===J.sessionKey;return J.sha!==null&&Z.sha===J.sha}function KW($,Z,J){return Z.some((Q)=>x6($,Q)&&HW($,Q,J))}function MW($,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 S6($,Z,J){return $.require.filter((Q)=>!KW(Q,Z,J)).map((Q)=>({proof:Q,reason:Z.some((q)=>x6(Q,q))?MW(Q,J):null}))}function f6($){let{proof:Z,reason:J}=$,Q=`${Z.kind}(${Z.value}) since ${Z.since==="head"?"HEAD":"session"}`;return J===null?Q:`${Q} (${J})`}function H8($,Z){return $.some((J)=>J.require.some((Q)=>Q.kind===Z))}function b6($,Z){let J=new Set(Z.map((Q)=>Q.kind));return $.map((Q)=>({rule:Q.name,kinds:[...new Set(Q.require.map((q)=>q.kind))].filter((q)=>!J.has(q))})).filter((Q)=>Q.kinds.length>0)}function eZ($,Z){return $==="ask"&&Z!=="paired"?"deny":$}function FW($,Z){let J=`rule ${$.name} (${$.tier}): missing ${Z.join(", ")}`;return $.body.trim()===""?J:`${J}
120
+ `)}import{existsSync as WW,readFileSync as zW}from"node:fs";import{join as YW}from"node:path";function T6($){return YW(H($),"release-seen.json")}function R6($){let Z=T6($);if(!WW(Z))return null;try{let J=JSON.parse(zW(Z,"utf8"));return typeof J?.revision==="string"&&J.revision!==""?J:null}catch{return null}}async function E6($,Z){await X$(T6($),{revision:Z,updatedAt:new Date().toISOString()})}var VW={"pr-open":[{prefix:["gh","pr","create"],excludeIfAny:["--draft","-d"]},{prefix:["gh","pr","ready"]}],commit:[{prefix:["git","commit"]}],push:[{prefix:["git","push"]}]};function k6($){return w($).map((Z)=>Z.words.map((J)=>J.text)).filter((Z)=>Z.length>0)}function GW($,Z){return Z.every((J,Q)=>$[Q]===J)}function BW($,Z){if(!GW($,Z.prefix))return!1;return!Z.excludeIfAny?.some((J)=>$.includes(J))}function oZ($,Z){let J=Z.trim().split(/\s+/);if(J.length===0)return!1;return $.some((Q,q)=>J.every((X,W)=>$[q+W]===X))}function tZ($,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 J=VW[$.kind];return k6(Z.command).some((Q)=>J.some((q)=>BW(Q,q)))}default:{if(Z.command===void 0)return!1;return k6(Z.command).some((J)=>oZ(J,$.pattern))}}}function U8($,Z){return $.filter((J)=>J.enabled&&tZ(J.on,Z))}function UW($,Z){if($===Z)return!0;if($.startsWith("*"))return Z.endsWith($.slice(1));if($.endsWith("/"))return Z.startsWith($);return!1}function x6($,Z){if($.kind!==Z.kind)return!1;switch($.kind){case"command":return oZ(Z.value.split(/\s+/),$.value);case"file":return UW($.value,Z.value);default:return Z.value===$.value}}function HW($,Z,J){if($.since==="session")return Z.sessionKey===J.sessionKey;return J.sha!==null&&Z.sha===J.sha}function KW($,Z,J){return Z.some((Q)=>x6($,Q)&&HW($,Q,J))}function MW($,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 S6($,Z,J){return $.require.filter((Q)=>!KW(Q,Z,J)).map((Q)=>({proof:Q,reason:Z.some((q)=>x6(Q,q))?MW(Q,J):null}))}function f6($){let{proof:Z,reason:J}=$,Q=`${Z.kind}(${Z.value}) since ${Z.since==="head"?"HEAD":"session"}`;return J===null?Q:`${Q} (${J})`}function H8($,Z){return $.some((J)=>J.require.some((Q)=>Q.kind===Z))}function b6($,Z){let J=new Set(Z.map((Q)=>Q.kind));return $.map((Q)=>({rule:Q.name,kinds:[...new Set(Q.require.map((q)=>q.kind))].filter((q)=>!J.has(q))})).filter((Q)=>Q.kinds.length>0)}function eZ($,Z){return $==="ask"&&Z!=="paired"?"deny":$}function FW($,Z,J,Q){let q=`rule ${$.name} (${$.tier}): missing ${Z.join(", ")} — checked ${J} at ${Q??"no HEAD"}`;return $.body.trim()===""?q:`${q}
121
121
 
122
- ${$.body.trim()}`}function K8($,Z,J){let Q=[];for(let q of $){let X=S6(q,Z,J);if(X.length===0)continue;let W=X.map(f6);Q.push({rule:q,verdict:eZ(q.otherwise,J.mode),missing:W,message:FW(q,W)})}return Q}var y6={warn:0,"follow-up":1,ask:2,deny:3};function M8($){return $.reduce((Z,J)=>Z===null||y6[J.verdict]>y6[Z.verdict]?J:Z,null)}function F8($){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 C8($){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 $2($){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 J=$2($);return J===null?null:{...J,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function _8($,Z){return{kind:"gate",value:$,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function Z2($){if($.event!=="tool.after"||!CW.has($.toolName??""))return null;let{spawnAgentLabel:Z,spawnSubagentType:J}=$;return Z===void 0||J===void 0||Z===J?null:{label:Z,type:J}}var CW=new Set(["Task","Agent"]);function w6($,Z){if($.event!=="subagent.stop"||$.spawnSubagentType!==void 0)return $;let J=$.spawnAgentLabel;if(J===void 0)return $;let Q=Z().filter((X)=>X.label===J),q=Q[Q.length-1];return q===void 0?$:{...$,spawnSubagentType:q.type}}var v6=new Set(["deny","ask","follow-up","warn"]),m6=new Set(["subagent","command","gate","file"]);var OW=new Set(["pr-open","commit","push","stop"]);function _W($){let Z=$.trim();if(OW.has(Z))return{kind:Z};let J=/^(tool|command)\(([^)]*)\)$/.exec(Z),Q=J?.[1],q=J?.[2]?.trim();if(Q===void 0||q===void 0||q==="")return`unknown trigger "${Z}" — use one of pr-open, commit, push, stop, tool(<name>), command(<pattern>)`;return Q==="tool"?{kind:"tool",name:q}:{kind:"command",pattern:q}}function IW($){let[Z,...J]=$.trim().split(/\s+since\s+/i),Q=/^([a-z]+)\(([^)]*)\)$/.exec((Z??"").trim()),q=Q?.[1],X=Q?.[2]?.trim();if(q===void 0||!m6.has(q)||X===void 0||X==="")return`unknown proof "${$.trim()}" — use subagent(<type>), command(<pattern>), gate(<name>) or file(<glob>)`;let W=(J[0]??"head").trim().toLowerCase();if(W!=="head"&&W!=="session")return`unknown window "since ${W}" in "${$.trim()}" — use since HEAD or since session`;return{kind:q,value:X,since:W}}function PW($){let Z=(G)=>({error:{name:$.name,tier:$.tier,error:G}}),{doc:J,error:Q}=rZ($.text);if(J===null)return Z(Q??"unreadable");let q=J.fields.enabled,X=q===void 0?!0:String(q).trim()!=="false",W=J.fields.on;if(typeof W!=="string"||W.trim()==="")return Z("no `on:` trigger");let z=_W(W);if(typeof z==="string")return Z(z);let Y=J.fields.otherwise;if(typeof Y!=="string"||!v6.has(Y.trim()))return Z("`otherwise:` must be one of deny, ask, follow-up, warn");let V=[];for(let G of I6(J.fields.require)){let U=IW(G);if(typeof U==="string")return Z(U);V.push(U)}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:z,require:V,otherwise:Y.trim(),body:J.body}}}function I8($){let Z=new Map,J=[];for(let q of["global","project"])for(let X of $.filter((W)=>W.tier===q)){let W=PW(X);if("error"in W){J.push(W.error);continue}Z.set(W.rule.name,W.rule)}let Q=[...Z.values()];return{rules:Q.filter((q)=>q.enabled),disabled:Q.filter((q)=>!q.enabled),errors:J}}import{existsSync as NW,readdirSync as jW,readFileSync as LW}from"node:fs";import{basename as AW,join as I$}from"node:path";var u6=500;function h6($){return I$(H($),"rule-observations.jsonl")}function J2($){return I$(H($),"..","rules")}function Q2(){return I$(D$(),"rules")}function g6($,Z){if(!NW($))return[];return jW($,{withFileTypes:!0}).filter((J)=>J.isFile()&&J.name.endsWith(".md")).map((J)=>{let Q=I$($,J.name);return{name:AW(J.name,".md"),tier:Z,text:LW(Q,"utf8")}})}function P8($){return[...g6(Q2(),"global"),...g6(J2($),"project")]}function p6($){return I$(H($),"rule-spawn-links.jsonl")}function c6($,Z){try{A(p6($),Z)}catch{}}function d6($){try{return R(p6($),u6)}catch{return[]}}function P$($,Z){try{A(h6($),Z)}catch{}}function N8($){try{return R(h6($),u6)}catch{return[]}}function N$($,Z){if(!Z.enabled)return{rules:[],disabled:[],errors:[]};return I8(P8($))}function i6($,Z,J){let Q=N$($,Z).rules;if(Z2(J)!==null)return H8(Q,"subagent");let q=$2(J);return q!==null&&H8(Q,q.kind)}function n6($,Z,J,Q){if(!Z.enabled)return;let q=Z2(J);if(q!==null){c6($,{...q,at:Q.at});return}let X=O8(w6(J,()=>d6($)),Q);if(X!==null)P$($,X)}function r6($,Z){return H8(N$($,Z).rules,"gate")}function a6($,Z,J,Q){if(!Z.enabled)return;P$($,_8(J,Q))}var l6={decision:{kind:"abstain"},outcomes:[],errors:[]};function s6($,Z,J,Q){return t6($,Z,J,Q,F8)}function o6($,Z,J){return t6($,Z,{event:"stop"},J,C8)}function t6($,Z,J,Q,q){let X=N$($,Z);if(X.rules.length===0&&X.errors.length===0)return l6;let W=U8(X.rules,J);if(W.length===0)return{...l6,errors:X.errors};let z=K8(W,N8($),Q),Y=M8(z);return{decision:Y===null?{kind:"abstain"}:q(Y),outcomes:z,errors:X.errors}}import{existsSync as DW,mkdirSync as TW,readFileSync as RW,writeFileSync as EW}from"node:fs";import{join as kW}from"node:path";function e6($){return kW(H($),"shell-stall.json")}function $7($){let Z=e6($);if(!DW(Z))return{};try{return JSON.parse(RW(Z,"utf8"))}catch{return{}}}function Z7($,Z){try{TW(H($),{recursive:!0}),EW(e6($),`${JSON.stringify(Z,null,2)}
122
+ ${$.body.trim()}`}function K8($,Z,J){let Q=[];for(let q of $){let X=S6(q,Z,J);if(X.length===0)continue;let W=X.map(f6);Q.push({rule:q,verdict:eZ(q.otherwise,J.mode),missing:W,message:FW(q,W,J.shaRoot,J.sha)})}return Q}var y6={warn:0,"follow-up":1,ask:2,deny:3};function M8($){return $.reduce((Z,J)=>Z===null||y6[J.verdict]>y6[Z.verdict]?J:Z,null)}function F8($){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 C8($){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 $2($){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 J=$2($);return J===null?null:{...J,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function _8($,Z){return{kind:"gate",value:$,sha:Z.sha,sessionKey:Z.sessionKey,at:Z.at}}function Z2($){if($.event!=="tool.after"||!CW.has($.toolName??""))return null;let{spawnAgentLabel:Z,spawnSubagentType:J}=$;return Z===void 0||J===void 0||Z===J?null:{label:Z,type:J}}var CW=new Set(["Task","Agent"]);function w6($,Z){if($.event!=="subagent.stop"||$.spawnSubagentType!==void 0)return $;let J=$.spawnAgentLabel;if(J===void 0)return $;let Q=Z().filter((X)=>X.label===J),q=Q[Q.length-1];return q===void 0?$:{...$,spawnSubagentType:q.type}}var v6=new Set(["deny","ask","follow-up","warn"]),m6=new Set(["subagent","command","gate","file"]);var OW=new Set(["pr-open","commit","push","stop"]);function _W($){let Z=$.trim();if(OW.has(Z))return{kind:Z};let J=/^(tool|command)\(([^)]*)\)$/.exec(Z),Q=J?.[1],q=J?.[2]?.trim();if(Q===void 0||q===void 0||q==="")return`unknown trigger "${Z}" — use one of pr-open, commit, push, stop, tool(<name>), command(<pattern>)`;return Q==="tool"?{kind:"tool",name:q}:{kind:"command",pattern:q}}function IW($){let[Z,...J]=$.trim().split(/\s+since\s+/i),Q=/^([a-z]+)\(([^)]*)\)$/.exec((Z??"").trim()),q=Q?.[1],X=Q?.[2]?.trim();if(q===void 0||!m6.has(q)||X===void 0||X==="")return`unknown proof "${$.trim()}" — use subagent(<type>), command(<pattern>), gate(<name>) or file(<glob>)`;let W=(J[0]??"head").trim().toLowerCase();if(W!=="head"&&W!=="session")return`unknown window "since ${W}" in "${$.trim()}" — use since HEAD or since session`;return{kind:q,value:X,since:W}}function PW($){let Z=(G)=>({error:{name:$.name,tier:$.tier,error:G}}),{doc:J,error:Q}=rZ($.text);if(J===null)return Z(Q??"unreadable");let q=J.fields.enabled,X=q===void 0?!0:String(q).trim()!=="false",W=J.fields.on;if(typeof W!=="string"||W.trim()==="")return Z("no `on:` trigger");let z=_W(W);if(typeof z==="string")return Z(z);let Y=J.fields.otherwise;if(typeof Y!=="string"||!v6.has(Y.trim()))return Z("`otherwise:` must be one of deny, ask, follow-up, warn");let V=[];for(let G of I6(J.fields.require)){let U=IW(G);if(typeof U==="string")return Z(U);V.push(U)}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:z,require:V,otherwise:Y.trim(),body:J.body}}}function I8($){let Z=new Map,J=[];for(let q of["global","project"])for(let X of $.filter((W)=>W.tier===q)){let W=PW(X);if("error"in W){J.push(W.error);continue}Z.set(W.rule.name,W.rule)}let Q=[...Z.values()];return{rules:Q.filter((q)=>q.enabled),disabled:Q.filter((q)=>!q.enabled),errors:J}}import{existsSync as NW,readdirSync as jW,readFileSync as LW}from"node:fs";import{basename as AW,join as I$}from"node:path";var u6=500;function h6($){return I$(H($),"rule-observations.jsonl")}function J2($){return I$(H($),"..","rules")}function Q2(){return I$(D$(),"rules")}function g6($,Z){if(!NW($))return[];return jW($,{withFileTypes:!0}).filter((J)=>J.isFile()&&J.name.endsWith(".md")).map((J)=>{let Q=I$($,J.name);return{name:AW(J.name,".md"),tier:Z,text:LW(Q,"utf8")}})}function P8($){return[...g6(Q2(),"global"),...g6(J2($),"project")]}function p6($){return I$(H($),"rule-spawn-links.jsonl")}function c6($,Z){try{A(p6($),Z)}catch{}}function d6($){try{return R(p6($),u6)}catch{return[]}}function P$($,Z){try{A(h6($),Z)}catch{}}function N8($){try{return R(h6($),u6)}catch{return[]}}function N$($,Z){if(!Z.enabled)return{rules:[],disabled:[],errors:[]};return I8(P8($))}function i6($,Z,J){let Q=N$($,Z).rules;if(Z2(J)!==null)return H8(Q,"subagent");let q=$2(J);return q!==null&&H8(Q,q.kind)}function n6($,Z,J,Q){if(!Z.enabled)return;let q=Z2(J);if(q!==null){c6($,{...q,at:Q.at});return}let X=O8(w6(J,()=>d6($)),Q);if(X!==null)P$($,X)}function r6($,Z){return H8(N$($,Z).rules,"gate")}function a6($,Z,J,Q){if(!Z.enabled)return;P$($,_8(J,Q))}var l6={decision:{kind:"abstain"},outcomes:[],errors:[]};function s6($,Z,J,Q){return t6($,Z,J,Q,F8)}function o6($,Z,J){return t6($,Z,{event:"stop"},J,C8)}function t6($,Z,J,Q,q){let X=N$($,Z);if(X.rules.length===0&&X.errors.length===0)return l6;let W=U8(X.rules,J);if(W.length===0)return{...l6,errors:X.errors};let z=K8(W,N8($),Q),Y=M8(z);return{decision:Y===null?{kind:"abstain"}:q(Y),outcomes:z,errors:X.errors}}import{existsSync as DW,mkdirSync as TW,readFileSync as RW,writeFileSync as EW}from"node:fs";import{join as kW}from"node:path";function e6($){return kW(H($),"shell-stall.json")}function $7($){let Z=e6($);if(!DW(Z))return{};try{return JSON.parse(RW(Z,"utf8"))}catch{return{}}}function Z7($,Z){try{TW(H($),{recursive:!0}),EW(e6($),`${JSON.stringify(Z,null,2)}
123
123
  `,"utf8")}catch{}}function xW($){return $.trim().replace(/\s+/g," ").slice(0,300)}function J7($,Z,J){let Q=xW(J);if(!Q)return 0;let q=$7($),X=q[Z]??{hits:0},W=X.lastCommand===Q?{lastCommand:Q,hits:X.hits+1}:{lastCommand:Q,hits:1};return q[Z]=W,Z7($,q),W.hits}function Q7($,Z){let J=$7($);J[Z]={hits:0},Z7($,J)}var SW=new Set(["command","doas","env","nice","nohup","sudo","time","xargs"]),fW=new Set(["halt","poweroff","reboot","shutdown"]),bW=new Set(["curl","ftp","gh","nc","ncat","rsync","scp","sftp","ssh","telnet","wget"]),yW=new Set(["cp","mv","rm","rmdir","tee","truncate"]),wW=new Set(["chmod","chown"]),vW=/^\/dev\/(sd|nvme|vd|hd|disk)/;function mW($){let Z=0;while(Z<$.length){let J=$[Z];if(!J)break;if(SW.has(J.text)||J.text.startsWith("-")||J.text.includes("=")){Z+=1;continue}let Q=J.text.split("/").pop()??J.text,X=$.slice(Z+1).map((W)=>W.text);if(fW.has(Q)||Q==="mkfs"||Q.startsWith("mkfs."))return"destructive";if(Q==="dd"&&X.some((W)=>W.startsWith("of=")&&vW.test(W.slice(3))))return"destructive";if(Q==="diskutil"&&X.some((W)=>W.startsWith("erase")||W.startsWith("partition")))return"destructive";if(Q==="rm"&&X.some((W)=>W==="/"||W==="/*"||W.startsWith("../../")))return"destructive";if(bW.has(Q))return"network";if((Q==="git"||Q==="docker")&&X.includes("push"))return"network";if(yW.has(Q)||Q==="sed"&&X.includes("-i"))return"write";if(wW.has(Q))return"privilege";if(X.includes(">"))return"write";return X.includes(">>")?"write-preserving":"read"}return"read"}var q7=["read","write-preserving","write","privilege","network","destructive"];function W7($){let Z="read";for(let J of w($)){let Q=mW(J.words);if(q7.indexOf(Q)>q7.indexOf(Z))Z=Q}return Z}function gW($){return W7($)==="destructive"}function uW($,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 hW=new Set(["write","privilege","network"]),q2={catastrophic:"shell-catastrophic",posture:"shell-posture-paired",stall:"shell-stall"},pW={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 X7($){return pW[$]??"changes something outside this turn"}function cW($,Z){if(Z!=="paired")return null;let J=W7($);if(!hW.has(J))return null;return{kind:"ask",reason:`Posture paired: this command ${X7(J)}, 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 ${J} command ${X7(J)}. Approve it, or leave the posture with \`tlc harness mode solo\`.`,rule:q2.posture}}function z7($){let Z=$.command;if(!Z)return{kind:"allow"};if($.catastrophicAsk&&gW(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:q2.catastrophic};let J=cW(Z,$.mode);if(J)return J;if($.stallDetection){let Q=J7($.projectDir,$.sessionKey,Z);if(Q>=$.stallRepeatThreshold)return{kind:"deny",reason:uW(Z,Q),userNote:`Harness blocked a repeated shell command (${Q}x).`,rule:q2.stall}}return{kind:"allow"}}function dW($){return[$.command??"",...$.args??[]].join(" ")}function X2($,Z){for(let J of Object.values($.hooks??{}))for(let Q of J)for(let q of Q.hooks??[]){let X=dW(q);if(X.includes("tlc-exec")&&new RegExp(`(^|\\s)${Z}(\\s|$)`).test(X))return!0}return!1}function Y7($,Z){if($===null)return{run:!0,reason:"no user-level settings — this shim is the only hook for this event"};return X2($,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 V7($,Z,J){let Q=`${$}/skills/harness-init`;return Z.filter((q)=>J(q)).map((q)=>({providerDir:q,source:Q,target:`${q}/skills/harness-init`}))}function G7($,Z,J){let Q=J.linkTarget($);if(Q===null)return{state:"absent",target:$};if(!J.exists(Q))return{state:"dangling",target:$,resolved:Q};let X=(J.realpath??((W)=>W))(Z).replace(/\/+$/,"");return Q===X||Q.startsWith(`${X}/`)?{state:"ok",target:$,resolved:Q}:{state:"outside-runtime",target:$,resolved:Q}}function B7($){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 lW,mkdirSync as iW,readFileSync as nW,writeFileSync as rW}from"node:fs";import{join as aW}from"node:path";var U7=200,sW=8;function H7($){return aW(H($),"fingerprint-resolutions.json")}function K7($){let Z=H7($);if(!lW(Z))return{};try{let J=JSON.parse(nW(Z,"utf8"));return J&&typeof J==="object"?J:{}}catch{return{}}}function oW($){let Z=Object.entries($);if(Z.length<=U7)return $;let J=Z.sort((Q,q)=>q[1].at.localeCompare(Q[1].at)).slice(0,U7);return Object.fromEntries(J)}function M7($,Z,J){let Q=K7($);Q[Z]={...J,files:J.files.slice(0,sW)};let q=oW(Q);try{iW(H($),{recursive:!0}),rW(H7($),`${JSON.stringify(q,null,2)}
125
125
  `,"utf8")}catch{}return q}function F7($,Z){return K7($)[Z]??null}function C7($){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 tW}from"node:crypto";function O7($){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),J=JSON.stringify({files:[...$.files].sort(),gate:$.gate,exitCode:$.exitCode,output:Z});return tW("sha256").update(J).digest("hex").slice(0,16)}import{existsSync as eW,mkdirSync as $z,readFileSync as Zz,writeFileSync as Jz}from"node:fs";import{join as Qz}from"node:path";function _7($){return Qz(H($),"fingerprint.json")}function W2($){let Z=_7($);if(!eW(Z))return{};try{return JSON.parse(Zz(Z,"utf8"))}catch{return{}}}function I7($,Z){try{$z(H($),{recursive:!0}),Jz(_7($),`${JSON.stringify(Z,null,2)}