@tech-leads-club/harness-toolkit 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/tlc-cli.ts +20 -1
- package/dist/compact-before.mjs +5 -5
- package/dist/doctor.mjs +6 -6
- package/dist/help-topic.mjs +1 -1
- package/dist/init-project.mjs +3 -3
- package/dist/install-runtime.mjs +6 -6
- package/dist/lessons-cli.mjs +3 -3
- package/dist/obs-cli.mjs +3 -3
- package/dist/price-lookup.mjs +2 -2
- package/dist/prompt-submit.mjs +5 -5
- package/dist/refresh-model-prices.mjs +3 -3
- package/dist/response-after.mjs +5 -5
- package/dist/run.mjs +6 -6
- package/dist/session-end.mjs +5 -5
- package/dist/session-start.mjs +5 -5
- package/dist/shim.mjs +28 -28
- package/dist/stop.mjs +27 -27
- package/dist/subagent-start.mjs +5 -5
- package/dist/subagent-stop.mjs +5 -5
- package/dist/support.mjs +5 -5
- package/dist/tlc-cli.mjs +93 -93
- package/dist/tool-after.mjs +28 -28
- package/dist/tool-before.mjs +5 -5
- package/dist/tool-failure.mjs +4 -4
- package/dist/uninstall-runtime.mjs +3 -3
- package/package.json +1 -1
- package/src/core/policy/policy.integrity.ts +13 -1
- package/src/platform/paths.ts +28 -1
package/dist/session-end.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import{createRequire as A7}from"node:module";var NJ=A7(import.meta.url);import{createHash as RJ}from"node:crypto";import{join as x7}from"node:path";import{appendFileSync as D7,existsSync as T7,mkdirSync as R7,readFileSync as E7}from"node:fs";import{dirname as k7}from"node:path";function N($,Z){R7(k7($),{recursive:!0}),D7($,`${JSON.stringify(Z)}
|
|
2
2
|
`)}function R($,Z){if(!T7($))return[];let J=[];for(let Q of E7($,"utf8").split(`
|
|
3
|
-
`)){let q=Q.trim();if(q.length===0)continue;try{J.push(JSON.parse(q))}catch{}}return J.slice(-Z)}import{homedir as T8}from"node:os";import{delimiter as VY,join as P,resolve as
|
|
3
|
+
`)){let q=Q.trim();if(q.length===0)continue;try{J.push(JSON.parse(q))}catch{}}return J.slice(-Z)}import{homedir as T8}from"node:os";import{delimiter as VY,dirname as GY,join as P,resolve as BY}from"node:path";function LJ($){return P($,".tlc","harness")}function AJ(){return P(T8(),".tlc","harness")}function _$($=process.env){return $.TLC_HOME??AJ()}function I$($=process.env){return $.TLC_HOME_FROM_ENV==="0"?AJ():_$($)}function E($=process.env){return P(I$($),"config.json")}function m(){return P(I$(),"state")}function R8(){return P(m(),"obs-spool.jsonl")}function O($){return P(LJ($),"config.json")}function U($){return P(LJ($),"state")}function k($){return P(U($),"flags")}function P$($){return P(U($),"presence")}function E8($){return P(U($),"loops")}function k8($){return P(U($),"boot")}function p($){return P(U($),"policy-baseline")}function DJ(){let $=process.env.CLAUDE_CONFIG_DIR?.trim();return $&&$.length>0?$:P(T8(),".claude")}function TJ(){let $=process.env.CURSOR_CONFIG_DIR?.trim();return $&&$.length>0?$:P(T8(),".cursor")}var EJ="genesis";function j$($){return x7(U($),"attestation.jsonl")}function kJ($){let Z=[$.schema,$.ts,$.provider,$.session,$.policyFingerprint,String($.policyDiverged),$.railsActive.join(","),Object.entries($.decisionsByRule).sort((J,Q)=>J[0].localeCompare(Q[0])).map(([J,Q])=>`${J}=${Q}`).join(","),`${$.gates.pass}/${$.gates.fail}`,$.prev].join("\x00");return RJ("sha256").update(Z).digest("hex")}function x8($){return R(j$($),Number.MAX_SAFE_INTEGER)}function xJ($,Z){let Q=x8($).at(-1)?.self??EJ,q={schema:"harness.attestation.v1",...Z,prev:Q},X={...q,self:kJ(q)};return N(j$($),X),X}function SJ($){let Z=EJ;for(let[J,Q]of $.entries()){if(Q.prev!==Z)return{ok:!1,brokenAt:J,reason:"previous-hash-mismatch"};let{self:q,...X}=Q;if(kJ(X)!==q)return{ok:!1,brokenAt:J,reason:"content-hash-mismatch"};Z=q}return{ok:!0,length:$.length}}function fJ($){let Z=[...$].sort((J,Q)=>J.path.localeCompare(Q.path)).map((J)=>`${J.path}:${J.hash}`).join("|");return RJ("sha256").update(Z).digest("hex").slice(0,32)}var c='Enable: ask the agent "setup harness" (harness-init skill) or edit .tlc/harness/config.json';function S7($,Z){let J=$;for(let Q of Z.split(".").filter(Boolean)){if(!J||typeof J!=="object")return;J=J[Q]}return J}function S8($,Z){let J=S7($,Z.configPath);return Z.defaultOn?J===!1:J!==!0}function f8($,Z){return Z.capabilities.filter((J)=>S8($,J))}function bJ($,Z,J){return f8($,Z).filter((Q)=>Q.sinceCatalogVersion>J)}function yJ($){let Z=["Available for this project (not enabled yet):",""];for(let J of $)Z.push(`• ${J.title}`),Z.push(` Benefit: ${J.benefit}`),Z.push(` Trade-off: ${J.tradeOff}`),Z.push("");return Z.push(c),Z.join(`
|
|
4
4
|
`).trimEnd()}function wJ($){return`${$.title} off — ${$.tradeOff} — ${c}`}function vJ($){return`${$.length} available and not enabled: ${$.map((Z)=>Z.id).join(", ")}. ${c}`}import{existsSync as i7,readFileSync as n7}from"node:fs";import{join as dJ}from"node:path";import{randomBytes as b7}from"node:crypto";import{closeSync as y7,existsSync as w7,mkdirSync as gJ,openSync as v7,readFileSync as m7,renameSync as g7,rmSync as uJ,writeFileSync as u7}from"node:fs";import{dirname as hJ}from"node:path";function $$($){let{attempt:Z,baseMs:J,capMs:Q,random:q=Math.random}=$,X=J*2**Z,W=Math.min(Q,X);return q()*W}function f7($){return new Promise((Z)=>setTimeout(Z,$))}async function mJ($,Z){let{attempts:J,shouldRetry:Q=()=>!0,sleep:q=f7,random:X=Math.random,baseMs:W=50,capMs:z=2000}=Z;for(let Y=0;Y<J;Y++)try{return await $()}catch(V){if(Y===J-1||!Q(V))throw V;await q($$({attempt:Y,baseMs:W,capMs:z,random:X}))}throw Error("retry: unreachable")}var h7=new Set(["EPERM","EBUSY","EACCES"]);function pJ($){return typeof $==="object"&&$!==null&&"code"in $?$.code:void 0}function cJ($){let Z=pJ($);return Z!==void 0&&h7.has(Z)}function p7($){return`${$}.${process.pid}.${b7(4).toString("hex")}.tmp`}async function Z$($,Z,J={}){let{attempts:Q=5,baseMs:q=20,capMs:X=500,random:W,sleep:z,rename:Y=g7,writeFile:V=(B,K)=>u7(B,K,"utf8"),removeFile:G=(B)=>{try{uJ(B,{force:!0})}catch{}}}=J;gJ(hJ($),{recursive:!0});let H=p7($);V(H,`${JSON.stringify(Z,null,2)}
|
|
5
5
|
`);try{await mJ(()=>{Y(H,$)},{attempts:Q,baseMs:q,capMs:X,random:W,sleep:z,shouldRetry:cJ})}catch(B){throw G(H),B}}function c7($){if(!w7($))return null;try{return JSON.parse(m7($,"utf8"))}catch{return null}}function d7($){return pJ($)==="EEXIST"||cJ($)}async function l7($,Z,J={}){let{openLock:Q=(z)=>y7(v7(z,"wx")),lockSleep:q=(z)=>new Promise((Y)=>setTimeout(Y,z)),lockAttempts:X=200}=J;gJ(hJ($),{recursive:!0});let W=!1;for(let z=0;z<X;z++)try{Q($),W=!0;break}catch(Y){if(!d7(Y))throw Y;await q($$({attempt:z,baseMs:10,capMs:200}))}if(!W)throw Error(`fs-atomic: could not acquire lock at ${$}`);try{return await Z()}finally{try{uJ($,{force:!0})}catch{}}}async function N$($,Z,J){let{lockPath:Q,afterWrite:q,openLock:X,lockSleep:W,lockAttempts:z,...Y}=J;return l7(Q,async()=>{let V=c7($),G=Z(V);return await Z$($,G,Y),q?.($),G},{openLock:X,lockSleep:W,lockAttempts:z})}function b8($){if(!i7($))return null;try{return JSON.parse(n7($,"utf8"))}catch{return null}}function r7($=_$()){return dJ($,"capabilities","catalog.json")}function lJ($=_$()){let Z=b8(r7($));if(!Z||typeof Z.catalogVersion!=="number"||!Array.isArray(Z.capabilities))return null;return Z}function iJ($){return b8(O($))}function nJ($){return dJ(U($),"runtime-seen.json")}function rJ($){let Z=b8(nJ($));if(!Z||typeof Z.catalogVersion!=="number"||Z.catalogVersion<0)return{catalogVersion:0};return Z}async function aJ($,Z){await Z$(nJ($),{catalogVersion:Z,updatedAt:new Date().toISOString()})}import{readFileSync as QQ}from"node:fs";import{join as qQ}from"node:path";import{existsSync as t7,readFileSync as e7}from"node:fs";import{join as oJ}from"node:path";import{spawn as a7}from"node:child_process";var s7=124;async function sJ(){let $=[];for await(let Z of process.stdin)$.push(Buffer.isBuffer(Z)?Z:Buffer.from(Z));return Buffer.concat($).toString("utf8")}async function y8($){let[Z,...J]=$.command;if(Z===void 0)return{exitCode:0,stdout:"",stderr:""};return await new Promise((Q,q)=>{let X=a7(Z,J,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],env:$.env??process.env}),W="",z="",Y=!1,V=$.timeoutMs===void 0?void 0:setTimeout(()=>{Y=!0,X.kill("SIGKILL")},$.timeoutMs);if(X.stdout.on("data",(G)=>{W+=G.toString()}),X.stderr.on("data",(G)=>{z+=G.toString()}),X.on("error",(G)=>{if(V)clearTimeout(V);q(G)}),X.on("close",(G)=>{if(V)clearTimeout(V);if(Y){Q({exitCode:s7,stdout:W,stderr:`${z}
|
|
6
6
|
(process timed out)`});return}Q({exitCode:G??1,stdout:W,stderr:z})}),$.input!==void 0)X.stdin.write($.input);X.stdin.end()})}var o7=/[A-Za-z0-9._-]/;function I($){if($.length===0)return"_empty_";let Z="";for(let J of $){if(o7.test(J)){Z+=J;continue}for(let Q of Buffer.from(J,"utf8"))Z+=`%${Q.toString(16).toUpperCase().padStart(2,"0")}`}return Z}function L($){return $.replace(/\\/g,"/")}async function tJ($,Z){let J=await y8({command:["git",...Z],cwd:$});if(J.exitCode!==0)return[];return J.stdout.split(`
|
|
@@ -12,7 +12,7 @@ import{createRequire as A7}from"node:module";var NJ=A7(import.meta.url);import{c
|
|
|
12
12
|
`).entries())Q.push({file:z,line:V+1,text:G})}return{index:V2(Q,J),filesRead:X,truncated:W}}import{homedir as p8,tmpdir as EQ}from"node:os";import{basename as kQ,isAbsolute as H2,relative as J$,resolve as S,sep as xQ}from"node:path";function SQ($,Z=p8()){if($==="~")return Z;return $.startsWith(`~${xQ}`)||$.startsWith("~/")?S(Z,$.slice(2)):$}function d($,Z,J=p8()){let Q=SQ(Z,J);return H2(Q)?S(Q):S($,Q)}function f($,Z){let J=J$(S($),S(Z));return J===""||!J.startsWith("..")&&!H2(J)}function K2($,Z=EQ()){return f(Z,$)}function fQ($){let Z=S($);return Z===S(E())||f(m(),Z)}function A$($,Z){if(fQ(Z))return!0;let J=L(J$($,Z)||Z),Q=L(J$($,O($))),q=L(J$($,k($))),X=L(J$($,U($)));return J===Q||J.startsWith(`${q}/`)||J.startsWith(`${X}/`)}var bQ=[".ssh",".aws",".kube",".gnupg",".docker",".config/gh",".config/gcloud"],yQ=new Set([".git-credentials",".netrc",".npmrc",".pgpass","credentials","id_dsa","id_ecdsa","id_ed25519","id_rsa"]),wQ=[".pem",".p12",".pfx"],vQ=[".example",".sample",".template",".dist"];function mQ($){if($!==".env"&&!$.startsWith(".env."))return!1;return!vQ.some((Z)=>$.endsWith(Z))}function c8($,Z=p8()){let J=kQ($);if(mQ(J)||yQ.has(J))return!0;if(wQ.some((Q)=>J.endsWith(Q)))return!0;return bQ.some((Q)=>f(S(Z,Q),$))}import{relative as cQ,resolve as dQ}from"node:path";var gQ=new Set([";","|","&",`
|
|
13
13
|
`]),uQ=new Set([" ","\t",'"',"'","$","`","\\",";","|","&","(",")"]);function hQ($){return $.includes("$")||$.includes("`")}function M2($){let Z=/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/,J=[],Q=$,q="";for(;;){let X=Z.exec(Q);if(!X){q+=Q;break}let W=Q.indexOf(`
|
|
14
14
|
`,X.index+X[0].length),z=q+Q.slice(0,X.index);if(q+=Q.slice(0,X.index),W===-1)break;let Y=new RegExp(`^\\s*${X[2]}\\s*$`,"m"),V=Q.slice(W+1),G=Y.exec(V);if(!G){J.push({body:V,prefix:z});break}J.push({body:V.slice(0,G.index),prefix:z}),Q=V.slice(G.index+G[0].length)}return{stripped:q,heredocs:J}}function F2($){return M2($).heredocs}function b($){let Z=[],J=[],Q="",q=!1,X=!1,W=null,z=!1,Y=0;function V(){if(Q!==""||q)J.push({text:Q,unresolved:hQ(Q),quotedStart:X});Q="",q=!1,X=!1}function G(){if(V(),J.length>0)Z.push({words:J,opaque:z});J=[]}let{stripped:H}=M2($);for(let B=0;B<H.length;B+=1){let K=H[B];if(W!==null){if(K===W)W=null;else Q+=K;continue}if(K==="\\"){let A=H[B+1];if(A!==void 0&&uQ.has(A))Q+=A,B+=1;else Q+=K;continue}if(K==='"'||K==="'"){if(W=K,Q===""&&!q)X=!0;q=!0;continue}if(K==="$"&&(H[B+1]==="("||H[B+1]==="{")){Y+=1,Q+=K;continue}if(Y>0&&(K===")"||K==="}")){Y-=1,Q+=K;continue}if(Y===0&&gQ.has(K)){G();continue}if(Y===0&&(K===" "||K==="\t")){V();continue}Q+=K}if(W!==null||Y>0)z=!0;return G(),z?Z.map((B)=>({...B,opaque:!0})):Z}var pQ=new Set(["command","doas","env","nice","nohup","sudo","time","xargs"]);function g($){let Z=0;while(Z<$.length){let J=$[Z];if(!J)return null;if(pQ.has(J.text)||J.text.startsWith("-")||J.text.includes("=")){Z+=1;continue}return{verb:J.text.split("/").pop()??J.text,args:$.slice(Z+1)}}return null}function C2($){return $.find((Z)=>!Z.text.startsWith("-")&&Z.text!=="")??null}var D$={kind:"allow"},lQ=new Set(["cat","cmp","diff","echo","file","grep","head","jq","less","ls","md5sum","more","od","printf","rg","sha256sum","stat","strings","tail","test","[","wc","xxd"]),iQ=new Set(["show","diff","log","status","ls-files","cat-file","blame"]),nQ=new Set(["ash","awk","bash","bun","dash","deno","ed","ex","fish","gawk","ksh","lua","node","perl","php","python","python2","python3","ruby","sed","sh","tclsh","zsh"]),rQ=new Set(["tlc","tlc.cmd"]),aQ=new Set(["pause","resume","grind","mode","init","gate","policy"]);function y($,Z,J){return{kind:"deny",detail:$,note:Z,...J?{remedy:J}:{}}}var O2="Reading is allowed: run `tlc harness handoff` for handoff state, `tlc harness status` for posture and gates, `tlc harness doctor` for what the settings amount to, or use a proven reader (cat, head, jq, grep, ls, stat, test) on the path.";function d8($){let Z=L(cQ($,U($)));return Z.slice(0,Z.lastIndexOf("/"))}function sQ($,Z){return L(Z.words.map((Q)=>Q.text).join(" ")).includes(d8($))}function oQ($,Z){if(Z===dQ($))return!1;if(A$($,Z))return!0;return[O($),U($)].some((J)=>f(J,Z)||f(Z,J))}function _2($,Z){if(Z.text==="")return!1;if(Z.unresolved)return L(Z.text).includes(d8($));return oQ($,d($,Z.text))}function tQ($){let Z=[];for(let J=0;J<$.length;J+=1){let Q=$[J];if(!Q||Q.quotedStart)continue;let q=/^(.*?)>{1,2}\|?(.*)$/s.exec(Q.text);if(!q)continue;let X=q[2]??"";if(X!==""){Z.push({text:X,unresolved:Q.unresolved,quotedStart:!1});continue}let W=$[J+1];if(W)Z.push(W),J+=1}return Z}function eQ($){let Z=$.filter((J)=>!J.text.startsWith("-")&&J.text!=="");if(Z[0]?.text.toLowerCase()!=="harness")return null;return(Z[1]?.text??"status").toLowerCase()}function $3($,Z){for(let q of tQ(Z.words))if(_2($,q))return y("a redirect in this command writes into the harness policy surface.","redirect into the policy surface");let J=g(Z.words);if(J&&rQ.has(J.verb)){let q=eQ(J.args);if(q!==null&&aQ.has(q))return y(`\`tlc harness ${q}\` changes harness policy, and policy is the operator's to change.`,`tlc harness ${q}`)}let Q=Z.words.filter((q)=>_2($,q));if(Q.length===0&&!sQ($,Z))return D$;if(Z.opaque)return y("this command names the harness policy surface inside a segment this gate cannot split, so what it does to it cannot be established.","unprovable policy-surface access");if(!J)return y("the harness policy surface is named in a command with no resolvable verb.","policy-surface access with no verb");if(lQ.has(J.verb))return D$;if(J.verb==="git"){let q=C2(J.args)?.text.toLowerCase()??"";return iQ.has(q)?D$:y(`\`git ${q}\` can write the working tree, so it cannot be proven to only read the harness policy surface.`,`git ${q} on the policy surface`,O2)}if(Q.some((q)=>q.unresolved))return y("this command builds a harness policy path at runtime, so the file it would touch cannot be established.","unresolvable policy-surface path");return y(`\`${J.verb}\` is not a proven reader, so this command cannot be shown to only read the harness policy surface.`,`${J.verb} on the policy surface`,O2)}function Z3($,Z){let J=d8($);for(let Q of Z){if(!L(Q.body).includes(J))continue;let q=g(b(Q.prefix).at(-1)?.words??[]);if(q!==null&&nQ.has(q.verb))return y(`a heredoc fed to \`${q.verb}\` names the harness policy surface, so the body is a program rather than a document.`,"heredoc program naming the policy surface")}return D$}function I2($,Z,J){for(let Q of J){let q=$3($,Q);if(q.kind==="deny")return q}return Z3($,F2(Z))}var P2=new Set(["dd","rm","rmdir","shred","truncate"]),j2=new Set(["halt","poweroff","reboot","shutdown"]),J3=new Set(["base64","cat","head","less","more","od","strings","tail","xxd"]),Q3=new Set(["Read","Edit","MultiEdit","NotebookEdit"]),N2=new Set([".","eval","source"]),l8=new Set(["ash","bash","dash","fish","ksh","sh","zsh"]),i8=new Set(["aria2c","curl","fetch","http","httpie","https","wget"]),q3=["169.254.169.254","169.254.170.2","100.100.100.200","metadata.google.internal"],X3=new Set([...i8,"nc","ncat","socat","telnet","lwp-request"]);function W3($){return[...i8].some((Z)=>new RegExp(`\\b${Z}\\b`).test($))}function z3($,Z){let J=$.includes("|"),Q=!1;for(let q of Z){let X=g(q.words);if(!X)continue;let{verb:W,args:z}=X;if(J&&Q&&l8.has(W))return!0;if(l8.has(W)||N2.has(W)){for(let Y of z)if((Y.text.includes("<(")||Y.unresolved)&&W3(Y.text))return!0}Q=i8.has(W)}return!1}function Y3($,Z){return N2.has($)||l8.has($)&&Z.some((J)=>J.text==="-c")}function V3($,Z){return[`FLOOR: ${Z}`,"This is a floor rule — it has no config switch, because a limit an agent can turn off is not a limit.","Restate what you need and let the operator decide; do not work around this.",`rule=${$}`].join(`
|
|
15
|
-
`)}function T($,Z,J){return{kind:"deny",reason:V3($,Z),userNote:`Floor rule ${$}: ${J}`,rule:$}}function L2($){return $==="mkfs"||$.startsWith("mkfs.")}function G3($){let Z=$.split("/").pop()??$;return P2.has(Z)||j2.has(Z)||L2(Z)}function B3($){return $.words.some((Z)=>Z.text.split(/\s+/).some(G3))}function A2($){return $.filter((Z)=>!Z.text.startsWith("-")&&Z.text!=="")}function U3($){let Z=$.command;if(!Z)return{kind:"allow"};let J=b(Z);if(z3(Z,J))return T("unprovable-execution","This runs a program fetched over the network, which does not exist for this gate to check. Download it to a file, read it, then run that file.","fetched program piped to a shell");for(let q of J){let X=g(q.words);if(!X)continue;let{verb:W,args:z}=X;if(Y3(W,z)&&B3(q))return T("unprovable-destruction","A destructive verb appears inside a command this gate cannot expand, so its target cannot be established. Run it directly with a literal path instead.","hidden destructive verb");if(j2.has(W))return T("machine-control",`\`${W}\` controls the machine, not the project.`,W);if(W==="git"&&z.some((G)=>G.text==="push")){if(z.some((H)=>H.text==="--force"||H.text==="-f"))return T("history-rewrite","`git push --force` discards remote commits that are not in your history. Use --force-with-lease, which refuses when the remote moved.","force push")}if(!(P2.has(W)||L2(W)))continue;let V=A2(z);if(q.opaque||V.some((G)=>G.unresolved)||V.length===0)return T("unprovable-destruction",`\`${W}\` was called with a target this gate cannot resolve, so its safety cannot be established. Re-run it with a literal path inside the project.`,`unresolvable ${W}`);for(let G of V){let H=d($.projectDir,G.text);if(!f($.projectDir,H)&&!K2(H))return T("outside-project-destruction",`\`${W}\` targets ${H}, which is outside the project and outside scratch space.`,`${W} outside project`)}}let Q=I2($.projectDir,Z,J);if(Q.kind==="deny"){let q=Q.remedy??"Set a gate command with `tlc harness gate test-command` or `gate lint-command`, and run policy changes from your own terminal rather than from inside this session.";return T("policy-surface-write",`${Q.detail} ${q}`,Q.note)}return H3(J,$.projectDir)}function H3($,Z){for(let J of $){let Q=g(J.words);if(!Q)continue;if(X3.has(Q.verb)){let q=Q.args.map((W)=>W.text).join(" "),X=q3.find((W)=>q.includes(W));if(X!==void 0)return T("secret-access",`${X} is the instance metadata service, and \`${Q.verb}\` would copy the credentials it returns into the transcript.`,`read of ${X}`)}if(!J3.has(Q.verb))continue;for(let q of A2(Q.args)){if(q.unresolved)continue;let X=d(Z,q.text);if(c8(X))return T("secret-access",`\`${Q.verb}\` would read ${X} into the transcript. Credentials do not belong in an agent's context.`,`read of ${X}`)}}return{kind:"allow"}}function K3($){let Z=$.filePath;if(!Z)return{kind:"allow"};if(!($.isReadEvent===!0||$.toolName!==void 0&&Q3.has($.toolName)))return{kind:"allow"};let Q=d($.projectDir,Z);if(!c8(Q))return{kind:"allow"};return T("secret-access",`${Q} holds credentials, and reading it would copy them into the transcript.`,`read of ${Q}`)}function D2($){let Z=K3($);if(Z.kind!=="allow")return Z;return U3($)}import{createHash as k3}from"node:crypto";import{existsSync as x3,mkdirSync as S3,readFileSync as f3,unlinkSync as
|
|
15
|
+
`)}function T($,Z,J){return{kind:"deny",reason:V3($,Z),userNote:`Floor rule ${$}: ${J}`,rule:$}}function L2($){return $==="mkfs"||$.startsWith("mkfs.")}function G3($){let Z=$.split("/").pop()??$;return P2.has(Z)||j2.has(Z)||L2(Z)}function B3($){return $.words.some((Z)=>Z.text.split(/\s+/).some(G3))}function A2($){return $.filter((Z)=>!Z.text.startsWith("-")&&Z.text!=="")}function U3($){let Z=$.command;if(!Z)return{kind:"allow"};let J=b(Z);if(z3(Z,J))return T("unprovable-execution","This runs a program fetched over the network, which does not exist for this gate to check. Download it to a file, read it, then run that file.","fetched program piped to a shell");for(let q of J){let X=g(q.words);if(!X)continue;let{verb:W,args:z}=X;if(Y3(W,z)&&B3(q))return T("unprovable-destruction","A destructive verb appears inside a command this gate cannot expand, so its target cannot be established. Run it directly with a literal path instead.","hidden destructive verb");if(j2.has(W))return T("machine-control",`\`${W}\` controls the machine, not the project.`,W);if(W==="git"&&z.some((G)=>G.text==="push")){if(z.some((H)=>H.text==="--force"||H.text==="-f"))return T("history-rewrite","`git push --force` discards remote commits that are not in your history. Use --force-with-lease, which refuses when the remote moved.","force push")}if(!(P2.has(W)||L2(W)))continue;let V=A2(z);if(q.opaque||V.some((G)=>G.unresolved)||V.length===0)return T("unprovable-destruction",`\`${W}\` was called with a target this gate cannot resolve, so its safety cannot be established. Re-run it with a literal path inside the project.`,`unresolvable ${W}`);for(let G of V){let H=d($.projectDir,G.text);if(!f($.projectDir,H)&&!K2(H))return T("outside-project-destruction",`\`${W}\` targets ${H}, which is outside the project and outside scratch space.`,`${W} outside project`)}}let Q=I2($.projectDir,Z,J);if(Q.kind==="deny"){let q=Q.remedy??"Set a gate command with `tlc harness gate test-command` or `gate lint-command`, and run policy changes from your own terminal rather than from inside this session.";return T("policy-surface-write",`${Q.detail} ${q}`,Q.note)}return H3(J,$.projectDir)}function H3($,Z){for(let J of $){let Q=g(J.words);if(!Q)continue;if(X3.has(Q.verb)){let q=Q.args.map((W)=>W.text).join(" "),X=q3.find((W)=>q.includes(W));if(X!==void 0)return T("secret-access",`${X} is the instance metadata service, and \`${Q.verb}\` would copy the credentials it returns into the transcript.`,`read of ${X}`)}if(!J3.has(Q.verb))continue;for(let q of A2(Q.args)){if(q.unresolved)continue;let X=d(Z,q.text);if(c8(X))return T("secret-access",`\`${Q.verb}\` would read ${X} into the transcript. Credentials do not belong in an agent's context.`,`read of ${X}`)}}return{kind:"allow"}}function K3($){let Z=$.filePath;if(!Z)return{kind:"allow"};if(!($.isReadEvent===!0||$.toolName!==void 0&&Q3.has($.toolName)))return{kind:"allow"};let Q=d($.projectDir,Z);if(!c8(Q))return{kind:"allow"};return T("secret-access",`${Q} holds credentials, and reading it would copy them into the transcript.`,`read of ${Q}`)}function D2($){let Z=K3($);if(Z.kind!=="allow")return Z;return U3($)}import{createHash as k3}from"node:crypto";import{existsSync as x3,mkdirSync as S3,readFileSync as f3,unlinkSync as N0,writeFileSync as b3}from"node:fs";import{dirname as y3,join as w3}from"node:path";var M3=["CLAUDE_PROJECT_DIR","CURSOR_PROJECT_DIR","TLC_PROJECT_DIR"];function T2($=process.env){return M3.filter((Z)=>($[Z]??"").trim()!=="")}var F3=/\d+\s+(?:tests?|specs?|examples?)?\s*(?:fail(?:ed|ures?)?|pass(?:ed|ing)?|pending|skipped|todo|errors?)\b|(?:failures?|errors?)\s*=\s*\d+/gi,C3=/^(?:tests?|specs?|failed|failures?|summary|results?)\b[:\s]*/i,O3=/^[\s\d:;,|—–\-()=.✗×✕✖*]*$/,_3=[/^\(fail\)\s*\S/i,/^not ok\s+\d+/i,/^---\s*FAIL:\s*\S/i,/^(?:FAIL|FAILED)\s+(?!\()\S/i],I3=/^[✗×✕✖]\s+\S/,P3=/(?:expect\(|toEqual|toBe\b|toMatch|toThrow|AssertionError|assert(?:ion)?\b|deep(?:Strict)?Equal|strictEqual|Expected\b|received\b|actual\b)/i;function j3($){if(!/\d/.test($)||!/(?:fail|error)/i.test($))return!1;let Z=$.replace(C3," ").replace(F3," ");return O3.test(Z)}function N3($){if(_3.some((Z)=>Z.test($)))return"test";if(j3($))return"count";if(I3.test($))return"test";return P3.test($)?"assertion":"other"}function L3($){let Z=[],J=[],Q=null,q=null;for(let X of $)switch(N3(X)){case"count":Q??=X;break;case"test":{let W={summary:X,details:J.splice(0)};Z.push(W),q=W;break}case"assertion":if(q)q.details.push(X);else J.push(X);break;default:{let W={summary:X,details:J.splice(0)};Z.push(W),q=W}}if(J.length>0)Z.push({summary:J[0],details:J.slice(1)});return{failures:Z,firstCount:Q}}function A3($){return $.replace(/\s+/g," ").trim().toLowerCase()}function D3($){let Z=new Map;for(let J of $){let Q=A3(J.summary),q=Z.get(Q);if(q){q.details.push(...J.details);continue}Z.set(Q,{summary:J.summary,details:[...J.details]})}return[...Z.values()]}function R2($){let Z=[...new Set($.details)].join(`
|
|
16
16
|
`).slice(0,500);return Z?{summary:$.summary.slice(0,200),detail:Z}:{summary:$.summary.slice(0,200)}}function E2($,Z,J){let{failures:Q,firstCount:q}=L3($),X=D3(Q);if(X.length===0){let Y={summary:`gate exited with code ${Z}`};return q?[{...Y,detail:q.slice(0,500)}]:[Y]}if(X.length<=J)return X.map(R2);let W=X.slice(0,Math.max(1,J-1)).map(R2),z=X.length-W.length;return[...W,{summary:`…and ${z} more failures in the gate output`}]}var T3="ts|tsx|mts|cts|js|jsx|mjs|cjs|py|go|rb|rs|java|kt|swift|php|sh|sql",R3=new RegExp(`(?:file://)?((?:[A-Za-z]:)?[\\w./~@+-]*[\\w-]\\.(?:${T3}))(?=[:)\\s,'"\`]|$)`,"g");function E3($){let Z=String.fromCharCode(27);return $.replaceAll(new RegExp(`${Z}\\[[0-9;]*[A-Za-z]`,"g"),"")}function k2($,Z){let J=new Set,Q=[],q=`${Z.replace(/\/+$/,"")}/`;for(let X of E3($).matchAll(R3)){let W=X[1];if(!W)continue;let z=W.startsWith(q)?W.slice(q.length):W;if(J.has(z))continue;J.add(z),Q.push(z)}return Q}var x2="harness.gate.v1";var v3=8000,T$=8,m3=/(?:\bFAIL(?:ED)?\b|\bERROR\b|Error:|error\[|AssertionError|\bpanic:|✗|×|✕|✖|failures?\s*[:=]\s*[1-9])/i;function S2($){return w3(U($),"last-gate.json")}function g3($,Z=v3){let J=$.trim();if(!J)return"";return J.length<=Z?J:J.slice(-Z)}function f2($){if(!x3($))return null;try{return JSON.parse(f3($,"utf8"))}catch{return null}}function u3($){let Z=f2($);if(!Z||typeof Z!=="object")return null;let J=Z.findings;if(!Array.isArray(J))return null;let Q=[];for(let q of J){if(!q||typeof q!=="object")continue;let X=q.summary;if(typeof X!=="string"||!X.trim())continue;let{detail:W,id:z}=q;if(Q.push({summary:X.trim().slice(0,200),detail:typeof W==="string"?W.slice(0,500):void 0,id:typeof z==="string"?z:void 0}),Q.length>=T$)break}return Q.length>0?Q:null}function h3($,Z,J=T$){let Q=$.split(`
|
|
17
17
|
`).map((W)=>W.trim()).filter((W)=>W.length>0&&!W.startsWith(">")),q=Q.filter((W)=>m3.test(W)),X=q.length>0?q:Q.slice(-J);return E2(X,Z,J)}function b2($){let Z=g3($.output),J=$.reportPath?u3($.reportPath):null,Q=!Z||Z==="(no output captured)",q=J??($.exitCode===0?[]:Q?[{summary:`gate exited with code ${$.exitCode}`}]:h3(Z,$.exitCode)),X={schema:x2,gate:$.gate,exitCode:$.exitCode,passed:$.exitCode===0,command:$.command,files:[...$.files],durationMs:$.durationMs,ts:new Date().toISOString(),outputTail:Z,findings:q,scopedEnv:T2(),...$.inputsHash?{inputsHash:$.inputsHash}:{}},W=S2($.root);return S3(y3(W),{recursive:!0}),b3(W,`${JSON.stringify(X,null,2)}
|
|
18
18
|
`,"utf8"),X}function y2($){return f2(S2($))}function w2($){let Z=JSON.stringify({gate:$.gate,exitCode:$.exitCode,files:[...$.files].sort(),findings:$.findings.map((J)=>J.summary).sort()});return k3("sha256").update(Z).digest("hex").slice(0,16)}import{basename as p3}from"node:path";var c3=new Set(["just","make","task","mise","rake"]),d3=new Set(["npm","yarn","pnpm"]),l3=new Set(["npx","bunx","dlx","exec"]),i3=/[*?[\]]/,n3=[/does not contain recipe/i,/no rule to make target/i,/unknown recipe/i,/missing script:/i,/task ".*" does not exist/i,/don't know how to build task/i];function r3($){let Z=$;while(Z.length>1&&l3.has(n8(Z[0])))Z=Z.slice(1);if(Z.length>2&&n8(Z[0])==="bun"&&Z[1]==="run")return["npm",...Z.slice(1)];return Z}function n8($){return p3($).replace(/\.(exe|cmd|bat)$/i,"").toLowerCase()}function R$($){return n8(r3($)[0]??"")}function r8($){return c3.has(R$($))}function a3($){return d3.has(R$($))}function a8($,Z){if($.length===0)return{appends:!1,reason:"the command is empty"};if(Z==="always")return{appends:!0};if(Z==="never")return{appends:!1,reason:"appendFiles is set to never"};if(r8($))return{appends:!1,reason:`\`${R$($)}\` takes a target name, so a file path would read as a second target`};if(a3($))return{appends:!1,reason:`\`${R$($)}\` invokes a script, and whether a path reaches the runner is not something the harness can know`};let J=$.find((Q)=>i3.test(Q));if(J!==void 0)return{appends:!1,reason:`the command already scopes itself with \`${J}\`, so appending files would not narrow the run`};return{appends:!0}}function v2($,Z){return a8($,Z).appends}function E$($){if($.exitCode===127)return!0;return n3.some((Z)=>Z.test($.output))}import{createHash as m2}from"node:crypto";import{readFileSync as s3,statSync as o3}from"node:fs";import{isAbsolute as t3,resolve as e3}from"node:path";var $q=400,Zq=12000000;function Jq($,Z){if(t3(Z))return null;let J=e3($,Z);try{let Q=o3(J);if(!Q.isFile())return null;let q=s3(J);return{entry:`${Z}\x00${Q.size}\x00${m2("sha256").update(q).digest("hex")}`,bytes:Q.size}}catch{return null}}function g2($,Z,J){let Q=[...new Set(Z)].sort();if(Q.length>$q)return{hash:"",complete:!1};let q=[],X=0,W=!0;for(let Y of Q){let V=Jq($,Y);if(V===null){W=!1;continue}if(X+=V.bytes,X>Zq)return{hash:"",complete:!1};q.push(V.entry)}let z=JSON.stringify({command:[...J],entries:q});return{hash:m2("sha256").update(z).digest("hex").slice(0,32),complete:W}}function s8($,Z){return $.complete&&$.hash.length>0&&Z===$.hash}function u2($,Z,J){if($===null||$.gate!==Z)return null;return s8(J,$.inputsHash)?$:null}import{closeSync as Qq,existsSync as p2,mkdirSync as qq,openSync as Xq,readFileSync as Wq,statSync as zq,unlinkSync as c2,writeFileSync as Yq}from"node:fs";import{hostname as d2}from"node:os";import{dirname as Vq,join as Gq}from"node:path";var o8=120000,l2=1800000,Bq=5000;class k$ extends Error{constructor($="gate lock timeout"){super($);this.name="GateLockTimeoutError"}}function i2($){return Gq(U($),"grind.lock")}function Uq($){return new Promise((Z)=>setTimeout(Z,$))}function Q$($){if(!p2($))return null;try{return JSON.parse(Wq($,"utf8"))}catch{return null}}function n2($,Z){if(!p2($))return null;try{return Z-zq($).mtimeMs}catch{return null}}function r2($,Z){let J=n2($,Z.now);return J!==null&&J>=Z.staleMs}function t8($){if(typeof $!=="object"||$===null)return!1;let Z=$;return typeof Z.provider==="string"&&typeof Z.session==="string"&&typeof Z.pid==="number"}function Hq($,Z){let J=n2($,Z.now);if(J===null||J<Z.graceMs)return!1;return!t8(Q$($))}var Kq=($)=>{process.kill($,0)};function a2($,Z=d2(),J=Kq){if(!t8($))return!1;let{host:Q,pid:q}=$;if(typeof Q!=="string"||Q!==Z)return!1;if(!Number.isInteger(q)||q<=0)return!1;try{return J(q),!1}catch(X){return X.code==="ESRCH"}}function Mq($,Z){return r2($,{now:Z.now,staleMs:Z.staleMs})||Hq($,{now:Z.now,graceMs:Z.graceMs})||a2(Q$($))}function e8($,Z={}){let J=i2($),Q=Z.now??Date.now(),q=Z.staleMs??l2;if(r2(J,{now:Q,staleMs:q}))return null;let X=Q$(J);if(!t8(X))return null;if(a2(X))return null;return`${X.provider} session ${X.session} (pid ${X.pid})`}function s2($,Z){qq(Vq($),{recursive:!0});try{let J=Xq($,"wx");try{Yq(J,JSON.stringify(Z))}finally{Qq(J)}return!0}catch{return!1}}function Fq($,Z,J){if(!Mq($,Z))return{stolen:!1,previousHolder:null};let Q=Q$($);try{c2($)}catch{return{stolen:!1,previousHolder:null}}return{stolen:s2($,J),previousHolder:Q}}function Cq($,Z){let J=Q$($);if(J&&J.pid===Z)try{c2($)}catch{}}async function o2($,Z,J,Q,q={}){let X=q.waitMs??o8,W=q.staleMs??l2,z=q.unreadableGraceMs??Bq,Y=q.now??Date.now,V=q.sleep??Uq,G=q.random??Math.random,H=q.baseMs??20,B=q.capMs??500,K=i2($),A=Y()+X,D=process.pid,O$=0;while(!0){let IJ=Y(),PJ={provider:Z,session:J,pid:D,acquired_at:new Date(IJ).toISOString(),host:d2()};if(s2(K,PJ))return h2(K,D,Q);let D8=Fq(K,{staleMs:W,graceMs:z,now:IJ},PJ);if(D8.stolen){if(D8.previousHolder)q.onSteal?.(D8.previousHolder);return h2(K,D,Q)}if(Y()>=A){let jJ=e8($);throw new k$(`gate lock busy at ${K} after ${X}ms${jJ?` — held by ${jJ}`:""}`)}await V($$({attempt:O$,baseMs:H,capMs:B,random:G})),O$+=1}}async function h2($,Z,J){try{return await J()}finally{Cq($,Z)}}function t2($){let Z=$.max??T$,J=$.artifact.findings.slice(0,Z);if(J.length===0)return[{id:`${$.artifact.gate}-0`,gate:$.artifact.gate,category:$.category,summary:`${$.artifact.gate} failed (exit ${$.artifact.exitCode})`}];return J.map((Q,q)=>({id:Q.id??`${$.artifact.gate}-${q}`,gate:$.artifact.gate,category:$.category,summary:Q.summary,detail:Q.detail}))}import{createHash as Oq}from"node:crypto";import{existsSync as _q,mkdirSync as Iq,readFileSync as e2,writeFileSync as Pq}from"node:fs";import{basename as jq,dirname as $9,join as Nq}from"node:path";var Lq="harness.seal.v1";function $Z($){return Nq($9($),".seal",`${jq($)}.json`)}function Z9($){try{return Oq("sha256").update(e2($)).digest("hex")}catch{return null}}function x$($){let Z=Z9($);if(Z===null)return;try{Iq($9($Z($)),{recursive:!0}),Pq($Z($),JSON.stringify({schema:Lq,hash:Z}))}catch{}}function S$($){if(!_q($))return"absent";let Z=null;try{let J=JSON.parse(e2($Z($),"utf8"));Z=typeof J.hash==="string"?J.hash:null}catch{Z=null}if(Z===null)return"unsealed";return Z9($)===Z?"sealed":"diverged"}function f$($){return $!=="diverged"}function b$($,Z){return[`${Z} at ${$} changed without a harness write behind it, so it was not injected into this turn.`,"That file is read aloud to the model, so text placed in it reaches every later turn. Read it, and if the","contents are yours, the next harness write reseals it."].join(`
|
|
@@ -106,7 +106,7 @@ ${" ".repeat(4)}${Z.dim(j.bar)} ${z.detail}`:B});return[Z.heading(`LAST ${$.leng
|
|
|
106
106
|
`)}var PZ=["comments"];function s$($){return PZ.includes($)}function J1($){return $.filter((Z)=>!s$(Z))}function Q1($,Z,J){return $.enabled&&!J&&s$(Z)&&$.rails.includes(Z)}function q1($){return{rail:$.rail,violations:$.violations,prose_injected:$.proseInjected,reading:$.violations===0?$.proseInjected?"held-with-prose":"held-without-prose":$.proseInjected?"violated-with-prose":"violated-without-prose"}}var pX=/(?:^|\n)\s*HARNESS_PLAN:\s*(.+?)\s*(?=\n|$)/,cX=/(?:^|\n)\s*HARNESS_PLAN_DEVIATION:\s*(.+?)\s*(?=\n|$)/g,dX=/\s+(?:—|--|-)\s+/;function lX($){return $.split(/[,\s]+/).map((Z)=>Z.trim()).filter((Z)=>Z.length>0)}function X1($){let J=pX.exec($)?.[1]?.trim();if(!J)return null;let Q=lX(J);if(Q.length===0)return null;return{paths:Q,snippet:`HARNESS_PLAN: ${J}`.slice(0,280)}}function W1($){let Z=[];for(let J of $.matchAll(cX)){let Q=J[1]?.trim();if(!Q)continue;let[q,...X]=Q.split(dX),W=q?.trim(),z=X.join(" ").trim();if(!W||z.length===0)continue;Z.push({path:W,reason:z})}return Z}import{existsSync as B1,readFileSync as aX}from"node:fs";import{join as sX}from"node:path";var iX={enabled:!1,maxInjectSession:5,maxInjectRetry:8,maxCharsSession:900,maxCharsRetry:1400,promoteHitCount:2,decayLambda:0.02,projectBoost:1.5,syncRulesFile:"auto",gardenOnSessionEnd:!0},G$={version:1,mode:"solo",codePaths:["src","apps","libs","packages"],grind:{enabled:!1,maxLoops:5,lintCommand:null,testCommand:null,appendFiles:"auto"},shipGate:{enabled:!1,runtimePathPrefixes:["src","apps","libs","packages","deploy","scripts"],runtimePathExcludes:[".tlc/","**/node_modules/","**/.git/"],evidenceDir:null,evidenceMaxAgeHours:48,emptyDiffAntiShip:!1,claimWindowMinutes:10},subagents:{enforceAllowlist:!1,requireModel:!1,allowedModels:[],blockedPatterns:["-fast(?:$|[^a-z0-9])","/fast(?:$|[^a-z0-9])"],minEffort:null,blockParentFast:!1,blockMode:"deny",readOnlyTypes:["explore"]},docs:{command:null,severity:"warn"},observe:{enabled:!1,rails:[]},comments:{enabled:!1,onViolation:"followup",mode:"declared"},supplyChain:{enabled:!1},duplication:{enabled:!1,minRun:x},obs:{globalSpool:!1,includePayloads:w.includePayloads,maxAttrChars:w.maxAttrChars,sessionCostAlertUsd:w.sessionCostAlertUsd,retentionDays:w.retentionDays},untrustedContent:{mode:"frame",enabled:!1,extraTools:[],extraCommandPatterns:[]},planGate:{enabled:!1,windowMinutes:120},rules:{enabled:!1},shell:{catastrophicAsk:!0,stallDetection:!1,stallRepeatThreshold:3},intelligence:{gapFeedback:!0,failureClassification:!0,progressiveHandoff:!0,progressiveContext:!0,autopilot:!0,idleTurnGate:!1,budgetContinue:!1,budgetContinueAfterLoops:3,lessons:{...iX}},mcpPrime:[],bootstrapExtra:[]};import{existsSync as Y1,readFileSync as nX}from"node:fs";import{join as V1}from"node:path";var jZ=["paired","solo","focus"],z1="solo";function o$($){return typeof $==="string"&&jZ.includes($)}function rX($){let Z=V1(U($),"harness-mode");if(!Y1(Z))return null;try{return nX(Z,"utf8").trim().toLowerCase()}catch{return null}}function G1($,Z){let J=rX($);if(o$(J))return{mode:J,origin:"file"};for(let Q of["focus","paired"])if(Y1(V1(k($),Q)))return{mode:Q,origin:"flag"};if(o$(Z))return{mode:Z,origin:"config"};if(Z===void 0||Z===null)return{mode:z1,origin:"config"};return{mode:z1,origin:"fallback",invalid:String(Z)}}function NZ($){if(!B1($))return null;try{return JSON.parse(aX($,"utf8"))}catch{return null}}function LZ($,Z){return{...$,...Z,grind:{...$.grind,...Z.grind},shipGate:{...$.shipGate,...Z.shipGate},subagents:{...$.subagents,...Z.subagents},docs:{...$.docs,...Z.docs},observe:{...$.observe,...Z.observe},comments:{...$.comments,...Z.comments},supplyChain:{...$.supplyChain,...Z.supplyChain},duplication:{...$.duplication,...Z.duplication},obs:{...$.obs,...Z.obs},untrustedContent:{...$.untrustedContent,...Z.untrustedContent},planGate:{...$.planGate,...Z.planGate},shell:{...$.shell,...Z.shell},intelligence:{...$.intelligence,...Z.intelligence,lessons:{...$.intelligence.lessons,...Z.intelligence?.lessons}},codePaths:Z.codePaths??$.codePaths,mcpPrime:Z.mcpPrime??$.mcpPrime,bootstrapExtra:Z.bootstrapExtra??$.bootstrapExtra}}function oX($,Z){return B1(sX(k($),Z))}function AZ($){return{fromUser:NZ(E())??{},fromProject:NZ(O($))??{}}}function U1($,Z){return G1($,Z.fromProject.mode??Z.fromUser.mode)}function H1($){return U1($,AZ($))}function K1($){let Z=AZ($),J=Z.fromProject.intelligence?.lessons?.syncRulesFile,Q=J??Z.fromUser.intelligence?.lessons?.syncRulesFile,q=Y$(Q);if(q.coercedFrom===void 0)return q;let X=J===void 0?E():O($);return{...q,coercedIn:X}}function M1($){let Z=AZ($),J=LZ(LZ(G$,Z.fromUser),Z.fromProject);if(J.mode=U1($,Z).mode,oX($,"grind-on"))J.grind.enabled=!0;return J.intelligence.lessons.syncRulesFile=b9(J.intelligence.lessons.syncRulesFile),J}function F1(){let $=NZ(E())??{};return LZ(G$,$)}function t$($,Z){let J=$.replace(/\\/g,"/");return Z.some((Q)=>J===Q||J.startsWith(`${Q}/`))}import{existsSync as C1,readdirSync as tX,readFileSync as eX,statSync as O1}from"node:fs";import{join as DZ}from"node:path";function _1($){return DZ(U($),"ship-ledger.jsonl")}function I1($,Z){let J={...Z,ts:Z.ts??new Date().toISOString()};N(_1($),J)}function P1($){return R(_1($),Number.MAX_SAFE_INTEGER)}function e$($,Z,J){if(!C1($))return!1;let Q=Z*60*60*1000,q=Date.now();for(let X of tX($)){let W=DZ($,X,"90-verdict.txt");if(!C1(W))continue;try{let z=O1(W).mtimeMs;if(J!==void 0&&z<J)continue;if(q-z>Q)continue;if(/\bPASS\b/i.test(eX(W,"utf8")))return!0}catch{}}return!1}function j1($,Z){let J;for(let Q of Z)try{let q=O1(DZ($,Q)).mtimeMs;if(J===void 0||q>J)J=q}catch{}return J}var $4=/(?:^|\n)\s*HARNESS_SHIP_CLAIM:\s*(.+?)\s*(?=\n|$)/;function N1($){let Z=$.trim();if(!Z)return null;let Q=Z.match($4)?.[1]?.trim();if(!Q)return null;return{kind:"structured",snippet:`HARNESS_SHIP_CLAIM: ${Q}`.slice(0,280)}}function $8($,Z){let J=$.replace(/\\/g,"/");for(let Q of Z){let q=Q.replace(/\\/g,"/").replace(/^\.\//,"");if(!q)continue;if(q.endsWith("/**")){let X=q.slice(0,-3);if(J===X||J.startsWith(`${X}/`))return!0;continue}if(q.endsWith("/")){if(J.startsWith(q)||J.startsWith(`${q.slice(0,-1)}/`))return!0;continue}if(q.includes("*")){if(new RegExp(`^${q.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*")}$`).test(J))return!0;continue}if(J===q||J.startsWith(`${q}/`))return!0}return!1}function TZ($,Z,J){return $.some((Q)=>{if($8(Q,J))return!1;return t$(Q,Z)||/^Dockerfile(\.|$)/.test(Q)})}function L1($,Z,J=Date.now()){if(!$)return!1;let Q=Date.parse($);if(Number.isNaN(Q))return!1;return J-Q<Z*60*1000}function A1($){if($.enabled&&$.recentShipClaim&&$.changedFilesCount===0)return{kind:"continue",text:["BLOCKED: HARNESS_SHIP_CLAIM with no file diff.","TRIED: inspected git working tree / changed files.","NEED: either implement the remaining work or remove the ship claim — do not claim ship on an empty diff."].join(`
|
|
107
107
|
`)};return{kind:"abstain"}}function D1($){if(!$.enabled||!$.recentShipClaim||$.changedFiles.length===0)return{kind:"abstain"};if(!TZ($.changedFiles,$.runtimePathPrefixes,$.runtimePathExcludes))return{kind:"abstain"};if($.evidenceDir!==null&&e$($.evidenceDir,$.evidenceMaxAgeHours,$.evidenceNotBeforeMs))return{kind:"abstain"};return{kind:"continue",text:["BLOCKED: HARNESS_SHIP_CLAIM without recent production PASS evidence.",`TRIED: checked ${$.evidenceDir??"(no evidenceDir configured)"}/*/90-verdict.txt.`,"NEED: run the verification after the last code change, then cite the verdict path — evidence written before the change certifies the older tree."].join(`
|
|
108
108
|
`)}}function Z4($,Z,J=Date.now()){if(!$)return!1;let Q=Date.parse($);if(Number.isNaN(Q))return!1;return J-Q<Z*60*1000}function J4($){let Z=$.deviations.map((J)=>J.path);return $.changedFiles.filter((J)=>{if($8(J,[...$.planned]))return!1;return!$8(J,Z)})}function T1($){let Z=RZ($);if(!Z.active||Z.unplanned.length===0)return{kind:"abstain"};let J=Z.unplanned.slice(0,10).join(", "),Q=Z.unplanned.length>10?` (+${Z.unplanned.length-10} more)`:"";return{kind:"continue",text:[`BLOCKED: ${Z.unplanned.length} changed file(s) are outside the declared plan: ${J}${Q}`,`TRIED: compared the working tree against HARNESS_PLAN (${$.planned.join(", ")}).`,"NEED: either revert what the plan did not call for, or justify each path with a reason —","HARNESS_PLAN_DEVIATION: <path> — <why this file had to change>"].join(`
|
|
109
|
-
`)}}function RZ($){if(!$.enabled||$.planned.length===0)return{active:!1,unplanned:[]};if(!Z4($.declaredAt,$.windowMinutes,$.now??Date.now()))return{active:!1,unplanned:[]};return{active:!0,unplanned:J4({changedFiles:$.changedFiles,planned:$.planned,deviations:$.deviations})}}var Q4=new Set(["Edit","Write","Delete","MultiEdit","NotebookEdit"]);function Z8($){return $!==void 0&&Q4.has($)}function R1($){if(!Z8($.toolName)||!$.filePath)return{kind:"allow"};if(!A$($.projectDir,$.filePath))return{kind:"allow"};return{kind:"deny",reason:["Harness policy and state are not agent-writable — a gate an agent can switch off is not a gate.","The harness CLI does not help you here either: the same floor rule refuses the mutating subcommands from inside a session.","Tell the operator which value you would change and why, and let them run it from their own terminal."].join(" "),userNote:`Blocked an agent write to ${$.filePath}.`,rule:"policy-surface-write"}}import{createHash as q4}from"node:crypto";import{existsSync as U$,mkdirSync as X4,readdirSync as EZ,readFileSync as E1,writeFileSync as kZ}from"node:fs";import{join as B$}from"node:path";var W4="absent",xZ="harness.policy-baseline.v1",z4="harness-mode",Y4=["grind-on","skip-verify","focus","paired"];function V4($){if(!U$($))return W4;try{return q4("sha256").update(E1($)).digest("hex")}catch{return"unreadable"}}function v($){
|
|
109
|
+
`)}}function RZ($){if(!$.enabled||$.planned.length===0)return{active:!1,unplanned:[]};if(!Z4($.declaredAt,$.windowMinutes,$.now??Date.now()))return{active:!1,unplanned:[]};return{active:!0,unplanned:J4({changedFiles:$.changedFiles,planned:$.planned,deviations:$.deviations})}}var Q4=new Set(["Edit","Write","Delete","MultiEdit","NotebookEdit"]);function Z8($){return $!==void 0&&Q4.has($)}function R1($){if(!Z8($.toolName)||!$.filePath)return{kind:"allow"};if(!A$($.projectDir,$.filePath))return{kind:"allow"};return{kind:"deny",reason:["Harness policy and state are not agent-writable — a gate an agent can switch off is not a gate.","The harness CLI does not help you here either: the same floor rule refuses the mutating subcommands from inside a session.","Tell the operator which value you would change and why, and let them run it from their own terminal."].join(" "),userNote:`Blocked an agent write to ${$.filePath}.`,rule:"policy-surface-write"}}import{createHash as q4}from"node:crypto";import{existsSync as U$,mkdirSync as X4,readdirSync as EZ,readFileSync as E1,writeFileSync as kZ}from"node:fs";import{join as B$}from"node:path";var W4="absent",xZ="harness.policy-baseline.v1",z4="harness-mode",Y4=["grind-on","skip-verify","focus","paired"];function V4($){if(!U$($))return W4;try{return q4("sha256").update(E1($)).digest("hex")}catch{return"unreadable"}}function v($){let Z=[O($),E(),B$(U($),z4),...Y4.map((Q)=>B$(k($),Q))],J=new Set;return Z.filter((Q)=>!J.has(Q)&&J.add(Q)!==void 0).map((Q)=>({path:Q,hash:V4(Q)}))}function k1($,Z){return B$(p($),`${I(Z)}.json`)}function SZ($,Z){try{X4(p($),{recursive:!0}),kZ(k1($,Z),`${JSON.stringify({schema:xZ,sources:v($)},null,2)}
|
|
110
110
|
`,"utf8")}catch{}}function J8($,Z){let J=k1($,Z);if(!U$(J))return null;try{let Q=JSON.parse(E1(J,"utf8"));return Array.isArray(Q.sources)?Q.sources:null}catch{return null}}function fZ($,Z){let J=new Map($.map((Q)=>[Q.path,Q.hash]));return Z.filter((Q)=>{let q=J.get(Q.path);return q!==void 0&&q!==Q.hash}).map((Q)=>Q.path)}function x1($,Z){let J=J8($,Z);return J===null?[]:fZ(J,v($))}function S1($){let Z=p($);if(!U$(Z))return[];let J=new Set,Q=v($);for(let q of EZ(Z)){if(!q.endsWith(".json"))continue;let X=J8($,q.replace(/\.json$/,""));if(X)for(let W of fZ(X,Q))J.add(W)}return[...J].sort()}function f1($,Z){let J=v($),Q=new Map(J.map((W)=>[W.path,W.hash])),q=Z.filter((W)=>!Q.has(W));if(q.length>0)return{kind:"not-a-source",paths:q,sources:J.map((W)=>W.path)};let X=p($);if(!U$(X)||Z.length===0)return{kind:"nothing-to-accept"};for(let W of EZ(X)){if(!W.endsWith(".json"))continue;let z=W.replace(/\.json$/,""),Y=J8($,z);if(!Y)continue;let V=Y.map((G)=>Z.includes(G.path)?{path:G.path,hash:Q.get(G.path)}:G);try{kZ(B$(X,W),`${JSON.stringify({schema:xZ,sources:V},null,2)}
|
|
111
111
|
`,"utf8")}catch{}}return{kind:"accepted",paths:Z}}function b1($,Z){let J=J8($,Z);if(!J)return SZ($,Z),{kind:"allow"};let Q=fZ(J,v($));if(Q.length===0)return{kind:"allow"};return{kind:"deny",reason:[`HARNESS: ${Q.join(", ")} changed during this session, and no harness command changed it.`,"The gates are now running a policy the operator did not set, so what they check cannot be trusted.","Report this to the operator and name the paths above. Only they can clear it, from their own terminal — the harness commands that would are refused from inside a session, so there is nothing for you to run here."].join(`
|
|
112
112
|
`),userNote:[`Harness policy changed out of band during this session: ${Q.join(", ")}.`,`If that was you, accept it with: tlc harness policy accept ${Q.join(" ")}`].join(" "),rule:"policy-baseline-divergence"}}function y1($){let Z=p($);if(!U$(Z))return;let J=v($);for(let Q of EZ(Z)){if(!Q.endsWith(".json"))continue;try{kZ(B$(Z,Q),`${JSON.stringify({schema:xZ,sources:J},null,2)}
|
|
@@ -143,13 +143,13 @@ ${$.body.trim()}`}function W8($,Z,J){let Q=[];for(let q of $){let X=K5(q,Z,J);if
|
|
|
143
143
|
`:"",X=J.length>0?`${J}${q}
|
|
144
144
|
${BJ}
|
|
145
145
|
`:`${BJ}
|
|
146
|
-
`;return Uz(o6(Z),{recursive:!0}),Kz(Z,X,"utf8"),Z}import{dirname as
|
|
146
|
+
`;return Uz(o6(Z),{recursive:!0}),Kz(Z,X,"utf8"),Z}import{dirname as WK,join as Cz}from"node:path";var Oz=[{hookEvent:"SessionStart",handler:"session-start",timeoutSeconds:10},{hookEvent:"SessionEnd",handler:"session-end",timeoutSeconds:10},{hookEvent:"UserPromptSubmit",handler:"prompt-submit",timeoutSeconds:5},{hookEvent:"PreToolUse",handler:"tool-before",timeoutSeconds:10,failClosed:!0},{hookEvent:"PostToolUse",handler:"tool-after",timeoutSeconds:10},{hookEvent:"PostToolUseFailure",handler:"tool-failure",timeoutSeconds:5},{hookEvent:"SubagentStart",handler:"subagent-start",timeoutSeconds:5,failClosed:!0},{hookEvent:"SubagentStop",handler:"subagent-stop",timeoutSeconds:5},{hookEvent:"Stop",handler:"stop",timeoutSeconds:120,loopLimit:5},{hookEvent:"PreCompact",handler:"compact-before",timeoutSeconds:5},{hookEvent:"MessageDisplay",handler:"response-after",timeoutSeconds:5}];function _z(){return Cz(DJ(),"settings.json")}function HJ($){let Z=Oz.map((J)=>({hookEvent:J.hookEvent,handler:J.handler,command:"node",args:[$.launcherPath,J.handler],timeoutSeconds:J.timeoutSeconds,...J.failClosed!==void 0?{failClosed:J.failClosed}:{},...J.loopLimit!==void 0?{loopLimit:J.loopLimit}:{}}));return{target:_z(),strategy:"merge",entries:Z}}import{existsSync as Iz,mkdirSync as Pz,readFileSync as jz,writeFileSync as Nz}from"node:fs";import{dirname as e6,join as $7}from"node:path";function Lz($){return $7(e6(O($)),"lessons.md")}function Az($){return $7($,".cursor","rules","harness-lessons.mdc")}function KJ($){let Z=Lz($);if(!Iz(Z))return null;let J=jz(Z,"utf8"),Q=Az($);Pz(e6(Q),{recursive:!0});let q=`---
|
|
147
147
|
description: Harness-learned lessons (auto-synced from gate failures)
|
|
148
148
|
alwaysApply: true
|
|
149
149
|
---
|
|
150
150
|
|
|
151
151
|
${J}`;return Nz(Q,q,"utf8"),Q}var Dz={rewriteUnavailable:"rewrite-unavailable"};var Tz=new Set(["bypassPermissions","dontAsk"]);function Rz($){return $.kind==="deny"||$.kind==="ask"||$.kind==="continue"||$.kind==="rewriteInput"}function Ez($){switch($.kind){case"deny":case"ask":return $.reason;case"continue":return $.text;case"rewriteInput":return`${$.reason} (proposed input: ${JSON.stringify($.input)})`;default:return""}}function Z7($,Z){if($.length<=Z)return $;if(Z<=0)return"";let J=35<=Z?`
|
|
152
152
|
…(truncated — over context budget)`:`
|
|
153
|
-
…(truncated — over context budget)`.slice(0,Z),Q=Math.max(0,Z-J.length);return`${$.slice(0,Q)}${J}`}function kz($,Z){if($.event==="tool.before")return Z.contextAtToolBefore;if($.event==="tool.after")return Z.contextAtToolAfter;if($.event==="stop")return Z.contextAtStop;return!0}function MJ($,Z){if($.kind!=="context"||Z===void 0)return $;let J=Z7($.text,Z);if(J===$.text)return $;return{...$,text:J}}function FJ($,Z,J,Q={}){if(!J.enforcesHooks&&Rz($))return MJ({kind:"context",text:`${"ADVISORY — this provider cannot enforce: "}${Ez($)}`},Q.contextBudgetChars);if($.kind==="ask"){if(!J.askSupportedOn.includes(Z.event))return{kind:"deny",reason:`${"Escalation unavailable on this provider — "}${$.reason}`,userNote:$.userNote,rule:$.rule};if(Z.permissionMode!==void 0&&Tz.has(Z.permissionMode))return{kind:"deny",reason:`${"No operator is answering prompts in this permission mode — "}${$.reason}`,userNote:$.userNote,rule:$.rule};return $}if($.kind==="rewriteInput"&&!J.toolInputRewrite)return{kind:"ask",reason:`Input rewrite unavailable on this provider — proposed input: ${JSON.stringify($.input)}. ${$.reason}`,rule:Dz.rewriteUnavailable};if($.kind==="context"){if(!kz(Z,J))return{kind:"abstain"};if($.env&&!J.sessionEnv){let{env:q,...X}=$;return MJ(X,Q.contextBudgetChars)}return MJ($,Q.contextBudgetChars)}return $}function J7(){return{enforcesHooks:!0,askSupportedOn:["tool.before","shell.before","mcp.before","read.before"],sessionEnv:!1,nativeLoopCounter:!1,dedicatedShellEvent:!1,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!0,contextAtToolAfter:!0,contextAtStop:!0,sessionStartContextReliable:!0,toolOutputAtAfter:!0,usageInPayload:!1,effortSignal:!0,thoughtEvent:!1}}var xz=/^[A-Z][a-zA-Z0-9]*$/;function Q7($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!xz.test(J))return!1;return typeof Z.cwd==="string"||typeof Z.transcript_path==="string"}var Sz={SessionStart:"session.start",SessionEnd:"session.end",UserPromptSubmit:"prompt.submit",PostToolUseFailure:"tool.failure",SubagentStart:"subagent.start",SubagentStop:"subagent.stop",Stop:"stop",PreCompact:"compact.before",MessageDisplay:"response.after"},q7=/^mcp__/;function F($){return typeof $==="string"?$:void 0}function fz($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function X7($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function bz($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function yz($){let Z=F($.session_id)??"default";return`claude-${I(Z)}`}function wz($){let Z=process.env.CLAUDE_PROJECT_DIR;if(Z)return Z;let J=F($.cwd);if(J)return J;return process.cwd()}function vz($){let J=X7($.effort)?.level;return C8(J)?J:void 0}function mz($){if($==="Bash")return"shell.before";if($&&q7.test($))return"mcp.before";if($==="Read")return"read.before";return"tool.before"}function gz($){if($==="Bash")return"shell.after";if($&&q7.test($))return"mcp.after";if($==="Edit"||$==="Write")return"edit.after";return"tool.after"}function W7($){let Z=F($.hook_event_name);if(!Z)return null;let J=F($.tool_name),Q=X7($.tool_input),q;if(Z==="PreToolUse")q=mz(J);else if(Z==="PostToolUse")q=gz(J);else q=Sz[Z];if(!q)return null;let X={provider:"claude",event:q,sessionKey:yz($),projectDir:wz($),raw:$},W=F($.permission_mode);if(W)X.permissionMode=W;let z=q==="subagent.start"||q==="subagent.stop",Y=z?void 0:F($.model);if(Y)X.model=Y;let V=vz($);if(V)X.effort=V;let G=fz($.context_usage_percent);if(G!==void 0)X.contextUsagePercent=G;let H=F($.transcript_path);if(H)X.transcriptPath=H;if(!z){let B=F($.agent_type);if(B)X.subagentType=B}switch(q){case"prompt.submit":{let B=F($.prompt);if(B!==void 0)X.text=B;break}case"response.after":{let B=F($.text);if(B!==void 0)X.text=B;break}case"shell.before":case"shell.after":{let B=Q?F(Q.command):void 0;if(B!==void 0)X.command=B;break}case"mcp.before":case"mcp.after":{if(J)X.toolName=J;if(Q)X.toolInput=Q;break}case"read.before":{let B=Q?F(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"edit.after":{if(J)X.toolName=J;let B=Q?F(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"tool.before":case"tool.after":case"tool.failure":{if(J)X.toolName=J;let B=$.tool_response;if(B!==void 0&&B!==null)X.toolOutput=typeof B==="string"?B:JSON.stringify(B);if(Q)X.toolInput=Q;let K=Q?F(Q.file_path):void 0;if(K!==void 0)X.filePath=K;let A=Q?F(Q.subagent_type):void 0;if(A)X.spawnSubagentType=A;let D=Q?F(Q.model):void 0;if(D)X.spawnModel=D;break}case"subagent.start":case"subagent.stop":{let B=F($.agent_type)??F($.subagent_type)??(Q?F(Q.subagent_type):void 0);if(B)X.spawnSubagentType=B;let K=(Q?F(Q.model):void 0)??F($.model);if(K)X.spawnModel=K;break}case"stop":{let B=bz($.status);if(B)X.status=B;break}default:break}return X}var uz={"session.start":"SessionStart","session.end":"SessionEnd","prompt.submit":"UserPromptSubmit","tool.before":"PreToolUse","tool.after":"PostToolUse","tool.failure":"PostToolUseFailure","shell.before":"PreToolUse","shell.after":"PostToolUse","mcp.before":"PreToolUse","mcp.after":"PostToolUse","read.before":"PreToolUse","edit.after":"PostToolUse","subagent.start":"SubagentStart","subagent.stop":"SubagentStop",stop:"Stop","compact.before":"PreCompact","response.after":"MessageDisplay","thought.after":"MessageDisplay"};function CJ($,Z,J){let Q={hookEventName:Z,permissionDecision:$};if(J!==void 0)Q.permissionDecisionReason=J;return JSON.stringify({hookSpecificOutput:Q})}function z7($,Z){let J=uz[Z.event];switch($.kind){case"abstain":return{stdout:null,exitCode:0};case"allow":return{stdout:CJ("allow",J,void 0),exitCode:0};case"deny":return{stdout:CJ("deny",J,$.reason),exitCode:0};case"ask":return{stdout:CJ("ask",J,$.reason),exitCode:0};case"context":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,additionalContext:$.text}}),exitCode:0};case"continue":return{stdout:JSON.stringify({decision:"block",reason:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,updatedInput:$.input}}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function Y7(){return{blockedPatterns:[],minEffort:null,untrustedTools:["WebFetch","WebSearch"]}}var V7={name:"claude",detect:Q7,capabilities:J7,policyDefaults:Y7,toEvent:W7,render:z7,wiring:HJ};function G7(){return{enforcesHooks:!0,askSupportedOn:["shell.before","mcp.before"],sessionEnv:!0,nativeLoopCounter:!0,dedicatedShellEvent:!0,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!1,contextAtToolAfter:!0,contextAtStop:!1,sessionStartContextReliable:!1,toolOutputAtAfter:!0,usageInPayload:!0,effortSignal:!1,thoughtEvent:!0}}var hz=/^[a-z][a-zA-Z0-9]*$/;function B7($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!hz.test(J))return!1;return Array.isArray(Z.workspace_roots)}var pz={sessionStart:"session.start",sessionEnd:"session.end",beforeSubmitPrompt:"prompt.submit",preToolUse:"tool.before",postToolUse:"tool.after",postToolUseFailure:"tool.failure",beforeShellExecution:"shell.before",afterShellExecution:"shell.after",beforeMCPExecution:"mcp.before",afterMCPExecution:"mcp.after",beforeReadFile:"read.before",afterFileEdit:"edit.after",subagentStart:"subagent.start",subagentStop:"subagent.stop",stop:"stop",preCompact:"compact.before",afterAgentResponse:"response.after",afterAgentThought:"thought.after"};function C($){return typeof $==="string"?$:void 0}function U7($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function H7($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function cz($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function dz($){let Z=C($.conversation_id)||C($.session_id)||"default";return`cursor-${I(Z)}`}function lz($){let Z=process.env.CURSOR_PROJECT_DIR;if(Z)return Z;let J=$.workspace_roots;if(Array.isArray(J)){let Q=C(J[0]);if(Q)return Q}return process.cwd()}function K7($){let Z=C($.hook_event_name),J=Z?pz[Z]:void 0;if(!J)return null;let Q={provider:"cursor",event:J,sessionKey:dz($),projectDir:lz($),raw:$},q=C($.model);if(q)Q.model=q;let X=U7($.context_usage_percent);if(X!==void 0)Q.contextUsagePercent=X;switch(J){case"prompt.submit":{let W=C($.prompt);if(W!==void 0)Q.text=W;break}case"response.after":{let W=C($.text);if(W!==void 0)Q.text=W;break}case"thought.after":{let W=C($.thought)??C($.text);if(W!==void 0)Q.text=W;break}case"tool.before":case"tool.after":case"tool.failure":{let W=C($.tool_name);if(W)Q.toolName=W;let z=H7($.tool_input);if(z)Q.toolInput=z;let Y=C($.subagent_type);if(Y)Q.subagentType=Y;let V=z?C(z.model):void 0;if(V)Q.spawnModel=V;let G=z?C(z.subagent_type):void 0;if(G)Q.spawnSubagentType=G;break}case"shell.before":case"shell.after":{let W=C($.command);if(W!==void 0)Q.command=W;let z=C($.output);if(z!==void 0)Q.toolOutput=z;break}case"mcp.before":case"mcp.after":{let W=C($.result_json);if(W!==void 0)Q.toolOutput=W;let z=C($.tool_name);if(z)Q.toolName=z;let Y=H7($.tool_input);if(Y)Q.toolInput=Y;let V=C($.command);if(V!==void 0)Q.command=V;break}case"read.before":case"edit.after":{let W=C($.file_path);if(W!==void 0)Q.filePath=W;break}case"subagent.start":case"subagent.stop":{let W=C($.subagent_type);if(W)Q.spawnSubagentType=W;let z=C($.subagent_model);if(z)Q.spawnModel=z;break}case"stop":{let W=cz($.status);if(W)Q.status=W;let z=U7($.loop_count);if(z!==void 0)Q.loopCount=z;break}default:break}return Q}function M7($,Z){let J={permission:$};if(Z.userNote!==void 0)J.user_message=Z.userNote;return J.agent_message=Z.reason,JSON.stringify(J)}function F7($,Z){switch($.kind){case"abstain":return{stdout:"{}",exitCode:0};case"allow":return{stdout:JSON.stringify({permission:"allow"}),exitCode:0};case"deny":return{stdout:M7("deny",$),exitCode:0};case"ask":return{stdout:M7("ask",$),exitCode:0};case"context":{let J={};if($.env!==void 0)J.env=$.env;return J.additional_context=$.text,{stdout:JSON.stringify(J),exitCode:0}}case"continue":return{stdout:JSON.stringify({followup_message:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({updated_input:$.input}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function C7(){return{blockedPatterns:["-fast(?:$|[^a-z0-9])","/fast(?:$|[^a-z0-9])","composer-2\\.5-fast"],minEffort:null,untrustedTools:["Fetch","WebSearch"]}}import{join as iz}from"node:path";var nz=[{hookEvent:"sessionStart",handler:"session-start",timeoutSeconds:10},{hookEvent:"sessionEnd",handler:"session-end",timeoutSeconds:10},{hookEvent:"beforeSubmitPrompt",handler:"prompt-submit",timeoutSeconds:5},{hookEvent:"afterAgentThought",handler:"tool-after",timeoutSeconds:5},{hookEvent:"preCompact",handler:"compact-before",timeoutSeconds:5},{hookEvent:"subagentStart",handler:"subagent-start",timeoutSeconds:5,failClosed:!0},{hookEvent:"subagentStop",handler:"subagent-stop",timeoutSeconds:5},{hookEvent:"preToolUse",handler:"tool-before",timeoutSeconds:5,failClosed:!0},{hookEvent:"postToolUse",handler:"tool-after",timeoutSeconds:5},{hookEvent:"postToolUseFailure",handler:"tool-failure",timeoutSeconds:5},{hookEvent:"beforeShellExecution",handler:"tool-before",timeoutSeconds:10,failClosed:!0},{hookEvent:"afterShellExecution",handler:"tool-after",timeoutSeconds:10},{hookEvent:"beforeMCPExecution",handler:"tool-before",timeoutSeconds:10},{hookEvent:"afterMCPExecution",handler:"tool-after",timeoutSeconds:5},{hookEvent:"beforeReadFile",handler:"tool-before",timeoutSeconds:5},{hookEvent:"afterFileEdit",handler:"tool-after",timeoutSeconds:30,matcher:"Write"},{hookEvent:"stop",handler:"stop",timeoutSeconds:120,loopLimit:5},{hookEvent:"afterAgentResponse",handler:"response-after",timeoutSeconds:5,matcher:"AgentResponse"}];function O7($){let J=[$.launcherPath],Q=nz.map((q)=>({hookEvent:q.hookEvent,handler:q.handler,command:"node",args:[...J,q.handler],timeoutSeconds:q.timeoutSeconds,...q.failClosed!==void 0?{failClosed:q.failClosed}:{},...q.matcher!==void 0?{matcher:q.matcher}:{},...q.loopLimit!==void 0?{loopLimit:q.loopLimit}:{}}));return{target:iz(TJ(),"hooks.json"),strategy:"replace",entries:Q}}var _7={name:"cursor",detect:B7,capabilities:G7,policyDefaults:C7,toEvent:K7,render:F7,wiring:O7};var OJ=[_7,V7];function _J($,Z){let J=Z.filter((Q)=>Q.detect($));if(J.length===0)return{provider:null,ambiguous:!1,matchedNames:[]};return{provider:J[0]??null,ambiguous:J.length>1,matchedNames:J.map((Q)=>Q.name)}}var I7=M.observability.DEFAULT_OBS,XM={...I7,debugEnabled:!0};function P7($,Z=I7){return{...Z,globalSpool:$.obs.globalSpool,includePayloads:$.obs.includePayloads,maxAttrChars:$.obs.maxAttrChars,sessionCostAlertUsd:$.obs.sessionCostAlertUsd,retentionDays:$.obs.retentionDays}}function A8($){let Z=`${$.provider}-`;return $.sessionKey.startsWith(Z)?$.sessionKey.slice(Z.length):$.sessionKey}function j7($,Z){return[...M.policy.forProvider($,Z.name)??[],...Z.policyDefaults().blockedPatterns]}function N7($,Z){if($==="cursor")return KJ(Z);if($==="claude")return UJ(Z);return null}var az=6000;function sz($){if($.filePath===void 0)return!1;if($.event==="edit.after")return!0;return Z8($.toolName)}function oz($){return $ instanceof Error?$.message:String($)}function e($,Z,J){try{N(rz(U($),"obs.jsonl"),{schema:"harness.observability.v1",provider:"unknown",kind:Z,level:"signal",ts:new Date().toISOString(),attrs:J})}catch{}}function tz($,Z,J){if(J.kind!=="deny"&&J.kind!=="ask")return;if($.event==="shell.before")return;M.observability.recordObs($.projectDir,P7(Z),{provider:$.provider,kind:"policy.deny",sessionKey:$.sessionKey,attrs:{event:$.event,tool_name:$.toolName,permission:J.kind,rule:J.rule??"none"}})}function ez($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:{}}async function $Y($,Z={}){let J=Z.readStdin??sJ,Q=Z.now?Z.now():new Date,q={stdout:null,exitCode:0},W=(await J()).trim();if(!W)return e(process.cwd(),"adapter.unrecognized",{reason:"empty-stdin"}),{event:null,decision:{kind:"abstain"},rendered:q};let z;try{z=JSON.parse(W)}catch{return e(process.cwd(),"adapter.unrecognized",{reason:"invalid-json"}),{event:null,decision:{kind:"abstain"},rendered:q}}let Y=_J(z,OJ);if(!Y.provider)return e(process.cwd(),"adapter.unrecognized",{reason:"no-provider-match"}),{event:null,decision:{kind:"abstain"},rendered:q};if(Y.ambiguous)e(process.cwd(),"adapter.ambiguous",{matched:Y.matchedNames});let V=Y.provider,G=V.toEvent(ez(z));if(!G)return e(process.cwd(),"adapter.unrecognized",{reason:"unrecognized-event",provider:V.name}),{event:null,decision:{kind:"abstain"},rendered:q};let H=V.capabilities();try{let B=M.policy.loadPolicy(G.projectDir);if(G.model)M.subagentPolicy.upsertParentModelState(G.projectDir,G.sessionKey,{model:G.model},j7(B.subagents.blockedPatterns,V));M.presence.heartbeat(G.projectDir,{provider:G.provider,session:A8(G),...sz(G)?{file:G.filePath}:{},now:Q});let A=await $(G,{policy:B,capabilities:H,provider:V,now:Q}),D=FJ(A,G,H,{contextBudgetChars:az});tz(G,B,D);let O$=V.render(D,G);return{event:G,decision:D,rendered:O$}}catch(B){e(G.projectDir,"adapter.error",{provider:G.provider,event:G.event,message:oz(B)});let K={kind:"abstain"};return{event:G,decision:K,rendered:V.render(K,G)}}}async function L7($){let Z=await $Y($);if(Z.rendered.stdout!==null){let J=Z.rendered.stdout;process.stdout.write(J.endsWith(`
|
|
153
|
+
…(truncated — over context budget)`.slice(0,Z),Q=Math.max(0,Z-J.length);return`${$.slice(0,Q)}${J}`}function kz($,Z){if($.event==="tool.before")return Z.contextAtToolBefore;if($.event==="tool.after")return Z.contextAtToolAfter;if($.event==="stop")return Z.contextAtStop;return!0}function MJ($,Z){if($.kind!=="context"||Z===void 0)return $;let J=Z7($.text,Z);if(J===$.text)return $;return{...$,text:J}}function FJ($,Z,J,Q={}){if(!J.enforcesHooks&&Rz($))return MJ({kind:"context",text:`${"ADVISORY — this provider cannot enforce: "}${Ez($)}`},Q.contextBudgetChars);if($.kind==="ask"){if(!J.askSupportedOn.includes(Z.event))return{kind:"deny",reason:`${"Escalation unavailable on this provider — "}${$.reason}`,userNote:$.userNote,rule:$.rule};if(Z.permissionMode!==void 0&&Tz.has(Z.permissionMode))return{kind:"deny",reason:`${"No operator is answering prompts in this permission mode — "}${$.reason}`,userNote:$.userNote,rule:$.rule};return $}if($.kind==="rewriteInput"&&!J.toolInputRewrite)return{kind:"ask",reason:`Input rewrite unavailable on this provider — proposed input: ${JSON.stringify($.input)}. ${$.reason}`,rule:Dz.rewriteUnavailable};if($.kind==="context"){if(!kz(Z,J))return{kind:"abstain"};if($.env&&!J.sessionEnv){let{env:q,...X}=$;return MJ(X,Q.contextBudgetChars)}return MJ($,Q.contextBudgetChars)}return $}function J7(){return{enforcesHooks:!0,askSupportedOn:["tool.before","shell.before","mcp.before","read.before"],sessionEnv:!1,nativeLoopCounter:!1,dedicatedShellEvent:!1,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!0,contextAtToolAfter:!0,contextAtStop:!0,sessionStartContextReliable:!0,toolOutputAtAfter:!0,usageInPayload:!1,effortSignal:!0,thoughtEvent:!1}}var xz=/^[A-Z][a-zA-Z0-9]*$/;function Q7($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!xz.test(J))return!1;return typeof Z.cwd==="string"||typeof Z.transcript_path==="string"}var Sz={SessionStart:"session.start",SessionEnd:"session.end",UserPromptSubmit:"prompt.submit",PostToolUseFailure:"tool.failure",SubagentStart:"subagent.start",SubagentStop:"subagent.stop",Stop:"stop",PreCompact:"compact.before",MessageDisplay:"response.after"},q7=/^mcp__/;function F($){return typeof $==="string"?$:void 0}function fz($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function X7($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function bz($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function yz($){let Z=F($.session_id)??"default";return`claude-${I(Z)}`}function wz($){let Z=process.env.CLAUDE_PROJECT_DIR;if(Z)return Z;let J=F($.cwd);if(J)return J;return process.cwd()}function vz($){let J=X7($.effort)?.level;return C8(J)?J:void 0}function mz($){if($==="Bash")return"shell.before";if($&&q7.test($))return"mcp.before";if($==="Read")return"read.before";return"tool.before"}function gz($){if($==="Bash")return"shell.after";if($&&q7.test($))return"mcp.after";if($==="Edit"||$==="Write")return"edit.after";return"tool.after"}function W7($){let Z=F($.hook_event_name);if(!Z)return null;let J=F($.tool_name),Q=X7($.tool_input),q;if(Z==="PreToolUse")q=mz(J);else if(Z==="PostToolUse")q=gz(J);else q=Sz[Z];if(!q)return null;let X={provider:"claude",event:q,sessionKey:yz($),projectDir:wz($),raw:$},W=F($.permission_mode);if(W)X.permissionMode=W;let z=q==="subagent.start"||q==="subagent.stop",Y=z?void 0:F($.model);if(Y)X.model=Y;let V=vz($);if(V)X.effort=V;let G=fz($.context_usage_percent);if(G!==void 0)X.contextUsagePercent=G;let H=F($.transcript_path);if(H)X.transcriptPath=H;if(!z){let B=F($.agent_type);if(B)X.subagentType=B}switch(q){case"prompt.submit":{let B=F($.prompt);if(B!==void 0)X.text=B;break}case"response.after":{let B=F($.text);if(B!==void 0)X.text=B;break}case"shell.before":case"shell.after":{let B=Q?F(Q.command):void 0;if(B!==void 0)X.command=B;break}case"mcp.before":case"mcp.after":{if(J)X.toolName=J;if(Q)X.toolInput=Q;break}case"read.before":{let B=Q?F(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"edit.after":{if(J)X.toolName=J;let B=Q?F(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"tool.before":case"tool.after":case"tool.failure":{if(J)X.toolName=J;let B=$.tool_response;if(B!==void 0&&B!==null)X.toolOutput=typeof B==="string"?B:JSON.stringify(B);if(Q)X.toolInput=Q;let K=Q?F(Q.file_path):void 0;if(K!==void 0)X.filePath=K;let A=Q?F(Q.subagent_type):void 0;if(A)X.spawnSubagentType=A;let D=Q?F(Q.model):void 0;if(D)X.spawnModel=D;break}case"subagent.start":case"subagent.stop":{let B=F($.agent_type)??F($.subagent_type)??(Q?F(Q.subagent_type):void 0);if(B)X.spawnSubagentType=B;let K=(Q?F(Q.model):void 0)??F($.model);if(K)X.spawnModel=K;break}case"stop":{let B=bz($.status);if(B)X.status=B;break}default:break}return X}var uz={"session.start":"SessionStart","session.end":"SessionEnd","prompt.submit":"UserPromptSubmit","tool.before":"PreToolUse","tool.after":"PostToolUse","tool.failure":"PostToolUseFailure","shell.before":"PreToolUse","shell.after":"PostToolUse","mcp.before":"PreToolUse","mcp.after":"PostToolUse","read.before":"PreToolUse","edit.after":"PostToolUse","subagent.start":"SubagentStart","subagent.stop":"SubagentStop",stop:"Stop","compact.before":"PreCompact","response.after":"MessageDisplay","thought.after":"MessageDisplay"};function CJ($,Z,J){let Q={hookEventName:Z,permissionDecision:$};if(J!==void 0)Q.permissionDecisionReason=J;return JSON.stringify({hookSpecificOutput:Q})}function z7($,Z){let J=uz[Z.event];switch($.kind){case"abstain":return{stdout:null,exitCode:0};case"allow":return{stdout:CJ("allow",J,void 0),exitCode:0};case"deny":return{stdout:CJ("deny",J,$.reason),exitCode:0};case"ask":return{stdout:CJ("ask",J,$.reason),exitCode:0};case"context":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,additionalContext:$.text}}),exitCode:0};case"continue":return{stdout:JSON.stringify({decision:"block",reason:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,updatedInput:$.input}}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function Y7(){return{blockedPatterns:[],minEffort:null,untrustedTools:["WebFetch","WebSearch"]}}var V7={name:"claude",detect:Q7,capabilities:J7,policyDefaults:Y7,toEvent:W7,render:z7,wiring:HJ};function G7(){return{enforcesHooks:!0,askSupportedOn:["shell.before","mcp.before"],sessionEnv:!0,nativeLoopCounter:!0,dedicatedShellEvent:!0,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!1,contextAtToolAfter:!0,contextAtStop:!1,sessionStartContextReliable:!1,toolOutputAtAfter:!0,usageInPayload:!0,effortSignal:!1,thoughtEvent:!0}}var hz=/^[a-z][a-zA-Z0-9]*$/;function B7($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!hz.test(J))return!1;return Array.isArray(Z.workspace_roots)}var pz={sessionStart:"session.start",sessionEnd:"session.end",beforeSubmitPrompt:"prompt.submit",preToolUse:"tool.before",postToolUse:"tool.after",postToolUseFailure:"tool.failure",beforeShellExecution:"shell.before",afterShellExecution:"shell.after",beforeMCPExecution:"mcp.before",afterMCPExecution:"mcp.after",beforeReadFile:"read.before",afterFileEdit:"edit.after",subagentStart:"subagent.start",subagentStop:"subagent.stop",stop:"stop",preCompact:"compact.before",afterAgentResponse:"response.after",afterAgentThought:"thought.after"};function C($){return typeof $==="string"?$:void 0}function U7($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function H7($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function cz($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function dz($){let Z=C($.conversation_id)||C($.session_id)||"default";return`cursor-${I(Z)}`}function lz($){let Z=process.env.CURSOR_PROJECT_DIR;if(Z)return Z;let J=$.workspace_roots;if(Array.isArray(J)){let Q=C(J[0]);if(Q)return Q}return process.cwd()}function K7($){let Z=C($.hook_event_name),J=Z?pz[Z]:void 0;if(!J)return null;let Q={provider:"cursor",event:J,sessionKey:dz($),projectDir:lz($),raw:$},q=C($.model);if(q)Q.model=q;let X=U7($.context_usage_percent);if(X!==void 0)Q.contextUsagePercent=X;switch(J){case"prompt.submit":{let W=C($.prompt);if(W!==void 0)Q.text=W;break}case"response.after":{let W=C($.text);if(W!==void 0)Q.text=W;break}case"thought.after":{let W=C($.thought)??C($.text);if(W!==void 0)Q.text=W;break}case"tool.before":case"tool.after":case"tool.failure":{let W=C($.tool_name);if(W)Q.toolName=W;let z=H7($.tool_input);if(z)Q.toolInput=z;let Y=C($.subagent_type);if(Y)Q.subagentType=Y;let V=z?C(z.model):void 0;if(V)Q.spawnModel=V;let G=z?C(z.subagent_type):void 0;if(G)Q.spawnSubagentType=G;break}case"shell.before":case"shell.after":{let W=C($.command);if(W!==void 0)Q.command=W;let z=C($.output);if(z!==void 0)Q.toolOutput=z;break}case"mcp.before":case"mcp.after":{let W=C($.result_json);if(W!==void 0)Q.toolOutput=W;let z=C($.tool_name);if(z)Q.toolName=z;let Y=H7($.tool_input);if(Y)Q.toolInput=Y;let V=C($.command);if(V!==void 0)Q.command=V;break}case"read.before":case"edit.after":{let W=C($.file_path);if(W!==void 0)Q.filePath=W;break}case"subagent.start":case"subagent.stop":{let W=C($.subagent_type);if(W)Q.spawnSubagentType=W;let z=C($.subagent_model);if(z)Q.spawnModel=z;break}case"stop":{let W=cz($.status);if(W)Q.status=W;let z=U7($.loop_count);if(z!==void 0)Q.loopCount=z;break}default:break}return Q}function M7($,Z){let J={permission:$};if(Z.userNote!==void 0)J.user_message=Z.userNote;return J.agent_message=Z.reason,JSON.stringify(J)}function F7($,Z){switch($.kind){case"abstain":return{stdout:"{}",exitCode:0};case"allow":return{stdout:JSON.stringify({permission:"allow"}),exitCode:0};case"deny":return{stdout:M7("deny",$),exitCode:0};case"ask":return{stdout:M7("ask",$),exitCode:0};case"context":{let J={};if($.env!==void 0)J.env=$.env;return J.additional_context=$.text,{stdout:JSON.stringify(J),exitCode:0}}case"continue":return{stdout:JSON.stringify({followup_message:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({updated_input:$.input}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function C7(){return{blockedPatterns:["-fast(?:$|[^a-z0-9])","/fast(?:$|[^a-z0-9])","composer-2\\.5-fast"],minEffort:null,untrustedTools:["Fetch","WebSearch"]}}import{join as iz}from"node:path";var nz=[{hookEvent:"sessionStart",handler:"session-start",timeoutSeconds:10},{hookEvent:"sessionEnd",handler:"session-end",timeoutSeconds:10},{hookEvent:"beforeSubmitPrompt",handler:"prompt-submit",timeoutSeconds:5},{hookEvent:"afterAgentThought",handler:"tool-after",timeoutSeconds:5},{hookEvent:"preCompact",handler:"compact-before",timeoutSeconds:5},{hookEvent:"subagentStart",handler:"subagent-start",timeoutSeconds:5,failClosed:!0},{hookEvent:"subagentStop",handler:"subagent-stop",timeoutSeconds:5},{hookEvent:"preToolUse",handler:"tool-before",timeoutSeconds:5,failClosed:!0},{hookEvent:"postToolUse",handler:"tool-after",timeoutSeconds:5},{hookEvent:"postToolUseFailure",handler:"tool-failure",timeoutSeconds:5},{hookEvent:"beforeShellExecution",handler:"tool-before",timeoutSeconds:10,failClosed:!0},{hookEvent:"afterShellExecution",handler:"tool-after",timeoutSeconds:10},{hookEvent:"beforeMCPExecution",handler:"tool-before",timeoutSeconds:10},{hookEvent:"afterMCPExecution",handler:"tool-after",timeoutSeconds:5},{hookEvent:"beforeReadFile",handler:"tool-before",timeoutSeconds:5},{hookEvent:"afterFileEdit",handler:"tool-after",timeoutSeconds:30,matcher:"Write"},{hookEvent:"stop",handler:"stop",timeoutSeconds:120,loopLimit:5},{hookEvent:"afterAgentResponse",handler:"response-after",timeoutSeconds:5,matcher:"AgentResponse"}];function O7($){let J=[$.launcherPath],Q=nz.map((q)=>({hookEvent:q.hookEvent,handler:q.handler,command:"node",args:[...J,q.handler],timeoutSeconds:q.timeoutSeconds,...q.failClosed!==void 0?{failClosed:q.failClosed}:{},...q.matcher!==void 0?{matcher:q.matcher}:{},...q.loopLimit!==void 0?{loopLimit:q.loopLimit}:{}}));return{target:iz(TJ(),"hooks.json"),strategy:"replace",entries:Q}}var _7={name:"cursor",detect:B7,capabilities:G7,policyDefaults:C7,toEvent:K7,render:F7,wiring:O7};var OJ=[_7,V7];function _J($,Z){let J=Z.filter((Q)=>Q.detect($));if(J.length===0)return{provider:null,ambiguous:!1,matchedNames:[]};return{provider:J[0]??null,ambiguous:J.length>1,matchedNames:J.map((Q)=>Q.name)}}var I7=M.observability.DEFAULT_OBS,WM={...I7,debugEnabled:!0};function P7($,Z=I7){return{...Z,globalSpool:$.obs.globalSpool,includePayloads:$.obs.includePayloads,maxAttrChars:$.obs.maxAttrChars,sessionCostAlertUsd:$.obs.sessionCostAlertUsd,retentionDays:$.obs.retentionDays}}function A8($){let Z=`${$.provider}-`;return $.sessionKey.startsWith(Z)?$.sessionKey.slice(Z.length):$.sessionKey}function j7($,Z){return[...M.policy.forProvider($,Z.name)??[],...Z.policyDefaults().blockedPatterns]}function N7($,Z){if($==="cursor")return KJ(Z);if($==="claude")return UJ(Z);return null}var az=6000;function sz($){if($.filePath===void 0)return!1;if($.event==="edit.after")return!0;return Z8($.toolName)}function oz($){return $ instanceof Error?$.message:String($)}function e($,Z,J){try{N(rz(U($),"obs.jsonl"),{schema:"harness.observability.v1",provider:"unknown",kind:Z,level:"signal",ts:new Date().toISOString(),attrs:J})}catch{}}function tz($,Z,J){if(J.kind!=="deny"&&J.kind!=="ask")return;if($.event==="shell.before")return;M.observability.recordObs($.projectDir,P7(Z),{provider:$.provider,kind:"policy.deny",sessionKey:$.sessionKey,attrs:{event:$.event,tool_name:$.toolName,permission:J.kind,rule:J.rule??"none"}})}function ez($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:{}}async function $Y($,Z={}){let J=Z.readStdin??sJ,Q=Z.now?Z.now():new Date,q={stdout:null,exitCode:0},W=(await J()).trim();if(!W)return e(process.cwd(),"adapter.unrecognized",{reason:"empty-stdin"}),{event:null,decision:{kind:"abstain"},rendered:q};let z;try{z=JSON.parse(W)}catch{return e(process.cwd(),"adapter.unrecognized",{reason:"invalid-json"}),{event:null,decision:{kind:"abstain"},rendered:q}}let Y=_J(z,OJ);if(!Y.provider)return e(process.cwd(),"adapter.unrecognized",{reason:"no-provider-match"}),{event:null,decision:{kind:"abstain"},rendered:q};if(Y.ambiguous)e(process.cwd(),"adapter.ambiguous",{matched:Y.matchedNames});let V=Y.provider,G=V.toEvent(ez(z));if(!G)return e(process.cwd(),"adapter.unrecognized",{reason:"unrecognized-event",provider:V.name}),{event:null,decision:{kind:"abstain"},rendered:q};let H=V.capabilities();try{let B=M.policy.loadPolicy(G.projectDir);if(G.model)M.subagentPolicy.upsertParentModelState(G.projectDir,G.sessionKey,{model:G.model},j7(B.subagents.blockedPatterns,V));M.presence.heartbeat(G.projectDir,{provider:G.provider,session:A8(G),...sz(G)?{file:G.filePath}:{},now:Q});let A=await $(G,{policy:B,capabilities:H,provider:V,now:Q}),D=FJ(A,G,H,{contextBudgetChars:az});tz(G,B,D);let O$=V.render(D,G);return{event:G,decision:D,rendered:O$}}catch(B){e(G.projectDir,"adapter.error",{provider:G.provider,event:G.event,message:oz(B)});let K={kind:"abstain"};return{event:G,decision:K,rendered:V.render(K,G)}}}async function L7($){let Z=await $Y($);if(Z.rendered.stdout!==null){let J=Z.rendered.stdout;process.stdout.write(J.endsWith(`
|
|
154
154
|
`)?J:`${J}
|
|
155
155
|
`)}process.exit(Z.rendered.exitCode)}var ZY=async($,Z)=>{let{policy:J}=Z,Q=$.projectDir,q=A8($);if(await M.handoff.patchHandoff(Q,$.provider,{slice:{next_action:"Session ended. Run `tlc harness handoff` before resuming."}}),M.presence.release(Q,$.provider,q),M.turn.resetLoop(Q,$.sessionKey),J.intelligence.lessons.enabled&&J.intelligence.lessons.gardenOnSessionEnd){let z=M.lesson.durableViewVerdict(J.intelligence.lessons.syncRulesFile,Z.capabilities.sessionStartContextReliable);if((await M.lesson.gardenAndPersistLessons(Q,J.intelligence.lessons,{writeDurableView:z.writes})).markdownPath)N7($.provider,Q)}let X=M.observability.getRollup(Q,$.sessionKey),W=M.policy.policySourceFingerprint(Q);return M.attest.appendAttestation(Q,{ts:new Date().toISOString(),provider:$.provider,session:q,policyFingerprint:M.attest.fingerprintOf(W),policyDiverged:M.policy.checkPolicyBaseline(Q,$.sessionKey).kind!=="allow",railsActive:M.policy.activeRails(J),decisionsByRule:X?.railsByRule??{},gates:X?.gates??{pass:0,fail:0}}),{kind:"abstain"}};if(NJ.main==NJ.module)await L7(ZY);export{ZY as sessionEndHandler};
|
package/dist/session-start.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import{createRequire as xQ}from"node:module";var LJ=xQ(import.meta.url);import{createHash as EJ}from"node:crypto";import{join as vQ}from"node:path";import{appendFileSync as SQ,existsSync as fQ,mkdirSync as bQ,readFileSync as yQ}from"node:fs";import{dirname as wQ}from"node:path";function A($,Z){bQ(wQ($),{recursive:!0}),SQ($,`${JSON.stringify(Z)}
|
|
2
2
|
`)}function R($,Z){if(!fQ($))return[];let J=[];for(let Q of yQ($,"utf8").split(`
|
|
3
|
-
`)){let q=Q.trim();if(q.length===0)continue;try{J.push(JSON.parse(q))}catch{}}return J.slice(-Z)}import{homedir as x8}from"node:os";import{delimiter as CY,join as j,resolve as
|
|
3
|
+
`)){let q=Q.trim();if(q.length===0)continue;try{J.push(JSON.parse(q))}catch{}}return J.slice(-Z)}import{homedir as x8}from"node:os";import{delimiter as CY,dirname as OY,join as j,resolve as _Y}from"node:path";function AJ($){return j($,".tlc","harness")}function DJ(){return j(x8(),".tlc","harness")}function j$($=process.env){return $.TLC_HOME??DJ()}function N$($=process.env){return $.TLC_HOME_FROM_ENV==="0"?DJ():j$($)}function E($=process.env){return j(N$($),"config.json")}function g(){return j(N$(),"state")}function S8(){return j(g(),"obs-spool.jsonl")}function _($){return j(AJ($),"config.json")}function H($){return j(AJ($),"state")}function k($){return j(H($),"flags")}function L$($){return j(H($),"presence")}function f8($){return j(H($),"loops")}function b8($){return j(H($),"boot")}function c($){return j(H($),"policy-baseline")}function TJ(){let $=process.env.CLAUDE_CONFIG_DIR?.trim();return $&&$.length>0?$:j(x8(),".claude")}function RJ(){let $=process.env.CURSOR_CONFIG_DIR?.trim();return $&&$.length>0?$:j(x8(),".cursor")}var kJ="genesis";function A$($){return vQ(H($),"attestation.jsonl")}function xJ($){let Z=[$.schema,$.ts,$.provider,$.session,$.policyFingerprint,String($.policyDiverged),$.railsActive.join(","),Object.entries($.decisionsByRule).sort((J,Q)=>J[0].localeCompare(Q[0])).map(([J,Q])=>`${J}=${Q}`).join(","),`${$.gates.pass}/${$.gates.fail}`,$.prev].join("\x00");return EJ("sha256").update(Z).digest("hex")}function y8($){return R(A$($),Number.MAX_SAFE_INTEGER)}function SJ($,Z){let Q=y8($).at(-1)?.self??kJ,q={schema:"harness.attestation.v1",...Z,prev:Q},X={...q,self:xJ(q)};return A(A$($),X),X}function fJ($){let Z=kJ;for(let[J,Q]of $.entries()){if(Q.prev!==Z)return{ok:!1,brokenAt:J,reason:"previous-hash-mismatch"};let{self:q,...X}=Q;if(xJ(X)!==q)return{ok:!1,brokenAt:J,reason:"content-hash-mismatch"};Z=q}return{ok:!0,length:$.length}}function bJ($){let Z=[...$].sort((J,Q)=>J.path.localeCompare(Q.path)).map((J)=>`${J.path}:${J.hash}`).join("|");return EJ("sha256").update(Z).digest("hex").slice(0,32)}var d='Enable: ask the agent "setup harness" (harness-init skill) or edit .tlc/harness/config.json';function mQ($,Z){let J=$;for(let Q of Z.split(".").filter(Boolean)){if(!J||typeof J!=="object")return;J=J[Q]}return J}function w8($,Z){let J=mQ($,Z.configPath);return Z.defaultOn?J===!1:J!==!0}function v8($,Z){return Z.capabilities.filter((J)=>w8($,J))}function yJ($,Z,J){return v8($,Z).filter((Q)=>Q.sinceCatalogVersion>J)}function wJ($){let Z=["Available for this project (not enabled yet):",""];for(let J of $)Z.push(`• ${J.title}`),Z.push(` Benefit: ${J.benefit}`),Z.push(` Trade-off: ${J.tradeOff}`),Z.push("");return Z.push(d),Z.join(`
|
|
4
4
|
`).trimEnd()}function vJ($){return`${$.title} off — ${$.tradeOff} — ${d}`}function mJ($){return`${$.length} available and not enabled: ${$.map((Z)=>Z.id).join(", ")}. ${d}`}import{existsSync as tQ,readFileSync as eQ}from"node:fs";import{join as lJ}from"node:path";import{randomBytes as uQ}from"node:crypto";import{closeSync as hQ,existsSync as pQ,mkdirSync as uJ,openSync as cQ,readFileSync as dQ,renameSync as lQ,rmSync as hJ,writeFileSync as iQ}from"node:fs";import{dirname as pJ}from"node:path";function Q$($){let{attempt:Z,baseMs:J,capMs:Q,random:q=Math.random}=$,X=J*2**Z,W=Math.min(Q,X);return q()*W}function gQ($){return new Promise((Z)=>setTimeout(Z,$))}async function gJ($,Z){let{attempts:J,shouldRetry:Q=()=>!0,sleep:q=gQ,random:X=Math.random,baseMs:W=50,capMs:z=2000}=Z;for(let Y=0;Y<J;Y++)try{return await $()}catch(V){if(Y===J-1||!Q(V))throw V;await q(Q$({attempt:Y,baseMs:W,capMs:z,random:X}))}throw Error("retry: unreachable")}var nQ=new Set(["EPERM","EBUSY","EACCES"]);function cJ($){return typeof $==="object"&&$!==null&&"code"in $?$.code:void 0}function dJ($){let Z=cJ($);return Z!==void 0&&nQ.has(Z)}function rQ($){return`${$}.${process.pid}.${uQ(4).toString("hex")}.tmp`}async function q$($,Z,J={}){let{attempts:Q=5,baseMs:q=20,capMs:X=500,random:W,sleep:z,rename:Y=lQ,writeFile:V=(B,K)=>iQ(B,K,"utf8"),removeFile:G=(B)=>{try{hJ(B,{force:!0})}catch{}}}=J;uJ(pJ($),{recursive:!0});let U=rQ($);V(U,`${JSON.stringify(Z,null,2)}
|
|
5
5
|
`);try{await gJ(()=>{Y(U,$)},{attempts:Q,baseMs:q,capMs:X,random:W,sleep:z,shouldRetry:dJ})}catch(B){throw G(U),B}}function aQ($){if(!pQ($))return null;try{return JSON.parse(dQ($,"utf8"))}catch{return null}}function sQ($){return cJ($)==="EEXIST"||dJ($)}async function oQ($,Z,J={}){let{openLock:Q=(z)=>hQ(cQ(z,"wx")),lockSleep:q=(z)=>new Promise((Y)=>setTimeout(Y,z)),lockAttempts:X=200}=J;uJ(pJ($),{recursive:!0});let W=!1;for(let z=0;z<X;z++)try{Q($),W=!0;break}catch(Y){if(!sQ(Y))throw Y;await q(Q$({attempt:z,baseMs:10,capMs:200}))}if(!W)throw Error(`fs-atomic: could not acquire lock at ${$}`);try{return await Z()}finally{try{hJ($,{force:!0})}catch{}}}async function D$($,Z,J){let{lockPath:Q,afterWrite:q,openLock:X,lockSleep:W,lockAttempts:z,...Y}=J;return oQ(Q,async()=>{let V=aQ($),G=Z(V);return await q$($,G,Y),q?.($),G},{openLock:X,lockSleep:W,lockAttempts:z})}function m8($){if(!tQ($))return null;try{return JSON.parse(eQ($,"utf8"))}catch{return null}}function $7($=j$()){return lJ($,"capabilities","catalog.json")}function iJ($=j$()){let Z=m8($7($));if(!Z||typeof Z.catalogVersion!=="number"||!Array.isArray(Z.capabilities))return null;return Z}function nJ($){return m8(_($))}function rJ($){return lJ(H($),"runtime-seen.json")}function aJ($){let Z=m8(rJ($));if(!Z||typeof Z.catalogVersion!=="number"||Z.catalogVersion<0)return{catalogVersion:0};return Z}async function sJ($,Z){await q$(rJ($),{catalogVersion:Z,updatedAt:new Date().toISOString()})}import{readFileSync as V7}from"node:fs";import{join as G7}from"node:path";import{existsSync as q7,readFileSync as X7}from"node:fs";import{join as tJ}from"node:path";import{spawn as Z7}from"node:child_process";var J7=124;async function oJ(){let $=[];for await(let Z of process.stdin)$.push(Buffer.isBuffer(Z)?Z:Buffer.from(Z));return Buffer.concat($).toString("utf8")}async function X$($){let[Z,...J]=$.command;if(Z===void 0)return{exitCode:0,stdout:"",stderr:""};return await new Promise((Q,q)=>{let X=Z7(Z,J,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],env:$.env??process.env}),W="",z="",Y=!1,V=$.timeoutMs===void 0?void 0:setTimeout(()=>{Y=!0,X.kill("SIGKILL")},$.timeoutMs);if(X.stdout.on("data",(G)=>{W+=G.toString()}),X.stderr.on("data",(G)=>{z+=G.toString()}),X.on("error",(G)=>{if(V)clearTimeout(V);q(G)}),X.on("close",(G)=>{if(V)clearTimeout(V);if(Y){Q({exitCode:J7,stdout:W,stderr:`${z}
|
|
6
6
|
(process timed out)`});return}Q({exitCode:G??1,stdout:W,stderr:z})}),$.input!==void 0)X.stdin.write($.input);X.stdin.end()})}var Q7=/[A-Za-z0-9._-]/;function P($){if($.length===0)return"_empty_";let Z="";for(let J of $){if(Q7.test(J)){Z+=J;continue}for(let Q of Buffer.from(J,"utf8"))Z+=`%${Q.toString(16).toUpperCase().padStart(2,"0")}`}return Z}function D($){return $.replace(/\\/g,"/")}async function eJ($,Z){let J=await X$({command:["git",...Z],cwd:$});if(J.exitCode!==0)return[];return J.stdout.split(`
|
|
@@ -12,7 +12,7 @@ import{createRequire as xQ}from"node:module";var LJ=xQ(import.meta.url);import{c
|
|
|
12
12
|
`).entries())Q.push({file:z,line:V+1,text:G})}return{index:G2(Q,J),filesRead:X,truncated:W}}import{homedir as l8,tmpdir as y7}from"node:os";import{basename as w7,isAbsolute as K2,relative as W$,resolve as S,sep as v7}from"node:path";function m7($,Z=l8()){if($==="~")return Z;return $.startsWith(`~${v7}`)||$.startsWith("~/")?S(Z,$.slice(2)):$}function l($,Z,J=l8()){let Q=m7(Z,J);return K2(Q)?S(Q):S($,Q)}function f($,Z){let J=W$(S($),S(Z));return J===""||!J.startsWith("..")&&!K2(J)}function M2($,Z=y7()){return f(Z,$)}function g7($){let Z=S($);return Z===S(E())||f(g(),Z)}function R$($,Z){if(g7(Z))return!0;let J=D(W$($,Z)||Z),Q=D(W$($,_($))),q=D(W$($,k($))),X=D(W$($,H($)));return J===Q||J.startsWith(`${q}/`)||J.startsWith(`${X}/`)}var u7=[".ssh",".aws",".kube",".gnupg",".docker",".config/gh",".config/gcloud"],h7=new Set([".git-credentials",".netrc",".npmrc",".pgpass","credentials","id_dsa","id_ecdsa","id_ed25519","id_rsa"]),p7=[".pem",".p12",".pfx"],c7=[".example",".sample",".template",".dist"];function d7($){if($!==".env"&&!$.startsWith(".env."))return!1;return!c7.some((Z)=>$.endsWith(Z))}function i8($,Z=l8()){let J=w7($);if(d7(J)||h7.has(J))return!0;if(p7.some((Q)=>J.endsWith(Q)))return!0;return u7.some((Q)=>f(S(Z,Q),$))}import{relative as a7,resolve as s7}from"node:path";var l7=new Set([";","|","&",`
|
|
13
13
|
`]),i7=new Set([" ","\t",'"',"'","$","`","\\",";","|","&","(",")"]);function n7($){return $.includes("$")||$.includes("`")}function F2($){let Z=/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/,J=[],Q=$,q="";for(;;){let X=Z.exec(Q);if(!X){q+=Q;break}let W=Q.indexOf(`
|
|
14
14
|
`,X.index+X[0].length),z=q+Q.slice(0,X.index);if(q+=Q.slice(0,X.index),W===-1)break;let Y=new RegExp(`^\\s*${X[2]}\\s*$`,"m"),V=Q.slice(W+1),G=Y.exec(V);if(!G){J.push({body:V,prefix:z});break}J.push({body:V.slice(0,G.index),prefix:z}),Q=V.slice(G.index+G[0].length)}return{stripped:q,heredocs:J}}function C2($){return F2($).heredocs}function b($){let Z=[],J=[],Q="",q=!1,X=!1,W=null,z=!1,Y=0;function V(){if(Q!==""||q)J.push({text:Q,unresolved:n7(Q),quotedStart:X});Q="",q=!1,X=!1}function G(){if(V(),J.length>0)Z.push({words:J,opaque:z});J=[]}let{stripped:U}=F2($);for(let B=0;B<U.length;B+=1){let K=U[B];if(W!==null){if(K===W)W=null;else Q+=K;continue}if(K==="\\"){let L=U[B+1];if(L!==void 0&&i7.has(L))Q+=L,B+=1;else Q+=K;continue}if(K==='"'||K==="'"){if(W=K,Q===""&&!q)X=!0;q=!0;continue}if(K==="$"&&(U[B+1]==="("||U[B+1]==="{")){Y+=1,Q+=K;continue}if(Y>0&&(K===")"||K==="}")){Y-=1,Q+=K;continue}if(Y===0&&l7.has(K)){G();continue}if(Y===0&&(K===" "||K==="\t")){V();continue}Q+=K}if(W!==null||Y>0)z=!0;return G(),z?Z.map((B)=>({...B,opaque:!0})):Z}var r7=new Set(["command","doas","env","nice","nohup","sudo","time","xargs"]);function u($){let Z=0;while(Z<$.length){let J=$[Z];if(!J)return null;if(r7.has(J.text)||J.text.startsWith("-")||J.text.includes("=")){Z+=1;continue}return{verb:J.text.split("/").pop()??J.text,args:$.slice(Z+1)}}return null}function O2($){return $.find((Z)=>!Z.text.startsWith("-")&&Z.text!=="")??null}var E$={kind:"allow"},o7=new Set(["cat","cmp","diff","echo","file","grep","head","jq","less","ls","md5sum","more","od","printf","rg","sha256sum","stat","strings","tail","test","[","wc","xxd"]),t7=new Set(["show","diff","log","status","ls-files","cat-file","blame"]),e7=new Set(["ash","awk","bash","bun","dash","deno","ed","ex","fish","gawk","ksh","lua","node","perl","php","python","python2","python3","ruby","sed","sh","tclsh","zsh"]),$3=new Set(["tlc","tlc.cmd"]),Z3=new Set(["pause","resume","grind","mode","init","gate","policy"]);function y($,Z,J){return{kind:"deny",detail:$,note:Z,...J?{remedy:J}:{}}}var _2="Reading is allowed: run `tlc harness handoff` for handoff state, `tlc harness status` for posture and gates, `tlc harness doctor` for what the settings amount to, or use a proven reader (cat, head, jq, grep, ls, stat, test) on the path.";function n8($){let Z=D(a7($,H($)));return Z.slice(0,Z.lastIndexOf("/"))}function J3($,Z){return D(Z.words.map((Q)=>Q.text).join(" ")).includes(n8($))}function Q3($,Z){if(Z===s7($))return!1;if(R$($,Z))return!0;return[_($),H($)].some((J)=>f(J,Z)||f(Z,J))}function I2($,Z){if(Z.text==="")return!1;if(Z.unresolved)return D(Z.text).includes(n8($));return Q3($,l($,Z.text))}function q3($){let Z=[];for(let J=0;J<$.length;J+=1){let Q=$[J];if(!Q||Q.quotedStart)continue;let q=/^(.*?)>{1,2}\|?(.*)$/s.exec(Q.text);if(!q)continue;let X=q[2]??"";if(X!==""){Z.push({text:X,unresolved:Q.unresolved,quotedStart:!1});continue}let W=$[J+1];if(W)Z.push(W),J+=1}return Z}function X3($){let Z=$.filter((J)=>!J.text.startsWith("-")&&J.text!=="");if(Z[0]?.text.toLowerCase()!=="harness")return null;return(Z[1]?.text??"status").toLowerCase()}function W3($,Z){for(let q of q3(Z.words))if(I2($,q))return y("a redirect in this command writes into the harness policy surface.","redirect into the policy surface");let J=u(Z.words);if(J&&$3.has(J.verb)){let q=X3(J.args);if(q!==null&&Z3.has(q))return y(`\`tlc harness ${q}\` changes harness policy, and policy is the operator's to change.`,`tlc harness ${q}`)}let Q=Z.words.filter((q)=>I2($,q));if(Q.length===0&&!J3($,Z))return E$;if(Z.opaque)return y("this command names the harness policy surface inside a segment this gate cannot split, so what it does to it cannot be established.","unprovable policy-surface access");if(!J)return y("the harness policy surface is named in a command with no resolvable verb.","policy-surface access with no verb");if(o7.has(J.verb))return E$;if(J.verb==="git"){let q=O2(J.args)?.text.toLowerCase()??"";return t7.has(q)?E$:y(`\`git ${q}\` can write the working tree, so it cannot be proven to only read the harness policy surface.`,`git ${q} on the policy surface`,_2)}if(Q.some((q)=>q.unresolved))return y("this command builds a harness policy path at runtime, so the file it would touch cannot be established.","unresolvable policy-surface path");return y(`\`${J.verb}\` is not a proven reader, so this command cannot be shown to only read the harness policy surface.`,`${J.verb} on the policy surface`,_2)}function z3($,Z){let J=n8($);for(let Q of Z){if(!D(Q.body).includes(J))continue;let q=u(b(Q.prefix).at(-1)?.words??[]);if(q!==null&&e7.has(q.verb))return y(`a heredoc fed to \`${q.verb}\` names the harness policy surface, so the body is a program rather than a document.`,"heredoc program naming the policy surface")}return E$}function P2($,Z,J){for(let Q of J){let q=W3($,Q);if(q.kind==="deny")return q}return z3($,C2(Z))}var j2=new Set(["dd","rm","rmdir","shred","truncate"]),N2=new Set(["halt","poweroff","reboot","shutdown"]),Y3=new Set(["base64","cat","head","less","more","od","strings","tail","xxd"]),V3=new Set(["Read","Edit","MultiEdit","NotebookEdit"]),L2=new Set([".","eval","source"]),r8=new Set(["ash","bash","dash","fish","ksh","sh","zsh"]),a8=new Set(["aria2c","curl","fetch","http","httpie","https","wget"]),G3=["169.254.169.254","169.254.170.2","100.100.100.200","metadata.google.internal"],B3=new Set([...a8,"nc","ncat","socat","telnet","lwp-request"]);function U3($){return[...a8].some((Z)=>new RegExp(`\\b${Z}\\b`).test($))}function H3($,Z){let J=$.includes("|"),Q=!1;for(let q of Z){let X=u(q.words);if(!X)continue;let{verb:W,args:z}=X;if(J&&Q&&r8.has(W))return!0;if(r8.has(W)||L2.has(W)){for(let Y of z)if((Y.text.includes("<(")||Y.unresolved)&&U3(Y.text))return!0}Q=a8.has(W)}return!1}function K3($,Z){return L2.has($)||r8.has($)&&Z.some((J)=>J.text==="-c")}function M3($,Z){return[`FLOOR: ${Z}`,"This is a floor rule — it has no config switch, because a limit an agent can turn off is not a limit.","Restate what you need and let the operator decide; do not work around this.",`rule=${$}`].join(`
|
|
15
|
-
`)}function T($,Z,J){return{kind:"deny",reason:M3($,Z),userNote:`Floor rule ${$}: ${J}`,rule:$}}function A2($){return $==="mkfs"||$.startsWith("mkfs.")}function F3($){let Z=$.split("/").pop()??$;return j2.has(Z)||N2.has(Z)||A2(Z)}function C3($){return $.words.some((Z)=>Z.text.split(/\s+/).some(F3))}function D2($){return $.filter((Z)=>!Z.text.startsWith("-")&&Z.text!=="")}function O3($){let Z=$.command;if(!Z)return{kind:"allow"};let J=b(Z);if(H3(Z,J))return T("unprovable-execution","This runs a program fetched over the network, which does not exist for this gate to check. Download it to a file, read it, then run that file.","fetched program piped to a shell");for(let q of J){let X=u(q.words);if(!X)continue;let{verb:W,args:z}=X;if(K3(W,z)&&C3(q))return T("unprovable-destruction","A destructive verb appears inside a command this gate cannot expand, so its target cannot be established. Run it directly with a literal path instead.","hidden destructive verb");if(N2.has(W))return T("machine-control",`\`${W}\` controls the machine, not the project.`,W);if(W==="git"&&z.some((G)=>G.text==="push")){if(z.some((U)=>U.text==="--force"||U.text==="-f"))return T("history-rewrite","`git push --force` discards remote commits that are not in your history. Use --force-with-lease, which refuses when the remote moved.","force push")}if(!(j2.has(W)||A2(W)))continue;let V=D2(z);if(q.opaque||V.some((G)=>G.unresolved)||V.length===0)return T("unprovable-destruction",`\`${W}\` was called with a target this gate cannot resolve, so its safety cannot be established. Re-run it with a literal path inside the project.`,`unresolvable ${W}`);for(let G of V){let U=l($.projectDir,G.text);if(!f($.projectDir,U)&&!M2(U))return T("outside-project-destruction",`\`${W}\` targets ${U}, which is outside the project and outside scratch space.`,`${W} outside project`)}}let Q=P2($.projectDir,Z,J);if(Q.kind==="deny"){let q=Q.remedy??"Set a gate command with `tlc harness gate test-command` or `gate lint-command`, and run policy changes from your own terminal rather than from inside this session.";return T("policy-surface-write",`${Q.detail} ${q}`,Q.note)}return _3(J,$.projectDir)}function _3($,Z){for(let J of $){let Q=u(J.words);if(!Q)continue;if(B3.has(Q.verb)){let q=Q.args.map((W)=>W.text).join(" "),X=G3.find((W)=>q.includes(W));if(X!==void 0)return T("secret-access",`${X} is the instance metadata service, and \`${Q.verb}\` would copy the credentials it returns into the transcript.`,`read of ${X}`)}if(!Y3.has(Q.verb))continue;for(let q of D2(Q.args)){if(q.unresolved)continue;let X=l(Z,q.text);if(i8(X))return T("secret-access",`\`${Q.verb}\` would read ${X} into the transcript. Credentials do not belong in an agent's context.`,`read of ${X}`)}}return{kind:"allow"}}function I3($){let Z=$.filePath;if(!Z)return{kind:"allow"};if(!($.isReadEvent===!0||$.toolName!==void 0&&V3.has($.toolName)))return{kind:"allow"};let Q=l($.projectDir,Z);if(!i8(Q))return{kind:"allow"};return T("secret-access",`${Q} holds credentials, and reading it would copy them into the transcript.`,`read of ${Q}`)}function T2($){let Z=I3($);if(Z.kind!=="allow")return Z;return O3($)}import{createHash as w3}from"node:crypto";import{existsSync as v3,mkdirSync as m3,readFileSync as g3,unlinkSync as
|
|
15
|
+
`)}function T($,Z,J){return{kind:"deny",reason:M3($,Z),userNote:`Floor rule ${$}: ${J}`,rule:$}}function A2($){return $==="mkfs"||$.startsWith("mkfs.")}function F3($){let Z=$.split("/").pop()??$;return j2.has(Z)||N2.has(Z)||A2(Z)}function C3($){return $.words.some((Z)=>Z.text.split(/\s+/).some(F3))}function D2($){return $.filter((Z)=>!Z.text.startsWith("-")&&Z.text!=="")}function O3($){let Z=$.command;if(!Z)return{kind:"allow"};let J=b(Z);if(H3(Z,J))return T("unprovable-execution","This runs a program fetched over the network, which does not exist for this gate to check. Download it to a file, read it, then run that file.","fetched program piped to a shell");for(let q of J){let X=u(q.words);if(!X)continue;let{verb:W,args:z}=X;if(K3(W,z)&&C3(q))return T("unprovable-destruction","A destructive verb appears inside a command this gate cannot expand, so its target cannot be established. Run it directly with a literal path instead.","hidden destructive verb");if(N2.has(W))return T("machine-control",`\`${W}\` controls the machine, not the project.`,W);if(W==="git"&&z.some((G)=>G.text==="push")){if(z.some((U)=>U.text==="--force"||U.text==="-f"))return T("history-rewrite","`git push --force` discards remote commits that are not in your history. Use --force-with-lease, which refuses when the remote moved.","force push")}if(!(j2.has(W)||A2(W)))continue;let V=D2(z);if(q.opaque||V.some((G)=>G.unresolved)||V.length===0)return T("unprovable-destruction",`\`${W}\` was called with a target this gate cannot resolve, so its safety cannot be established. Re-run it with a literal path inside the project.`,`unresolvable ${W}`);for(let G of V){let U=l($.projectDir,G.text);if(!f($.projectDir,U)&&!M2(U))return T("outside-project-destruction",`\`${W}\` targets ${U}, which is outside the project and outside scratch space.`,`${W} outside project`)}}let Q=P2($.projectDir,Z,J);if(Q.kind==="deny"){let q=Q.remedy??"Set a gate command with `tlc harness gate test-command` or `gate lint-command`, and run policy changes from your own terminal rather than from inside this session.";return T("policy-surface-write",`${Q.detail} ${q}`,Q.note)}return _3(J,$.projectDir)}function _3($,Z){for(let J of $){let Q=u(J.words);if(!Q)continue;if(B3.has(Q.verb)){let q=Q.args.map((W)=>W.text).join(" "),X=G3.find((W)=>q.includes(W));if(X!==void 0)return T("secret-access",`${X} is the instance metadata service, and \`${Q.verb}\` would copy the credentials it returns into the transcript.`,`read of ${X}`)}if(!Y3.has(Q.verb))continue;for(let q of D2(Q.args)){if(q.unresolved)continue;let X=l(Z,q.text);if(i8(X))return T("secret-access",`\`${Q.verb}\` would read ${X} into the transcript. Credentials do not belong in an agent's context.`,`read of ${X}`)}}return{kind:"allow"}}function I3($){let Z=$.filePath;if(!Z)return{kind:"allow"};if(!($.isReadEvent===!0||$.toolName!==void 0&&V3.has($.toolName)))return{kind:"allow"};let Q=l($.projectDir,Z);if(!i8(Q))return{kind:"allow"};return T("secret-access",`${Q} holds credentials, and reading it would copy them into the transcript.`,`read of ${Q}`)}function T2($){let Z=I3($);if(Z.kind!=="allow")return Z;return O3($)}import{createHash as w3}from"node:crypto";import{existsSync as v3,mkdirSync as m3,readFileSync as g3,unlinkSync as x0,writeFileSync as u3}from"node:fs";import{dirname as h3,join as p3}from"node:path";var P3=["CLAUDE_PROJECT_DIR","CURSOR_PROJECT_DIR","TLC_PROJECT_DIR"];function R2($=process.env){return P3.filter((Z)=>($[Z]??"").trim()!=="")}var j3=/\d+\s+(?:tests?|specs?|examples?)?\s*(?:fail(?:ed|ures?)?|pass(?:ed|ing)?|pending|skipped|todo|errors?)\b|(?:failures?|errors?)\s*=\s*\d+/gi,N3=/^(?:tests?|specs?|failed|failures?|summary|results?)\b[:\s]*/i,L3=/^[\s\d:;,|—–\-()=.✗×✕✖*]*$/,A3=[/^\(fail\)\s*\S/i,/^not ok\s+\d+/i,/^---\s*FAIL:\s*\S/i,/^(?:FAIL|FAILED)\s+(?!\()\S/i],D3=/^[✗×✕✖]\s+\S/,T3=/(?:expect\(|toEqual|toBe\b|toMatch|toThrow|AssertionError|assert(?:ion)?\b|deep(?:Strict)?Equal|strictEqual|Expected\b|received\b|actual\b)/i;function R3($){if(!/\d/.test($)||!/(?:fail|error)/i.test($))return!1;let Z=$.replace(N3," ").replace(j3," ");return L3.test(Z)}function E3($){if(A3.some((Z)=>Z.test($)))return"test";if(R3($))return"count";if(D3.test($))return"test";return T3.test($)?"assertion":"other"}function k3($){let Z=[],J=[],Q=null,q=null;for(let X of $)switch(E3(X)){case"count":Q??=X;break;case"test":{let W={summary:X,details:J.splice(0)};Z.push(W),q=W;break}case"assertion":if(q)q.details.push(X);else J.push(X);break;default:{let W={summary:X,details:J.splice(0)};Z.push(W),q=W}}if(J.length>0)Z.push({summary:J[0],details:J.slice(1)});return{failures:Z,firstCount:Q}}function x3($){return $.replace(/\s+/g," ").trim().toLowerCase()}function S3($){let Z=new Map;for(let J of $){let Q=x3(J.summary),q=Z.get(Q);if(q){q.details.push(...J.details);continue}Z.set(Q,{summary:J.summary,details:[...J.details]})}return[...Z.values()]}function E2($){let Z=[...new Set($.details)].join(`
|
|
16
16
|
`).slice(0,500);return Z?{summary:$.summary.slice(0,200),detail:Z}:{summary:$.summary.slice(0,200)}}function k2($,Z,J){let{failures:Q,firstCount:q}=k3($),X=S3(Q);if(X.length===0){let Y={summary:`gate exited with code ${Z}`};return q?[{...Y,detail:q.slice(0,500)}]:[Y]}if(X.length<=J)return X.map(E2);let W=X.slice(0,Math.max(1,J-1)).map(E2),z=X.length-W.length;return[...W,{summary:`…and ${z} more failures in the gate output`}]}var f3="ts|tsx|mts|cts|js|jsx|mjs|cjs|py|go|rb|rs|java|kt|swift|php|sh|sql",b3=new RegExp(`(?:file://)?((?:[A-Za-z]:)?[\\w./~@+-]*[\\w-]\\.(?:${f3}))(?=[:)\\s,'"\`]|$)`,"g");function y3($){let Z=String.fromCharCode(27);return $.replaceAll(new RegExp(`${Z}\\[[0-9;]*[A-Za-z]`,"g"),"")}function x2($,Z){let J=new Set,Q=[],q=`${Z.replace(/\/+$/,"")}/`;for(let X of y3($).matchAll(b3)){let W=X[1];if(!W)continue;let z=W.startsWith(q)?W.slice(q.length):W;if(J.has(z))continue;J.add(z),Q.push(z)}return Q}var S2="harness.gate.v1";var c3=8000,k$=8,d3=/(?:\bFAIL(?:ED)?\b|\bERROR\b|Error:|error\[|AssertionError|\bpanic:|✗|×|✕|✖|failures?\s*[:=]\s*[1-9])/i;function f2($){return p3(H($),"last-gate.json")}function l3($,Z=c3){let J=$.trim();if(!J)return"";return J.length<=Z?J:J.slice(-Z)}function b2($){if(!v3($))return null;try{return JSON.parse(g3($,"utf8"))}catch{return null}}function i3($){let Z=b2($);if(!Z||typeof Z!=="object")return null;let J=Z.findings;if(!Array.isArray(J))return null;let Q=[];for(let q of J){if(!q||typeof q!=="object")continue;let X=q.summary;if(typeof X!=="string"||!X.trim())continue;let{detail:W,id:z}=q;if(Q.push({summary:X.trim().slice(0,200),detail:typeof W==="string"?W.slice(0,500):void 0,id:typeof z==="string"?z:void 0}),Q.length>=k$)break}return Q.length>0?Q:null}function n3($,Z,J=k$){let Q=$.split(`
|
|
17
17
|
`).map((W)=>W.trim()).filter((W)=>W.length>0&&!W.startsWith(">")),q=Q.filter((W)=>d3.test(W)),X=q.length>0?q:Q.slice(-J);return k2(X,Z,J)}function y2($){let Z=l3($.output),J=$.reportPath?i3($.reportPath):null,Q=!Z||Z==="(no output captured)",q=J??($.exitCode===0?[]:Q?[{summary:`gate exited with code ${$.exitCode}`}]:n3(Z,$.exitCode)),X={schema:S2,gate:$.gate,exitCode:$.exitCode,passed:$.exitCode===0,command:$.command,files:[...$.files],durationMs:$.durationMs,ts:new Date().toISOString(),outputTail:Z,findings:q,scopedEnv:R2(),...$.inputsHash?{inputsHash:$.inputsHash}:{}},W=f2($.root);return m3(h3(W),{recursive:!0}),u3(W,`${JSON.stringify(X,null,2)}
|
|
18
18
|
`,"utf8"),X}function w2($){return b2(f2($))}function v2($){let Z=JSON.stringify({gate:$.gate,exitCode:$.exitCode,files:[...$.files].sort(),findings:$.findings.map((J)=>J.summary).sort()});return w3("sha256").update(Z).digest("hex").slice(0,16)}import{basename as r3}from"node:path";var a3=new Set(["just","make","task","mise","rake"]),s3=new Set(["npm","yarn","pnpm"]),o3=new Set(["npx","bunx","dlx","exec"]),t3=/[*?[\]]/,e3=[/does not contain recipe/i,/no rule to make target/i,/unknown recipe/i,/missing script:/i,/task ".*" does not exist/i,/don't know how to build task/i];function $q($){let Z=$;while(Z.length>1&&o3.has(s8(Z[0])))Z=Z.slice(1);if(Z.length>2&&s8(Z[0])==="bun"&&Z[1]==="run")return["npm",...Z.slice(1)];return Z}function s8($){return r3($).replace(/\.(exe|cmd|bat)$/i,"").toLowerCase()}function x$($){return s8($q($)[0]??"")}function o8($){return a3.has(x$($))}function Zq($){return s3.has(x$($))}function t8($,Z){if($.length===0)return{appends:!1,reason:"the command is empty"};if(Z==="always")return{appends:!0};if(Z==="never")return{appends:!1,reason:"appendFiles is set to never"};if(o8($))return{appends:!1,reason:`\`${x$($)}\` takes a target name, so a file path would read as a second target`};if(Zq($))return{appends:!1,reason:`\`${x$($)}\` invokes a script, and whether a path reaches the runner is not something the harness can know`};let J=$.find((Q)=>t3.test(Q));if(J!==void 0)return{appends:!1,reason:`the command already scopes itself with \`${J}\`, so appending files would not narrow the run`};return{appends:!0}}function m2($,Z){return t8($,Z).appends}function S$($){if($.exitCode===127)return!0;return e3.some((Z)=>Z.test($.output))}import{createHash as g2}from"node:crypto";import{readFileSync as Jq,statSync as Qq}from"node:fs";import{isAbsolute as qq,resolve as Xq}from"node:path";var Wq=400,zq=12000000;function Yq($,Z){if(qq(Z))return null;let J=Xq($,Z);try{let Q=Qq(J);if(!Q.isFile())return null;let q=Jq(J);return{entry:`${Z}\x00${Q.size}\x00${g2("sha256").update(q).digest("hex")}`,bytes:Q.size}}catch{return null}}function u2($,Z,J){let Q=[...new Set(Z)].sort();if(Q.length>Wq)return{hash:"",complete:!1};let q=[],X=0,W=!0;for(let Y of Q){let V=Yq($,Y);if(V===null){W=!1;continue}if(X+=V.bytes,X>zq)return{hash:"",complete:!1};q.push(V.entry)}let z=JSON.stringify({command:[...J],entries:q});return{hash:g2("sha256").update(z).digest("hex").slice(0,32),complete:W}}function e8($,Z){return $.complete&&$.hash.length>0&&Z===$.hash}function h2($,Z,J){if($===null||$.gate!==Z)return null;return e8(J,$.inputsHash)?$:null}import{closeSync as Vq,existsSync as c2,mkdirSync as Gq,openSync as Bq,readFileSync as Uq,statSync as Hq,unlinkSync as d2,writeFileSync as Kq}from"node:fs";import{hostname as l2}from"node:os";import{dirname as Mq,join as Fq}from"node:path";var $Z=120000,i2=1800000,Cq=5000;class f$ extends Error{constructor($="gate lock timeout"){super($);this.name="GateLockTimeoutError"}}function n2($){return Fq(H($),"grind.lock")}function Oq($){return new Promise((Z)=>setTimeout(Z,$))}function z$($){if(!c2($))return null;try{return JSON.parse(Uq($,"utf8"))}catch{return null}}function r2($,Z){if(!c2($))return null;try{return Z-Hq($).mtimeMs}catch{return null}}function a2($,Z){let J=r2($,Z.now);return J!==null&&J>=Z.staleMs}function ZZ($){if(typeof $!=="object"||$===null)return!1;let Z=$;return typeof Z.provider==="string"&&typeof Z.session==="string"&&typeof Z.pid==="number"}function _q($,Z){let J=r2($,Z.now);if(J===null||J<Z.graceMs)return!1;return!ZZ(z$($))}var Iq=($)=>{process.kill($,0)};function s2($,Z=l2(),J=Iq){if(!ZZ($))return!1;let{host:Q,pid:q}=$;if(typeof Q!=="string"||Q!==Z)return!1;if(!Number.isInteger(q)||q<=0)return!1;try{return J(q),!1}catch(X){return X.code==="ESRCH"}}function Pq($,Z){return a2($,{now:Z.now,staleMs:Z.staleMs})||_q($,{now:Z.now,graceMs:Z.graceMs})||s2(z$($))}function JZ($,Z={}){let J=n2($),Q=Z.now??Date.now(),q=Z.staleMs??i2;if(a2(J,{now:Q,staleMs:q}))return null;let X=z$(J);if(!ZZ(X))return null;if(s2(X))return null;return`${X.provider} session ${X.session} (pid ${X.pid})`}function o2($,Z){Gq(Mq($),{recursive:!0});try{let J=Bq($,"wx");try{Kq(J,JSON.stringify(Z))}finally{Vq(J)}return!0}catch{return!1}}function jq($,Z,J){if(!Pq($,Z))return{stolen:!1,previousHolder:null};let Q=z$($);try{d2($)}catch{return{stolen:!1,previousHolder:null}}return{stolen:o2($,J),previousHolder:Q}}function Nq($,Z){let J=z$($);if(J&&J.pid===Z)try{d2($)}catch{}}async function t2($,Z,J,Q,q={}){let X=q.waitMs??$Z,W=q.staleMs??i2,z=q.unreadableGraceMs??Cq,Y=q.now??Date.now,V=q.sleep??Oq,G=q.random??Math.random,U=q.baseMs??20,B=q.capMs??500,K=n2($),L=Y()+X,F=process.pid,m=0;while(!0){let Z$=Y(),J$={provider:Z,session:J,pid:F,acquired_at:new Date(Z$).toISOString(),host:l2()};if(o2(K,J$))return p2(K,F,Q);let k8=jq(K,{staleMs:W,graceMs:z,now:Z$},J$);if(k8.stolen){if(k8.previousHolder)q.onSteal?.(k8.previousHolder);return p2(K,F,Q)}if(Y()>=L){let NJ=JZ($);throw new f$(`gate lock busy at ${K} after ${X}ms${NJ?` — held by ${NJ}`:""}`)}await V(Q$({attempt:m,baseMs:U,capMs:B,random:G})),m+=1}}async function p2($,Z,J){try{return await J()}finally{Nq($,Z)}}function e2($){let Z=$.max??k$,J=$.artifact.findings.slice(0,Z);if(J.length===0)return[{id:`${$.artifact.gate}-0`,gate:$.artifact.gate,category:$.category,summary:`${$.artifact.gate} failed (exit ${$.artifact.exitCode})`}];return J.map((Q,q)=>({id:Q.id??`${$.artifact.gate}-${q}`,gate:$.artifact.gate,category:$.category,summary:Q.summary,detail:Q.detail}))}import{createHash as Lq}from"node:crypto";import{existsSync as Aq,mkdirSync as Dq,readFileSync as $9,writeFileSync as Tq}from"node:fs";import{basename as Rq,dirname as Z9,join as Eq}from"node:path";var kq="harness.seal.v1";function QZ($){return Eq(Z9($),".seal",`${Rq($)}.json`)}function J9($){try{return Lq("sha256").update($9($)).digest("hex")}catch{return null}}function b$($){let Z=J9($);if(Z===null)return;try{Dq(Z9(QZ($)),{recursive:!0}),Tq(QZ($),JSON.stringify({schema:kq,hash:Z}))}catch{}}function y$($){if(!Aq($))return"absent";let Z=null;try{let J=JSON.parse($9(QZ($),"utf8"));Z=typeof J.hash==="string"?J.hash:null}catch{Z=null}if(Z===null)return"unsealed";return J9($)===Z?"sealed":"diverged"}function w$($){return $!=="diverged"}function v$($,Z){return[`${Z} at ${$} changed without a harness write behind it, so it was not injected into this turn.`,"That file is read aloud to the model, so text placed in it reaches every later turn. Read it, and if the","contents are yours, the next harness write reseals it."].join(`
|
|
@@ -106,7 +106,7 @@ ${" ".repeat(4)}${Z.dim(N.bar)} ${z.detail}`:B});return[Z.heading(`LAST ${$.leng
|
|
|
106
106
|
`)}var LZ=["comments"];function e$($){return LZ.includes($)}function Q1($){return $.filter((Z)=>!e$(Z))}function q1($,Z,J){return $.enabled&&!J&&e$(Z)&&$.rails.includes(Z)}function X1($){return{rail:$.rail,violations:$.violations,prose_injected:$.proseInjected,reading:$.violations===0?$.proseInjected?"held-with-prose":"held-without-prose":$.proseInjected?"violated-with-prose":"violated-without-prose"}}var rX=/(?:^|\n)\s*HARNESS_PLAN:\s*(.+?)\s*(?=\n|$)/,aX=/(?:^|\n)\s*HARNESS_PLAN_DEVIATION:\s*(.+?)\s*(?=\n|$)/g,sX=/\s+(?:—|--|-)\s+/;function oX($){return $.split(/[,\s]+/).map((Z)=>Z.trim()).filter((Z)=>Z.length>0)}function W1($){let J=rX.exec($)?.[1]?.trim();if(!J)return null;let Q=oX(J);if(Q.length===0)return null;return{paths:Q,snippet:`HARNESS_PLAN: ${J}`.slice(0,280)}}function z1($){let Z=[];for(let J of $.matchAll(aX)){let Q=J[1]?.trim();if(!Q)continue;let[q,...X]=Q.split(sX),W=q?.trim(),z=X.join(" ").trim();if(!W||z.length===0)continue;Z.push({path:W,reason:z})}return Z}import{existsSync as U1,readFileSync as Z4}from"node:fs";import{join as J4}from"node:path";var tX={enabled:!1,maxInjectSession:5,maxInjectRetry:8,maxCharsSession:900,maxCharsRetry:1400,promoteHitCount:2,decayLambda:0.02,projectBoost:1.5,syncRulesFile:"auto",gardenOnSessionEnd:!0},K$={version:1,mode:"solo",codePaths:["src","apps","libs","packages"],grind:{enabled:!1,maxLoops:5,lintCommand:null,testCommand:null,appendFiles:"auto"},shipGate:{enabled:!1,runtimePathPrefixes:["src","apps","libs","packages","deploy","scripts"],runtimePathExcludes:[".tlc/","**/node_modules/","**/.git/"],evidenceDir:null,evidenceMaxAgeHours:48,emptyDiffAntiShip:!1,claimWindowMinutes:10},subagents:{enforceAllowlist:!1,requireModel:!1,allowedModels:[],blockedPatterns:["-fast(?:$|[^a-z0-9])","/fast(?:$|[^a-z0-9])"],minEffort:null,blockParentFast:!1,blockMode:"deny",readOnlyTypes:["explore"]},docs:{command:null,severity:"warn"},observe:{enabled:!1,rails:[]},comments:{enabled:!1,onViolation:"followup",mode:"declared"},supplyChain:{enabled:!1},duplication:{enabled:!1,minRun:x},obs:{globalSpool:!1,includePayloads:w.includePayloads,maxAttrChars:w.maxAttrChars,sessionCostAlertUsd:w.sessionCostAlertUsd,retentionDays:w.retentionDays},untrustedContent:{mode:"frame",enabled:!1,extraTools:[],extraCommandPatterns:[]},planGate:{enabled:!1,windowMinutes:120},rules:{enabled:!1},shell:{catastrophicAsk:!0,stallDetection:!1,stallRepeatThreshold:3},intelligence:{gapFeedback:!0,failureClassification:!0,progressiveHandoff:!0,progressiveContext:!0,autopilot:!0,idleTurnGate:!1,budgetContinue:!1,budgetContinueAfterLoops:3,lessons:{...tX}},mcpPrime:[],bootstrapExtra:[]};import{existsSync as V1,readFileSync as eX}from"node:fs";import{join as G1}from"node:path";var AZ=["paired","solo","focus"],Y1="solo";function $8($){return typeof $==="string"&&AZ.includes($)}function $4($){let Z=G1(H($),"harness-mode");if(!V1(Z))return null;try{return eX(Z,"utf8").trim().toLowerCase()}catch{return null}}function B1($,Z){let J=$4($);if($8(J))return{mode:J,origin:"file"};for(let Q of["focus","paired"])if(V1(G1(k($),Q)))return{mode:Q,origin:"flag"};if($8(Z))return{mode:Z,origin:"config"};if(Z===void 0||Z===null)return{mode:Y1,origin:"config"};return{mode:Y1,origin:"fallback",invalid:String(Z)}}function DZ($){if(!U1($))return null;try{return JSON.parse(Z4($,"utf8"))}catch{return null}}function TZ($,Z){return{...$,...Z,grind:{...$.grind,...Z.grind},shipGate:{...$.shipGate,...Z.shipGate},subagents:{...$.subagents,...Z.subagents},docs:{...$.docs,...Z.docs},observe:{...$.observe,...Z.observe},comments:{...$.comments,...Z.comments},supplyChain:{...$.supplyChain,...Z.supplyChain},duplication:{...$.duplication,...Z.duplication},obs:{...$.obs,...Z.obs},untrustedContent:{...$.untrustedContent,...Z.untrustedContent},planGate:{...$.planGate,...Z.planGate},shell:{...$.shell,...Z.shell},intelligence:{...$.intelligence,...Z.intelligence,lessons:{...$.intelligence.lessons,...Z.intelligence?.lessons}},codePaths:Z.codePaths??$.codePaths,mcpPrime:Z.mcpPrime??$.mcpPrime,bootstrapExtra:Z.bootstrapExtra??$.bootstrapExtra}}function Q4($,Z){return U1(J4(k($),Z))}function RZ($){return{fromUser:DZ(E())??{},fromProject:DZ(_($))??{}}}function H1($,Z){return B1($,Z.fromProject.mode??Z.fromUser.mode)}function K1($){return H1($,RZ($))}function M1($){let Z=RZ($),J=Z.fromProject.intelligence?.lessons?.syncRulesFile,Q=J??Z.fromUser.intelligence?.lessons?.syncRulesFile,q=U$(Q);if(q.coercedFrom===void 0)return q;let X=J===void 0?E():_($);return{...q,coercedIn:X}}function F1($){let Z=RZ($),J=TZ(TZ(K$,Z.fromUser),Z.fromProject);if(J.mode=H1($,Z).mode,Q4($,"grind-on"))J.grind.enabled=!0;return J.intelligence.lessons.syncRulesFile=y9(J.intelligence.lessons.syncRulesFile),J}function C1(){let $=DZ(E())??{};return TZ(K$,$)}function Z8($,Z){let J=$.replace(/\\/g,"/");return Z.some((Q)=>J===Q||J.startsWith(`${Q}/`))}import{existsSync as O1,readdirSync as q4,readFileSync as X4,statSync as _1}from"node:fs";import{join as EZ}from"node:path";function I1($){return EZ(H($),"ship-ledger.jsonl")}function P1($,Z){let J={...Z,ts:Z.ts??new Date().toISOString()};A(I1($),J)}function j1($){return R(I1($),Number.MAX_SAFE_INTEGER)}function J8($,Z,J){if(!O1($))return!1;let Q=Z*60*60*1000,q=Date.now();for(let X of q4($)){let W=EZ($,X,"90-verdict.txt");if(!O1(W))continue;try{let z=_1(W).mtimeMs;if(J!==void 0&&z<J)continue;if(q-z>Q)continue;if(/\bPASS\b/i.test(X4(W,"utf8")))return!0}catch{}}return!1}function N1($,Z){let J;for(let Q of Z)try{let q=_1(EZ($,Q)).mtimeMs;if(J===void 0||q>J)J=q}catch{}return J}var W4=/(?:^|\n)\s*HARNESS_SHIP_CLAIM:\s*(.+?)\s*(?=\n|$)/;function L1($){let Z=$.trim();if(!Z)return null;let Q=Z.match(W4)?.[1]?.trim();if(!Q)return null;return{kind:"structured",snippet:`HARNESS_SHIP_CLAIM: ${Q}`.slice(0,280)}}function Q8($,Z){let J=$.replace(/\\/g,"/");for(let Q of Z){let q=Q.replace(/\\/g,"/").replace(/^\.\//,"");if(!q)continue;if(q.endsWith("/**")){let X=q.slice(0,-3);if(J===X||J.startsWith(`${X}/`))return!0;continue}if(q.endsWith("/")){if(J.startsWith(q)||J.startsWith(`${q.slice(0,-1)}/`))return!0;continue}if(q.includes("*")){if(new RegExp(`^${q.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*")}$`).test(J))return!0;continue}if(J===q||J.startsWith(`${q}/`))return!0}return!1}function kZ($,Z,J){return $.some((Q)=>{if(Q8(Q,J))return!1;return Z8(Q,Z)||/^Dockerfile(\.|$)/.test(Q)})}function A1($,Z,J=Date.now()){if(!$)return!1;let Q=Date.parse($);if(Number.isNaN(Q))return!1;return J-Q<Z*60*1000}function D1($){if($.enabled&&$.recentShipClaim&&$.changedFilesCount===0)return{kind:"continue",text:["BLOCKED: HARNESS_SHIP_CLAIM with no file diff.","TRIED: inspected git working tree / changed files.","NEED: either implement the remaining work or remove the ship claim — do not claim ship on an empty diff."].join(`
|
|
107
107
|
`)};return{kind:"abstain"}}function T1($){if(!$.enabled||!$.recentShipClaim||$.changedFiles.length===0)return{kind:"abstain"};if(!kZ($.changedFiles,$.runtimePathPrefixes,$.runtimePathExcludes))return{kind:"abstain"};if($.evidenceDir!==null&&J8($.evidenceDir,$.evidenceMaxAgeHours,$.evidenceNotBeforeMs))return{kind:"abstain"};return{kind:"continue",text:["BLOCKED: HARNESS_SHIP_CLAIM without recent production PASS evidence.",`TRIED: checked ${$.evidenceDir??"(no evidenceDir configured)"}/*/90-verdict.txt.`,"NEED: run the verification after the last code change, then cite the verdict path — evidence written before the change certifies the older tree."].join(`
|
|
108
108
|
`)}}function z4($,Z,J=Date.now()){if(!$)return!1;let Q=Date.parse($);if(Number.isNaN(Q))return!1;return J-Q<Z*60*1000}function Y4($){let Z=$.deviations.map((J)=>J.path);return $.changedFiles.filter((J)=>{if(Q8(J,[...$.planned]))return!1;return!Q8(J,Z)})}function R1($){let Z=xZ($);if(!Z.active||Z.unplanned.length===0)return{kind:"abstain"};let J=Z.unplanned.slice(0,10).join(", "),Q=Z.unplanned.length>10?` (+${Z.unplanned.length-10} more)`:"";return{kind:"continue",text:[`BLOCKED: ${Z.unplanned.length} changed file(s) are outside the declared plan: ${J}${Q}`,`TRIED: compared the working tree against HARNESS_PLAN (${$.planned.join(", ")}).`,"NEED: either revert what the plan did not call for, or justify each path with a reason —","HARNESS_PLAN_DEVIATION: <path> — <why this file had to change>"].join(`
|
|
109
|
-
`)}}function xZ($){if(!$.enabled||$.planned.length===0)return{active:!1,unplanned:[]};if(!z4($.declaredAt,$.windowMinutes,$.now??Date.now()))return{active:!1,unplanned:[]};return{active:!0,unplanned:Y4({changedFiles:$.changedFiles,planned:$.planned,deviations:$.deviations})}}var V4=new Set(["Edit","Write","Delete","MultiEdit","NotebookEdit"]);function q8($){return $!==void 0&&V4.has($)}function E1($){if(!q8($.toolName)||!$.filePath)return{kind:"allow"};if(!R$($.projectDir,$.filePath))return{kind:"allow"};return{kind:"deny",reason:["Harness policy and state are not agent-writable — a gate an agent can switch off is not a gate.","The harness CLI does not help you here either: the same floor rule refuses the mutating subcommands from inside a session.","Tell the operator which value you would change and why, and let them run it from their own terminal."].join(" "),userNote:`Blocked an agent write to ${$.filePath}.`,rule:"policy-surface-write"}}import{createHash as G4}from"node:crypto";import{existsSync as F$,mkdirSync as B4,readdirSync as SZ,readFileSync as k1,writeFileSync as fZ}from"node:fs";import{join as M$}from"node:path";var U4="absent",bZ="harness.policy-baseline.v1",H4="harness-mode",K4=["grind-on","skip-verify","focus","paired"];function M4($){if(!F$($))return U4;try{return G4("sha256").update(k1($)).digest("hex")}catch{return"unreadable"}}function v($){
|
|
109
|
+
`)}}function xZ($){if(!$.enabled||$.planned.length===0)return{active:!1,unplanned:[]};if(!z4($.declaredAt,$.windowMinutes,$.now??Date.now()))return{active:!1,unplanned:[]};return{active:!0,unplanned:Y4({changedFiles:$.changedFiles,planned:$.planned,deviations:$.deviations})}}var V4=new Set(["Edit","Write","Delete","MultiEdit","NotebookEdit"]);function q8($){return $!==void 0&&V4.has($)}function E1($){if(!q8($.toolName)||!$.filePath)return{kind:"allow"};if(!R$($.projectDir,$.filePath))return{kind:"allow"};return{kind:"deny",reason:["Harness policy and state are not agent-writable — a gate an agent can switch off is not a gate.","The harness CLI does not help you here either: the same floor rule refuses the mutating subcommands from inside a session.","Tell the operator which value you would change and why, and let them run it from their own terminal."].join(" "),userNote:`Blocked an agent write to ${$.filePath}.`,rule:"policy-surface-write"}}import{createHash as G4}from"node:crypto";import{existsSync as F$,mkdirSync as B4,readdirSync as SZ,readFileSync as k1,writeFileSync as fZ}from"node:fs";import{join as M$}from"node:path";var U4="absent",bZ="harness.policy-baseline.v1",H4="harness-mode",K4=["grind-on","skip-verify","focus","paired"];function M4($){if(!F$($))return U4;try{return G4("sha256").update(k1($)).digest("hex")}catch{return"unreadable"}}function v($){let Z=[_($),E(),M$(H($),H4),...K4.map((Q)=>M$(k($),Q))],J=new Set;return Z.filter((Q)=>!J.has(Q)&&J.add(Q)!==void 0).map((Q)=>({path:Q,hash:M4(Q)}))}function x1($,Z){return M$(c($),`${P(Z)}.json`)}function yZ($,Z){try{B4(c($),{recursive:!0}),fZ(x1($,Z),`${JSON.stringify({schema:bZ,sources:v($)},null,2)}
|
|
110
110
|
`,"utf8")}catch{}}function X8($,Z){let J=x1($,Z);if(!F$(J))return null;try{let Q=JSON.parse(k1(J,"utf8"));return Array.isArray(Q.sources)?Q.sources:null}catch{return null}}function wZ($,Z){let J=new Map($.map((Q)=>[Q.path,Q.hash]));return Z.filter((Q)=>{let q=J.get(Q.path);return q!==void 0&&q!==Q.hash}).map((Q)=>Q.path)}function S1($,Z){let J=X8($,Z);return J===null?[]:wZ(J,v($))}function f1($){let Z=c($);if(!F$(Z))return[];let J=new Set,Q=v($);for(let q of SZ(Z)){if(!q.endsWith(".json"))continue;let X=X8($,q.replace(/\.json$/,""));if(X)for(let W of wZ(X,Q))J.add(W)}return[...J].sort()}function b1($,Z){let J=v($),Q=new Map(J.map((W)=>[W.path,W.hash])),q=Z.filter((W)=>!Q.has(W));if(q.length>0)return{kind:"not-a-source",paths:q,sources:J.map((W)=>W.path)};let X=c($);if(!F$(X)||Z.length===0)return{kind:"nothing-to-accept"};for(let W of SZ(X)){if(!W.endsWith(".json"))continue;let z=W.replace(/\.json$/,""),Y=X8($,z);if(!Y)continue;let V=Y.map((G)=>Z.includes(G.path)?{path:G.path,hash:Q.get(G.path)}:G);try{fZ(M$(X,W),`${JSON.stringify({schema:bZ,sources:V},null,2)}
|
|
111
111
|
`,"utf8")}catch{}}return{kind:"accepted",paths:Z}}function y1($,Z){let J=X8($,Z);if(!J)return yZ($,Z),{kind:"allow"};let Q=wZ(J,v($));if(Q.length===0)return{kind:"allow"};return{kind:"deny",reason:[`HARNESS: ${Q.join(", ")} changed during this session, and no harness command changed it.`,"The gates are now running a policy the operator did not set, so what they check cannot be trusted.","Report this to the operator and name the paths above. Only they can clear it, from their own terminal — the harness commands that would are refused from inside a session, so there is nothing for you to run here."].join(`
|
|
112
112
|
`),userNote:[`Harness policy changed out of band during this session: ${Q.join(", ")}.`,`If that was you, accept it with: tlc harness policy accept ${Q.join(" ")}`].join(" "),rule:"policy-baseline-divergence"}}function w1($){let Z=c($);if(!F$(Z))return;let J=v($);for(let Q of SZ(Z)){if(!Q.endsWith(".json"))continue;try{fZ(M$(Z,Q),`${JSON.stringify({schema:bZ,sources:J},null,2)}
|
|
@@ -143,14 +143,14 @@ ${$.body.trim()}`}function V8($,Z,J){let Q=[];for(let q of $){let X=M5(q,Z,J);if
|
|
|
143
143
|
`:"",X=J.length>0?`${J}${q}
|
|
144
144
|
${KJ}
|
|
145
145
|
`:`${KJ}
|
|
146
|
-
`;return Oz(t6(Z),{recursive:!0}),Iz(Z,X,"utf8"),Z}import{dirname as
|
|
146
|
+
`;return Oz(t6(Z),{recursive:!0}),Iz(Z,X,"utf8"),Z}import{dirname as KK,join as Nz}from"node:path";var Lz=[{hookEvent:"SessionStart",handler:"session-start",timeoutSeconds:10},{hookEvent:"SessionEnd",handler:"session-end",timeoutSeconds:10},{hookEvent:"UserPromptSubmit",handler:"prompt-submit",timeoutSeconds:5},{hookEvent:"PreToolUse",handler:"tool-before",timeoutSeconds:10,failClosed:!0},{hookEvent:"PostToolUse",handler:"tool-after",timeoutSeconds:10},{hookEvent:"PostToolUseFailure",handler:"tool-failure",timeoutSeconds:5},{hookEvent:"SubagentStart",handler:"subagent-start",timeoutSeconds:5,failClosed:!0},{hookEvent:"SubagentStop",handler:"subagent-stop",timeoutSeconds:5},{hookEvent:"Stop",handler:"stop",timeoutSeconds:120,loopLimit:5},{hookEvent:"PreCompact",handler:"compact-before",timeoutSeconds:5},{hookEvent:"MessageDisplay",handler:"response-after",timeoutSeconds:5}];function Az(){return Nz(TJ(),"settings.json")}function FJ($){let Z=Lz.map((J)=>({hookEvent:J.hookEvent,handler:J.handler,command:"node",args:[$.launcherPath,J.handler],timeoutSeconds:J.timeoutSeconds,...J.failClosed!==void 0?{failClosed:J.failClosed}:{},...J.loopLimit!==void 0?{loopLimit:J.loopLimit}:{}}));return{target:Az(),strategy:"merge",entries:Z}}import{existsSync as Dz,mkdirSync as Tz,readFileSync as Rz,writeFileSync as Ez}from"node:fs";import{dirname as $Q,join as ZQ}from"node:path";function kz($){return ZQ($Q(_($)),"lessons.md")}function xz($){return ZQ($,".cursor","rules","harness-lessons.mdc")}function CJ($){let Z=kz($);if(!Dz(Z))return null;let J=Rz(Z,"utf8"),Q=xz($);Tz($Q(Q),{recursive:!0});let q=`---
|
|
147
147
|
description: Harness-learned lessons (auto-synced from gate failures)
|
|
148
148
|
alwaysApply: true
|
|
149
149
|
---
|
|
150
150
|
|
|
151
151
|
${J}`;return Ez(Q,q,"utf8"),Q}var Sz={rewriteUnavailable:"rewrite-unavailable"};var fz=new Set(["bypassPermissions","dontAsk"]);function bz($){return $.kind==="deny"||$.kind==="ask"||$.kind==="continue"||$.kind==="rewriteInput"}function yz($){switch($.kind){case"deny":case"ask":return $.reason;case"continue":return $.text;case"rewriteInput":return`${$.reason} (proposed input: ${JSON.stringify($.input)})`;default:return""}}function JQ($,Z){if($.length<=Z)return $;if(Z<=0)return"";let J=35<=Z?`
|
|
152
152
|
…(truncated — over context budget)`:`
|
|
153
|
-
…(truncated — over context budget)`.slice(0,Z),Q=Math.max(0,Z-J.length);return`${$.slice(0,Q)}${J}`}function wz($,Z){if($.event==="tool.before")return Z.contextAtToolBefore;if($.event==="tool.after")return Z.contextAtToolAfter;if($.event==="stop")return Z.contextAtStop;return!0}function OJ($,Z){if($.kind!=="context"||Z===void 0)return $;let J=JQ($.text,Z);if(J===$.text)return $;return{...$,text:J}}function _J($,Z,J,Q={}){if(!J.enforcesHooks&&bz($))return OJ({kind:"context",text:`${"ADVISORY — this provider cannot enforce: "}${yz($)}`},Q.contextBudgetChars);if($.kind==="ask"){if(!J.askSupportedOn.includes(Z.event))return{kind:"deny",reason:`${"Escalation unavailable on this provider — "}${$.reason}`,userNote:$.userNote,rule:$.rule};if(Z.permissionMode!==void 0&&fz.has(Z.permissionMode))return{kind:"deny",reason:`${"No operator is answering prompts in this permission mode — "}${$.reason}`,userNote:$.userNote,rule:$.rule};return $}if($.kind==="rewriteInput"&&!J.toolInputRewrite)return{kind:"ask",reason:`Input rewrite unavailable on this provider — proposed input: ${JSON.stringify($.input)}. ${$.reason}`,rule:Sz.rewriteUnavailable};if($.kind==="context"){if(!wz(Z,J))return{kind:"abstain"};if($.env&&!J.sessionEnv){let{env:q,...X}=$;return OJ(X,Q.contextBudgetChars)}return OJ($,Q.contextBudgetChars)}return $}function QQ(){return{enforcesHooks:!0,askSupportedOn:["tool.before","shell.before","mcp.before","read.before"],sessionEnv:!1,nativeLoopCounter:!1,dedicatedShellEvent:!1,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!0,contextAtToolAfter:!0,contextAtStop:!0,sessionStartContextReliable:!0,toolOutputAtAfter:!0,usageInPayload:!1,effortSignal:!0,thoughtEvent:!1}}var vz=/^[A-Z][a-zA-Z0-9]*$/;function qQ($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!vz.test(J))return!1;return typeof Z.cwd==="string"||typeof Z.transcript_path==="string"}var mz={SessionStart:"session.start",SessionEnd:"session.end",UserPromptSubmit:"prompt.submit",PostToolUseFailure:"tool.failure",SubagentStart:"subagent.start",SubagentStop:"subagent.stop",Stop:"stop",PreCompact:"compact.before",MessageDisplay:"response.after"},XQ=/^mcp__/;function C($){return typeof $==="string"?$:void 0}function gz($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function WQ($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function uz($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function hz($){let Z=C($.session_id)??"default";return`claude-${P(Z)}`}function pz($){let Z=process.env.CLAUDE_PROJECT_DIR;if(Z)return Z;let J=C($.cwd);if(J)return J;return process.cwd()}function cz($){let J=WQ($.effort)?.level;return I8(J)?J:void 0}function dz($){if($==="Bash")return"shell.before";if($&&XQ.test($))return"mcp.before";if($==="Read")return"read.before";return"tool.before"}function lz($){if($==="Bash")return"shell.after";if($&&XQ.test($))return"mcp.after";if($==="Edit"||$==="Write")return"edit.after";return"tool.after"}function zQ($){let Z=C($.hook_event_name);if(!Z)return null;let J=C($.tool_name),Q=WQ($.tool_input),q;if(Z==="PreToolUse")q=dz(J);else if(Z==="PostToolUse")q=lz(J);else q=mz[Z];if(!q)return null;let X={provider:"claude",event:q,sessionKey:hz($),projectDir:pz($),raw:$},W=C($.permission_mode);if(W)X.permissionMode=W;let z=q==="subagent.start"||q==="subagent.stop",Y=z?void 0:C($.model);if(Y)X.model=Y;let V=cz($);if(V)X.effort=V;let G=gz($.context_usage_percent);if(G!==void 0)X.contextUsagePercent=G;let U=C($.transcript_path);if(U)X.transcriptPath=U;if(!z){let B=C($.agent_type);if(B)X.subagentType=B}switch(q){case"prompt.submit":{let B=C($.prompt);if(B!==void 0)X.text=B;break}case"response.after":{let B=C($.text);if(B!==void 0)X.text=B;break}case"shell.before":case"shell.after":{let B=Q?C(Q.command):void 0;if(B!==void 0)X.command=B;break}case"mcp.before":case"mcp.after":{if(J)X.toolName=J;if(Q)X.toolInput=Q;break}case"read.before":{let B=Q?C(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"edit.after":{if(J)X.toolName=J;let B=Q?C(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"tool.before":case"tool.after":case"tool.failure":{if(J)X.toolName=J;let B=$.tool_response;if(B!==void 0&&B!==null)X.toolOutput=typeof B==="string"?B:JSON.stringify(B);if(Q)X.toolInput=Q;let K=Q?C(Q.file_path):void 0;if(K!==void 0)X.filePath=K;let L=Q?C(Q.subagent_type):void 0;if(L)X.spawnSubagentType=L;let F=Q?C(Q.model):void 0;if(F)X.spawnModel=F;break}case"subagent.start":case"subagent.stop":{let B=C($.agent_type)??C($.subagent_type)??(Q?C(Q.subagent_type):void 0);if(B)X.spawnSubagentType=B;let K=(Q?C(Q.model):void 0)??C($.model);if(K)X.spawnModel=K;break}case"stop":{let B=uz($.status);if(B)X.status=B;break}default:break}return X}var iz={"session.start":"SessionStart","session.end":"SessionEnd","prompt.submit":"UserPromptSubmit","tool.before":"PreToolUse","tool.after":"PostToolUse","tool.failure":"PostToolUseFailure","shell.before":"PreToolUse","shell.after":"PostToolUse","mcp.before":"PreToolUse","mcp.after":"PostToolUse","read.before":"PreToolUse","edit.after":"PostToolUse","subagent.start":"SubagentStart","subagent.stop":"SubagentStop",stop:"Stop","compact.before":"PreCompact","response.after":"MessageDisplay","thought.after":"MessageDisplay"};function IJ($,Z,J){let Q={hookEventName:Z,permissionDecision:$};if(J!==void 0)Q.permissionDecisionReason=J;return JSON.stringify({hookSpecificOutput:Q})}function YQ($,Z){let J=iz[Z.event];switch($.kind){case"abstain":return{stdout:null,exitCode:0};case"allow":return{stdout:IJ("allow",J,void 0),exitCode:0};case"deny":return{stdout:IJ("deny",J,$.reason),exitCode:0};case"ask":return{stdout:IJ("ask",J,$.reason),exitCode:0};case"context":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,additionalContext:$.text}}),exitCode:0};case"continue":return{stdout:JSON.stringify({decision:"block",reason:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,updatedInput:$.input}}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function VQ(){return{blockedPatterns:[],minEffort:null,untrustedTools:["WebFetch","WebSearch"]}}var GQ={name:"claude",detect:qQ,capabilities:QQ,policyDefaults:VQ,toEvent:zQ,render:YQ,wiring:FJ};function BQ(){return{enforcesHooks:!0,askSupportedOn:["shell.before","mcp.before"],sessionEnv:!0,nativeLoopCounter:!0,dedicatedShellEvent:!0,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!1,contextAtToolAfter:!0,contextAtStop:!1,sessionStartContextReliable:!1,toolOutputAtAfter:!0,usageInPayload:!0,effortSignal:!1,thoughtEvent:!0}}var nz=/^[a-z][a-zA-Z0-9]*$/;function UQ($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!nz.test(J))return!1;return Array.isArray(Z.workspace_roots)}var rz={sessionStart:"session.start",sessionEnd:"session.end",beforeSubmitPrompt:"prompt.submit",preToolUse:"tool.before",postToolUse:"tool.after",postToolUseFailure:"tool.failure",beforeShellExecution:"shell.before",afterShellExecution:"shell.after",beforeMCPExecution:"mcp.before",afterMCPExecution:"mcp.after",beforeReadFile:"read.before",afterFileEdit:"edit.after",subagentStart:"subagent.start",subagentStop:"subagent.stop",stop:"stop",preCompact:"compact.before",afterAgentResponse:"response.after",afterAgentThought:"thought.after"};function O($){return typeof $==="string"?$:void 0}function HQ($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function KQ($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function az($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function sz($){let Z=O($.conversation_id)||O($.session_id)||"default";return`cursor-${P(Z)}`}function oz($){let Z=process.env.CURSOR_PROJECT_DIR;if(Z)return Z;let J=$.workspace_roots;if(Array.isArray(J)){let Q=O(J[0]);if(Q)return Q}return process.cwd()}function MQ($){let Z=O($.hook_event_name),J=Z?rz[Z]:void 0;if(!J)return null;let Q={provider:"cursor",event:J,sessionKey:sz($),projectDir:oz($),raw:$},q=O($.model);if(q)Q.model=q;let X=HQ($.context_usage_percent);if(X!==void 0)Q.contextUsagePercent=X;switch(J){case"prompt.submit":{let W=O($.prompt);if(W!==void 0)Q.text=W;break}case"response.after":{let W=O($.text);if(W!==void 0)Q.text=W;break}case"thought.after":{let W=O($.thought)??O($.text);if(W!==void 0)Q.text=W;break}case"tool.before":case"tool.after":case"tool.failure":{let W=O($.tool_name);if(W)Q.toolName=W;let z=KQ($.tool_input);if(z)Q.toolInput=z;let Y=O($.subagent_type);if(Y)Q.subagentType=Y;let V=z?O(z.model):void 0;if(V)Q.spawnModel=V;let G=z?O(z.subagent_type):void 0;if(G)Q.spawnSubagentType=G;break}case"shell.before":case"shell.after":{let W=O($.command);if(W!==void 0)Q.command=W;let z=O($.output);if(z!==void 0)Q.toolOutput=z;break}case"mcp.before":case"mcp.after":{let W=O($.result_json);if(W!==void 0)Q.toolOutput=W;let z=O($.tool_name);if(z)Q.toolName=z;let Y=KQ($.tool_input);if(Y)Q.toolInput=Y;let V=O($.command);if(V!==void 0)Q.command=V;break}case"read.before":case"edit.after":{let W=O($.file_path);if(W!==void 0)Q.filePath=W;break}case"subagent.start":case"subagent.stop":{let W=O($.subagent_type);if(W)Q.spawnSubagentType=W;let z=O($.subagent_model);if(z)Q.spawnModel=z;break}case"stop":{let W=az($.status);if(W)Q.status=W;let z=HQ($.loop_count);if(z!==void 0)Q.loopCount=z;break}default:break}return Q}function FQ($,Z){let J={permission:$};if(Z.userNote!==void 0)J.user_message=Z.userNote;return J.agent_message=Z.reason,JSON.stringify(J)}function CQ($,Z){switch($.kind){case"abstain":return{stdout:"{}",exitCode:0};case"allow":return{stdout:JSON.stringify({permission:"allow"}),exitCode:0};case"deny":return{stdout:FQ("deny",$),exitCode:0};case"ask":return{stdout:FQ("ask",$),exitCode:0};case"context":{let J={};if($.env!==void 0)J.env=$.env;return J.additional_context=$.text,{stdout:JSON.stringify(J),exitCode:0}}case"continue":return{stdout:JSON.stringify({followup_message:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({updated_input:$.input}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function OQ(){return{blockedPatterns:["-fast(?:$|[^a-z0-9])","/fast(?:$|[^a-z0-9])","composer-2\\.5-fast"],minEffort:null,untrustedTools:["Fetch","WebSearch"]}}import{join as tz}from"node:path";var ez=[{hookEvent:"sessionStart",handler:"session-start",timeoutSeconds:10},{hookEvent:"sessionEnd",handler:"session-end",timeoutSeconds:10},{hookEvent:"beforeSubmitPrompt",handler:"prompt-submit",timeoutSeconds:5},{hookEvent:"afterAgentThought",handler:"tool-after",timeoutSeconds:5},{hookEvent:"preCompact",handler:"compact-before",timeoutSeconds:5},{hookEvent:"subagentStart",handler:"subagent-start",timeoutSeconds:5,failClosed:!0},{hookEvent:"subagentStop",handler:"subagent-stop",timeoutSeconds:5},{hookEvent:"preToolUse",handler:"tool-before",timeoutSeconds:5,failClosed:!0},{hookEvent:"postToolUse",handler:"tool-after",timeoutSeconds:5},{hookEvent:"postToolUseFailure",handler:"tool-failure",timeoutSeconds:5},{hookEvent:"beforeShellExecution",handler:"tool-before",timeoutSeconds:10,failClosed:!0},{hookEvent:"afterShellExecution",handler:"tool-after",timeoutSeconds:10},{hookEvent:"beforeMCPExecution",handler:"tool-before",timeoutSeconds:10},{hookEvent:"afterMCPExecution",handler:"tool-after",timeoutSeconds:5},{hookEvent:"beforeReadFile",handler:"tool-before",timeoutSeconds:5},{hookEvent:"afterFileEdit",handler:"tool-after",timeoutSeconds:30,matcher:"Write"},{hookEvent:"stop",handler:"stop",timeoutSeconds:120,loopLimit:5},{hookEvent:"afterAgentResponse",handler:"response-after",timeoutSeconds:5,matcher:"AgentResponse"}];function _Q($){let J=[$.launcherPath],Q=ez.map((q)=>({hookEvent:q.hookEvent,handler:q.handler,command:"node",args:[...J,q.handler],timeoutSeconds:q.timeoutSeconds,...q.failClosed!==void 0?{failClosed:q.failClosed}:{},...q.matcher!==void 0?{matcher:q.matcher}:{},...q.loopLimit!==void 0?{loopLimit:q.loopLimit}:{}}));return{target:tz(RJ(),"hooks.json"),strategy:"replace",entries:Q}}var IQ={name:"cursor",detect:UQ,capabilities:BQ,policyDefaults:OQ,toEvent:MQ,render:CQ,wiring:_Q};var PJ=[IQ,GQ];function jJ($,Z){let J=Z.filter((Q)=>Q.detect($));if(J.length===0)return{provider:null,ambiguous:!1,matchedNames:[]};return{provider:J[0]??null,ambiguous:J.length>1,matchedNames:J.map((Q)=>Q.name)}}import{existsSync as PQ,statSync as $Y}from"node:fs";import{join as jQ}from"node:path";var NQ=M.observability.DEFAULT_OBS,MM={...NQ,debugEnabled:!0};function R8($,Z=NQ){return{...Z,globalSpool:$.obs.globalSpool,includePayloads:$.obs.includePayloads,maxAttrChars:$.obs.maxAttrChars,sessionCostAlertUsd:$.obs.sessionCostAlertUsd,retentionDays:$.obs.retentionDays}}function LQ($){try{return $Y($).size}catch{return 0}}function E8($){let Z=`${$.provider}-`;return $.sessionKey.startsWith(Z)?$.sessionKey.slice(Z.length):$.sessionKey}async function AQ($){if(!PQ(jQ($,".git")))return null;let Z=await X$({command:["git","rev-parse","--abbrev-ref","HEAD"],cwd:$});if(Z.exitCode!==0)return null;let J=Z.stdout.trim();return J.length>0?J:null}async function DQ($){if(!PQ(jQ($,".git")))return null;let Z=await X$({command:["git","rev-parse","--short","HEAD"],cwd:$});if(Z.exitCode!==0)return null;let J=Z.stdout.trim();return J.length>0?J:null}function TQ($,Z){return[...M.policy.forProvider($,Z.name)??[],...Z.policyDefaults().blockedPatterns]}function ZY($){return M.lesson.renderLessonBlock($)}function RQ($,Z){if($==="cursor")return CJ(Z);if($==="claude")return MJ(Z);return null}function EQ($,Z,J=0){if($.length===0)return"";let Q=[Z,...$.map(ZY)];if(J>0){let q=J===1?"lesson":"lessons";Q.push(` (${J} more eligible ${q} omitted under the char budget — raise maxCharsSession to see them)`)}return Q.join(`
|
|
153
|
+
…(truncated — over context budget)`.slice(0,Z),Q=Math.max(0,Z-J.length);return`${$.slice(0,Q)}${J}`}function wz($,Z){if($.event==="tool.before")return Z.contextAtToolBefore;if($.event==="tool.after")return Z.contextAtToolAfter;if($.event==="stop")return Z.contextAtStop;return!0}function OJ($,Z){if($.kind!=="context"||Z===void 0)return $;let J=JQ($.text,Z);if(J===$.text)return $;return{...$,text:J}}function _J($,Z,J,Q={}){if(!J.enforcesHooks&&bz($))return OJ({kind:"context",text:`${"ADVISORY — this provider cannot enforce: "}${yz($)}`},Q.contextBudgetChars);if($.kind==="ask"){if(!J.askSupportedOn.includes(Z.event))return{kind:"deny",reason:`${"Escalation unavailable on this provider — "}${$.reason}`,userNote:$.userNote,rule:$.rule};if(Z.permissionMode!==void 0&&fz.has(Z.permissionMode))return{kind:"deny",reason:`${"No operator is answering prompts in this permission mode — "}${$.reason}`,userNote:$.userNote,rule:$.rule};return $}if($.kind==="rewriteInput"&&!J.toolInputRewrite)return{kind:"ask",reason:`Input rewrite unavailable on this provider — proposed input: ${JSON.stringify($.input)}. ${$.reason}`,rule:Sz.rewriteUnavailable};if($.kind==="context"){if(!wz(Z,J))return{kind:"abstain"};if($.env&&!J.sessionEnv){let{env:q,...X}=$;return OJ(X,Q.contextBudgetChars)}return OJ($,Q.contextBudgetChars)}return $}function QQ(){return{enforcesHooks:!0,askSupportedOn:["tool.before","shell.before","mcp.before","read.before"],sessionEnv:!1,nativeLoopCounter:!1,dedicatedShellEvent:!1,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!0,contextAtToolAfter:!0,contextAtStop:!0,sessionStartContextReliable:!0,toolOutputAtAfter:!0,usageInPayload:!1,effortSignal:!0,thoughtEvent:!1}}var vz=/^[A-Z][a-zA-Z0-9]*$/;function qQ($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!vz.test(J))return!1;return typeof Z.cwd==="string"||typeof Z.transcript_path==="string"}var mz={SessionStart:"session.start",SessionEnd:"session.end",UserPromptSubmit:"prompt.submit",PostToolUseFailure:"tool.failure",SubagentStart:"subagent.start",SubagentStop:"subagent.stop",Stop:"stop",PreCompact:"compact.before",MessageDisplay:"response.after"},XQ=/^mcp__/;function C($){return typeof $==="string"?$:void 0}function gz($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function WQ($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function uz($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function hz($){let Z=C($.session_id)??"default";return`claude-${P(Z)}`}function pz($){let Z=process.env.CLAUDE_PROJECT_DIR;if(Z)return Z;let J=C($.cwd);if(J)return J;return process.cwd()}function cz($){let J=WQ($.effort)?.level;return I8(J)?J:void 0}function dz($){if($==="Bash")return"shell.before";if($&&XQ.test($))return"mcp.before";if($==="Read")return"read.before";return"tool.before"}function lz($){if($==="Bash")return"shell.after";if($&&XQ.test($))return"mcp.after";if($==="Edit"||$==="Write")return"edit.after";return"tool.after"}function zQ($){let Z=C($.hook_event_name);if(!Z)return null;let J=C($.tool_name),Q=WQ($.tool_input),q;if(Z==="PreToolUse")q=dz(J);else if(Z==="PostToolUse")q=lz(J);else q=mz[Z];if(!q)return null;let X={provider:"claude",event:q,sessionKey:hz($),projectDir:pz($),raw:$},W=C($.permission_mode);if(W)X.permissionMode=W;let z=q==="subagent.start"||q==="subagent.stop",Y=z?void 0:C($.model);if(Y)X.model=Y;let V=cz($);if(V)X.effort=V;let G=gz($.context_usage_percent);if(G!==void 0)X.contextUsagePercent=G;let U=C($.transcript_path);if(U)X.transcriptPath=U;if(!z){let B=C($.agent_type);if(B)X.subagentType=B}switch(q){case"prompt.submit":{let B=C($.prompt);if(B!==void 0)X.text=B;break}case"response.after":{let B=C($.text);if(B!==void 0)X.text=B;break}case"shell.before":case"shell.after":{let B=Q?C(Q.command):void 0;if(B!==void 0)X.command=B;break}case"mcp.before":case"mcp.after":{if(J)X.toolName=J;if(Q)X.toolInput=Q;break}case"read.before":{let B=Q?C(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"edit.after":{if(J)X.toolName=J;let B=Q?C(Q.file_path):void 0;if(B!==void 0)X.filePath=B;break}case"tool.before":case"tool.after":case"tool.failure":{if(J)X.toolName=J;let B=$.tool_response;if(B!==void 0&&B!==null)X.toolOutput=typeof B==="string"?B:JSON.stringify(B);if(Q)X.toolInput=Q;let K=Q?C(Q.file_path):void 0;if(K!==void 0)X.filePath=K;let L=Q?C(Q.subagent_type):void 0;if(L)X.spawnSubagentType=L;let F=Q?C(Q.model):void 0;if(F)X.spawnModel=F;break}case"subagent.start":case"subagent.stop":{let B=C($.agent_type)??C($.subagent_type)??(Q?C(Q.subagent_type):void 0);if(B)X.spawnSubagentType=B;let K=(Q?C(Q.model):void 0)??C($.model);if(K)X.spawnModel=K;break}case"stop":{let B=uz($.status);if(B)X.status=B;break}default:break}return X}var iz={"session.start":"SessionStart","session.end":"SessionEnd","prompt.submit":"UserPromptSubmit","tool.before":"PreToolUse","tool.after":"PostToolUse","tool.failure":"PostToolUseFailure","shell.before":"PreToolUse","shell.after":"PostToolUse","mcp.before":"PreToolUse","mcp.after":"PostToolUse","read.before":"PreToolUse","edit.after":"PostToolUse","subagent.start":"SubagentStart","subagent.stop":"SubagentStop",stop:"Stop","compact.before":"PreCompact","response.after":"MessageDisplay","thought.after":"MessageDisplay"};function IJ($,Z,J){let Q={hookEventName:Z,permissionDecision:$};if(J!==void 0)Q.permissionDecisionReason=J;return JSON.stringify({hookSpecificOutput:Q})}function YQ($,Z){let J=iz[Z.event];switch($.kind){case"abstain":return{stdout:null,exitCode:0};case"allow":return{stdout:IJ("allow",J,void 0),exitCode:0};case"deny":return{stdout:IJ("deny",J,$.reason),exitCode:0};case"ask":return{stdout:IJ("ask",J,$.reason),exitCode:0};case"context":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,additionalContext:$.text}}),exitCode:0};case"continue":return{stdout:JSON.stringify({decision:"block",reason:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({hookSpecificOutput:{hookEventName:J,updatedInput:$.input}}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function VQ(){return{blockedPatterns:[],minEffort:null,untrustedTools:["WebFetch","WebSearch"]}}var GQ={name:"claude",detect:qQ,capabilities:QQ,policyDefaults:VQ,toEvent:zQ,render:YQ,wiring:FJ};function BQ(){return{enforcesHooks:!0,askSupportedOn:["shell.before","mcp.before"],sessionEnv:!0,nativeLoopCounter:!0,dedicatedShellEvent:!0,toolInputRewrite:!0,toolOutputRewrite:!0,contextAtToolBefore:!1,contextAtToolAfter:!0,contextAtStop:!1,sessionStartContextReliable:!1,toolOutputAtAfter:!0,usageInPayload:!0,effortSignal:!1,thoughtEvent:!0}}var nz=/^[a-z][a-zA-Z0-9]*$/;function UQ($){if($===null||typeof $!=="object"||Array.isArray($))return!1;let Z=$,J=Z.hook_event_name;if(typeof J!=="string"||!nz.test(J))return!1;return Array.isArray(Z.workspace_roots)}var rz={sessionStart:"session.start",sessionEnd:"session.end",beforeSubmitPrompt:"prompt.submit",preToolUse:"tool.before",postToolUse:"tool.after",postToolUseFailure:"tool.failure",beforeShellExecution:"shell.before",afterShellExecution:"shell.after",beforeMCPExecution:"mcp.before",afterMCPExecution:"mcp.after",beforeReadFile:"read.before",afterFileEdit:"edit.after",subagentStart:"subagent.start",subagentStop:"subagent.stop",stop:"stop",preCompact:"compact.before",afterAgentResponse:"response.after",afterAgentThought:"thought.after"};function O($){return typeof $==="string"?$:void 0}function HQ($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function KQ($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:void 0}function az($){return $==="completed"||$==="aborted"||$==="error"?$:void 0}function sz($){let Z=O($.conversation_id)||O($.session_id)||"default";return`cursor-${P(Z)}`}function oz($){let Z=process.env.CURSOR_PROJECT_DIR;if(Z)return Z;let J=$.workspace_roots;if(Array.isArray(J)){let Q=O(J[0]);if(Q)return Q}return process.cwd()}function MQ($){let Z=O($.hook_event_name),J=Z?rz[Z]:void 0;if(!J)return null;let Q={provider:"cursor",event:J,sessionKey:sz($),projectDir:oz($),raw:$},q=O($.model);if(q)Q.model=q;let X=HQ($.context_usage_percent);if(X!==void 0)Q.contextUsagePercent=X;switch(J){case"prompt.submit":{let W=O($.prompt);if(W!==void 0)Q.text=W;break}case"response.after":{let W=O($.text);if(W!==void 0)Q.text=W;break}case"thought.after":{let W=O($.thought)??O($.text);if(W!==void 0)Q.text=W;break}case"tool.before":case"tool.after":case"tool.failure":{let W=O($.tool_name);if(W)Q.toolName=W;let z=KQ($.tool_input);if(z)Q.toolInput=z;let Y=O($.subagent_type);if(Y)Q.subagentType=Y;let V=z?O(z.model):void 0;if(V)Q.spawnModel=V;let G=z?O(z.subagent_type):void 0;if(G)Q.spawnSubagentType=G;break}case"shell.before":case"shell.after":{let W=O($.command);if(W!==void 0)Q.command=W;let z=O($.output);if(z!==void 0)Q.toolOutput=z;break}case"mcp.before":case"mcp.after":{let W=O($.result_json);if(W!==void 0)Q.toolOutput=W;let z=O($.tool_name);if(z)Q.toolName=z;let Y=KQ($.tool_input);if(Y)Q.toolInput=Y;let V=O($.command);if(V!==void 0)Q.command=V;break}case"read.before":case"edit.after":{let W=O($.file_path);if(W!==void 0)Q.filePath=W;break}case"subagent.start":case"subagent.stop":{let W=O($.subagent_type);if(W)Q.spawnSubagentType=W;let z=O($.subagent_model);if(z)Q.spawnModel=z;break}case"stop":{let W=az($.status);if(W)Q.status=W;let z=HQ($.loop_count);if(z!==void 0)Q.loopCount=z;break}default:break}return Q}function FQ($,Z){let J={permission:$};if(Z.userNote!==void 0)J.user_message=Z.userNote;return J.agent_message=Z.reason,JSON.stringify(J)}function CQ($,Z){switch($.kind){case"abstain":return{stdout:"{}",exitCode:0};case"allow":return{stdout:JSON.stringify({permission:"allow"}),exitCode:0};case"deny":return{stdout:FQ("deny",$),exitCode:0};case"ask":return{stdout:FQ("ask",$),exitCode:0};case"context":{let J={};if($.env!==void 0)J.env=$.env;return J.additional_context=$.text,{stdout:JSON.stringify(J),exitCode:0}}case"continue":return{stdout:JSON.stringify({followup_message:$.text}),exitCode:0};case"rewriteInput":return{stdout:JSON.stringify({updated_input:$.input}),exitCode:0};default:throw Error(`unreachable decision kind: ${JSON.stringify($)}`)}}function OQ(){return{blockedPatterns:["-fast(?:$|[^a-z0-9])","/fast(?:$|[^a-z0-9])","composer-2\\.5-fast"],minEffort:null,untrustedTools:["Fetch","WebSearch"]}}import{join as tz}from"node:path";var ez=[{hookEvent:"sessionStart",handler:"session-start",timeoutSeconds:10},{hookEvent:"sessionEnd",handler:"session-end",timeoutSeconds:10},{hookEvent:"beforeSubmitPrompt",handler:"prompt-submit",timeoutSeconds:5},{hookEvent:"afterAgentThought",handler:"tool-after",timeoutSeconds:5},{hookEvent:"preCompact",handler:"compact-before",timeoutSeconds:5},{hookEvent:"subagentStart",handler:"subagent-start",timeoutSeconds:5,failClosed:!0},{hookEvent:"subagentStop",handler:"subagent-stop",timeoutSeconds:5},{hookEvent:"preToolUse",handler:"tool-before",timeoutSeconds:5,failClosed:!0},{hookEvent:"postToolUse",handler:"tool-after",timeoutSeconds:5},{hookEvent:"postToolUseFailure",handler:"tool-failure",timeoutSeconds:5},{hookEvent:"beforeShellExecution",handler:"tool-before",timeoutSeconds:10,failClosed:!0},{hookEvent:"afterShellExecution",handler:"tool-after",timeoutSeconds:10},{hookEvent:"beforeMCPExecution",handler:"tool-before",timeoutSeconds:10},{hookEvent:"afterMCPExecution",handler:"tool-after",timeoutSeconds:5},{hookEvent:"beforeReadFile",handler:"tool-before",timeoutSeconds:5},{hookEvent:"afterFileEdit",handler:"tool-after",timeoutSeconds:30,matcher:"Write"},{hookEvent:"stop",handler:"stop",timeoutSeconds:120,loopLimit:5},{hookEvent:"afterAgentResponse",handler:"response-after",timeoutSeconds:5,matcher:"AgentResponse"}];function _Q($){let J=[$.launcherPath],Q=ez.map((q)=>({hookEvent:q.hookEvent,handler:q.handler,command:"node",args:[...J,q.handler],timeoutSeconds:q.timeoutSeconds,...q.failClosed!==void 0?{failClosed:q.failClosed}:{},...q.matcher!==void 0?{matcher:q.matcher}:{},...q.loopLimit!==void 0?{loopLimit:q.loopLimit}:{}}));return{target:tz(RJ(),"hooks.json"),strategy:"replace",entries:Q}}var IQ={name:"cursor",detect:UQ,capabilities:BQ,policyDefaults:OQ,toEvent:MQ,render:CQ,wiring:_Q};var PJ=[IQ,GQ];function jJ($,Z){let J=Z.filter((Q)=>Q.detect($));if(J.length===0)return{provider:null,ambiguous:!1,matchedNames:[]};return{provider:J[0]??null,ambiguous:J.length>1,matchedNames:J.map((Q)=>Q.name)}}import{existsSync as PQ,statSync as $Y}from"node:fs";import{join as jQ}from"node:path";var NQ=M.observability.DEFAULT_OBS,FM={...NQ,debugEnabled:!0};function R8($,Z=NQ){return{...Z,globalSpool:$.obs.globalSpool,includePayloads:$.obs.includePayloads,maxAttrChars:$.obs.maxAttrChars,sessionCostAlertUsd:$.obs.sessionCostAlertUsd,retentionDays:$.obs.retentionDays}}function LQ($){try{return $Y($).size}catch{return 0}}function E8($){let Z=`${$.provider}-`;return $.sessionKey.startsWith(Z)?$.sessionKey.slice(Z.length):$.sessionKey}async function AQ($){if(!PQ(jQ($,".git")))return null;let Z=await X$({command:["git","rev-parse","--abbrev-ref","HEAD"],cwd:$});if(Z.exitCode!==0)return null;let J=Z.stdout.trim();return J.length>0?J:null}async function DQ($){if(!PQ(jQ($,".git")))return null;let Z=await X$({command:["git","rev-parse","--short","HEAD"],cwd:$});if(Z.exitCode!==0)return null;let J=Z.stdout.trim();return J.length>0?J:null}function TQ($,Z){return[...M.policy.forProvider($,Z.name)??[],...Z.policyDefaults().blockedPatterns]}function ZY($){return M.lesson.renderLessonBlock($)}function RQ($,Z){if($==="cursor")return CJ(Z);if($==="claude")return MJ(Z);return null}function EQ($,Z,J=0){if($.length===0)return"";let Q=[Z,...$.map(ZY)];if(J>0){let q=J===1?"lesson":"lessons";Q.push(` (${J} more eligible ${q} omitted under the char budget — raise maxCharsSession to see them)`)}return Q.join(`
|
|
154
154
|
`)}var QY=6000;function qY($){if($.filePath===void 0)return!1;if($.event==="edit.after")return!0;return q8($.toolName)}function XY($){return $ instanceof Error?$.message:String($)}function $$($,Z,J){try{A(JY(H($),"obs.jsonl"),{schema:"harness.observability.v1",provider:"unknown",kind:Z,level:"signal",ts:new Date().toISOString(),attrs:J})}catch{}}function WY($,Z,J){if(J.kind!=="deny"&&J.kind!=="ask")return;if($.event==="shell.before")return;M.observability.recordObs($.projectDir,R8(Z),{provider:$.provider,kind:"policy.deny",sessionKey:$.sessionKey,attrs:{event:$.event,tool_name:$.toolName,permission:J.kind,rule:J.rule??"none"}})}function zY($){return $!==null&&typeof $==="object"&&!Array.isArray($)?$:{}}async function YY($,Z={}){let J=Z.readStdin??oJ,Q=Z.now?Z.now():new Date,q={stdout:null,exitCode:0},W=(await J()).trim();if(!W)return $$(process.cwd(),"adapter.unrecognized",{reason:"empty-stdin"}),{event:null,decision:{kind:"abstain"},rendered:q};let z;try{z=JSON.parse(W)}catch{return $$(process.cwd(),"adapter.unrecognized",{reason:"invalid-json"}),{event:null,decision:{kind:"abstain"},rendered:q}}let Y=jJ(z,PJ);if(!Y.provider)return $$(process.cwd(),"adapter.unrecognized",{reason:"no-provider-match"}),{event:null,decision:{kind:"abstain"},rendered:q};if(Y.ambiguous)$$(process.cwd(),"adapter.ambiguous",{matched:Y.matchedNames});let V=Y.provider,G=V.toEvent(zY(z));if(!G)return $$(process.cwd(),"adapter.unrecognized",{reason:"unrecognized-event",provider:V.name}),{event:null,decision:{kind:"abstain"},rendered:q};let U=V.capabilities();try{let B=M.policy.loadPolicy(G.projectDir);if(G.model)M.subagentPolicy.upsertParentModelState(G.projectDir,G.sessionKey,{model:G.model},TQ(B.subagents.blockedPatterns,V));M.presence.heartbeat(G.projectDir,{provider:G.provider,session:E8(G),...qY(G)?{file:G.filePath}:{},now:Q});let L=await $(G,{policy:B,capabilities:U,provider:V,now:Q}),F=_J(L,G,U,{contextBudgetChars:QY});WY(G,B,F);let m=V.render(F,G);return{event:G,decision:F,rendered:m}}catch(B){$$(G.projectDir,"adapter.error",{provider:G.provider,event:G.event,message:XY(B)});let K={kind:"abstain"};return{event:G,decision:K,rendered:V.render(K,G)}}}async function kQ($){let Z=await YY($);if(Z.rendered.stdout!==null){let J=Z.rendered.stdout;process.stdout.write(J.endsWith(`
|
|
155
155
|
`)?J:`${J}
|
|
156
156
|
`)}process.exit(Z.rendered.exitCode)}var VY=async($,Z)=>{let{policy:J}=Z,Q=E8($),q=$.projectDir;M.policy.recordPolicyBaseline(q,$.sessionKey);let X=0;if(M.turn.markBooted(q,$.sessionKey).alreadyBooted)return{kind:"context",text:"",env:{HARNESS_ACTIVE:"1"}};let z=await AQ(q),Y=await DQ(q);M.presence.sweepStale(q),M.presence.register(q,{provider:$.provider,session:Q,pid:process.pid,branch:z??"unknown"}),await M.handoff.patchHandoff(q,$.provider,{shared:{mode:J.mode,project_name:J.projectName,git_branch:z??void 0,git_sha:Y??void 0},slice:{session_key:$.sessionKey,next_action:"Run `tlc harness handoff` if resuming; otherwise start from the user request."}});let V=M.handoff.handoffInjectable(q),G=M.lesson.projectLessonsInjectable(q),U=V.ok?M.handoff.readHandoff(q,$.provider):{},B=V.ok?M.handoff.readForeignSlices(q,$.provider):[],K=[...[V.note,G.note].filter((F)=>F!==null),...M.policy.operatorBootstrapLines(J,H(q)),"",`Project root: ${q}`];if(J.projectName)K.push(`Project: ${J.projectName}`);if(z)K.push(`Git branch: ${z}`);if(Y)K.push(`Git HEAD: ${Y}`);if(U.blockers)K.push(`Handoff blocker: ${U.blockers}`);if(U.next_action)K.push(`Handoff next: ${U.next_action}`);if(J.intelligence.progressiveHandoff){let F=M.turn.formatCarriedGaps(U.previous_gaps??[]);if(F)K.push("",F)}for(let F of B){if(K.push("",`Foreign slice (${F.provider}):`),F.next_action)K.push(` next_action: ${F.next_action}`);if(F.blockers)K.push(` blockers: ${F.blockers}`)}if(J.intelligence.lessons.enabled&&G.ok){let F=J.intelligence.lessons,m=await M.lesson.selectLessons({projectDir:q,config:F,mode:"session",text:[U.blockers,U.next_action].filter(Boolean).join(" ")}),Z$=EQ(m.lessons,"Lessons (ranked; follow these — do not repeat known failures):",m.omitted);if(Z$)K.push("",Z$);if(M.lesson.durableViewVerdict(F.syncRulesFile,Z.capabilities.sessionStartContextReliable).writes){M.lesson.renderLessonsMarkdown(q,M.lesson.allLessons(q),F);let J$=RQ($.provider,q);X=J$===null?0:LQ(J$)}}K.push(J.grind.enabled?"Grind ON: stop hook runs configured lint/test gates and auto-continues on failure.":"Grind OFF (default).");let L=K.join(`
|