@brainervirus/workit-claude-code 8.44.3 → 8.45.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "workit",
3
3
  "displayName": "Workit",
4
- "version": "8.44.3",
4
+ "version": "8.45.0",
5
5
  "description": "Workflow rails for agentic coding: task context on every session, branch policy on shell commands, and the workit method skills",
6
6
  "author": {
7
7
  "name": "BrainerVirus"
@@ -210,7 +210,7 @@ ${n.addendum}`:""}
210
210
  `)}:ri}catch(r){return r instanceof rt?eu(r):ri}}var Kl=(e)=>({kind:"deny",reason:e,unblock:null}),m0=(e)=>`workit: ${G(e)} sends this push to a repository the shell hook cannot read, so it does not run. ${e.startsWith("-")?`Drop ${G(e)}`:`Unset ${e}`}, or cd into the repository and push with ${G("workit git push")}.`,Ob="Split it into simpler commands (no deeply nested substitutions or huge brace lists) and run them one at a time.",eu=(e)=>({kind:"deny",reason:`workit: the shell hook could not analyze this command (${e.message}), so it does not run. ${Ob}`,unblock:Ob}),tu="next",k0=3600,nu=(e,t,n)=>We.join(e.location.dir,"hooks",`commit-${Tb("sha256").update(`${t}\x00${n}`).digest("hex").slice(0,32)}.json`),di=(e,t)=>e??`cmd:${Tb("sha256").update(t).digest("hex")}`;function ru(e,t,n){try{if(!e.session.id||!/\bcommit\b/.test(t))return;let r=Math.floor(Date.now()/1000);for(let{action:o,repo:s}of ui(e.cwd,t,Ql(e))){if(o.kind!=="commit")continue;let i=nu(s,e.session.id,n);St.mkdirSync(We.dirname(i),{recursive:!0}),St.writeFileSync(i,`${JSON.stringify({head:XE(s),at:r})}
211
211
  `)}}catch{}}var y0=(e)=>{let t=no("git",["log","-1","--format=%H%x1f%ct%x1f%s%x1f%(trailers:key=Workit-Session,valueonly,separator=%x2c)"],{cwd:e,encoding:"utf8",timeout:5000,windowsHide:!0,env:{...process.env,GIT_TERMINAL_PROMPT:"0",GIT_OPTIONAL_LOCKS:"0",LC_ALL:"C"}}),[n,r,o="",s=""]=(t.status===0?t.stdout.trim():"").split("\x1F");return n&&/^[0-9a-f]{40,64}$/.test(n)?{sha:n,committed:Number(r),subject:o,trailer:s.trim()||null}:null},Yb=(e,t,n)=>{let r;try{r=JSON.parse(St.readFileSync(n,"utf8"))}catch{return}St.rmSync(n,{force:!0});let o=e.session.id,s=Date.now()/1000;if(typeof r.at!=="number"||s-r.at>k0)return;if(!o||!t.branch)return;let i=y0(t.dir);if(!i||i.sha===r.head||i.committed<r.at)return;if(i.trailer&&i.trailer!==o)return;let a=et(t.dir);if(!a.ok)return;if(a.value.rows.some((l)=>l.type==="commit.recorded"&&(l.sha===i.sha||l.head===i.sha)))return;ln(t.dir,{type:"commit.recorded",actor:{host:e.host,session:o,agentId:e.session.agentId},branch:t.branch,head:i.sha,sha:i.sha,session:o,agentId:e.session.agentId,subject:i.subject.slice(0,200),files:[],fileCount:null,via:"raw_shell"})};function ou(e,t,n){try{if(!e.session.id||!/\bcommit\b/.test(t))return;for(let{action:r,repo:o}of ui(e.cwd,t,Ql(e)))if(r.kind==="commit")Yb(e,o,nu(o,e.session.id,n))}catch{}}function Qb(e){try{if(!e.session.id)return;let t=Yl(e.cwd);if(!t)return;let n=nu(t,e.session.id,tu);if(St.existsSync(n))Yb(e,t,n)}catch{}}var S0=/[$`*?[\]{}~]/u,x0=new Set(["-c","--create","-C","--force-create","--orphan"]),_0=new Set(["-b","-B","--orphan"]),R0=new Set(["-b","-B"]),$0=new Set(["-b","--branch"]),ew=new Set(["-d","-D","--delete","-l","--list","-a","--all","-r","--remotes","--show-current"].concat(["-v","-vv","--verbose","--contains","--no-contains","--merged","--no-merged"]).concat(["--points-at","--sort","--format","--column","--no-column","-u"]).concat(["--set-upstream-to","--unset-upstream","--edit-description","-i","--ignore-case"])),tw=new Set(["-m","-M","--move","-c","-C","--copy"]),su=(e,t)=>t.has(e)||e.length>=3&&[...t].some((n)=>n.startsWith("--")&&n.startsWith(e)),I0=(e)=>[...e].filter((t)=>/^-[^-]$/u.test(t)).join("").replaceAll("-",""),pi=(e,t)=>{let n=I0(t);for(let r=1;r<e.length;r++){let o=e[r];if(o==="--")return null;if(o.startsWith("--")){let s=o.indexOf("=");if(!su(s>0?o.slice(0,s):o,t))continue;return s>0?o.slice(s+1):e[r+1]??null}if(!o.startsWith("-")||o.length<2)continue;for(let s=1;s<o.length;s++)if(n.includes(o[s]))return s+1<o.length?o.slice(s+1):e[r+1]??null}return null},O0=new Set(["--reason"]),T0=(e)=>{let t=pi(e,R0);if(t!==null)return t;let n=[];for(let o=1;o<e.length;o++){let s=e[o];if(s==="--detach"||s==="-d")return null;if(O0.has(s))o++;else if(!s.startsWith("-"))n.push(s)}if(n.length!==1)return null;let r=n[0].split(/[\\/]/u).findLast(Boolean)??"";return r&&r!=="."&&r!==".."?r:null},E0=(e)=>{let t=!1,n=[];for(let r=1;r<e.length;r++){let o=e[r];if(o==="--"){n.push(...e.slice(r+1));break}if(o.startsWith("--")){let s=o.split("=",1)[0];if(su(s,ew))return null;if(su(s,tw))t=!0}else if(o.startsWith("-")&&o.length>1){let s=o.slice(1).split("");if(s.some((i)=>ew.has(`-${i}`)))return null;if(s.some((i)=>tw.has(`-${i}`)))t=!0}else n.push(o)}if(n.length<1||n.length>2)return null;return t?n.at(-1)??null:n[0]},gi=(e,t,n=new Set)=>{let r=[];for(let o=t;o<e.length;o++){let s=e[o];if(s==="--")return[...r,...e.slice(o+1)];if(n.has(s))o++;else if(!s.startsWith("-")||s==="-")r.push(s)}return r},fi=(e)=>e.startsWith("refs/heads/")?e.slice(11):null,C0=(e,t)=>{if(e.some((o)=>o==="-d"||o==="--delete"))return[];if(e.includes("--stdin"))return(t??"").split(/[\n\0]/u).map((o)=>/^\s*(?:create|update)\s+(\S+)/u.exec(o)?.[1]??"").map(fi).filter((o)=>o!==null);let[n]=gi(e,1,new Set(["-m"])),r=n?fi(n):null;return r?[r]:[]},A0=(e)=>{if(e.some((n)=>n==="-d"||n==="--delete"))return null;let[,t]=gi(e,1,new Set(["-m"]));return t?fi(t):null},P0=new Set(["--depth","--deepen","--shallow-since","--shallow-exclude","--refmap","-j","--jobs"].concat(["--upload-pack","-o","--server-option","--negotiation-tip","--filter"]).concat(["--recurse-submodules-default","--submodule-prefix","-s","--strategy","-X"]).concat(["--strategy-option"])),z0=(e,t)=>{if(e.includes("--all")||e.includes("--multiple"))return[];let n=e.includes("--stdin")?(t??"").split(/\s+/u).filter(Boolean):gi(e,1,P0).slice(1),r=[];for(let o of n){let s=o.indexOf(":"),i=s>=0?o.slice(s+1):"";if(!i||i.includes("*"))continue;let a=i.startsWith("refs/")?fi(i):i;if(a)r.push(a)}return r},N0=(e)=>{let t=to(e);if(t?.kind!=="push"||t.remote!=="."||t.deletes)return[];return t.targets.filter((n)=>n!==null)},D0=(e,t)=>{let[n,r]=e;return(n==="switch"?[pi(e,x0)]:n==="checkout"?[pi(e,_0)]:n==="branch"?[E0(e)]:n==="worktree"&&r==="add"?[T0(e.slice(1))]:n==="stash"&&r==="branch"?gi(e,2).slice(0,1):n==="update-ref"?C0(e,t):n==="symbolic-ref"?[A0(e)]:n==="fetch"||n==="pull"?z0(e,t):n==="push"?N0(e):n==="subtree"&&r==="split"?[pi(e.slice(1),$0)]:[]).filter((s)=>s!==null&&s!==""&&!s.startsWith("-")&&!S0.test(s))},L0=(e)=>e.flatMap((t)=>t.tool==="git"?D0(t.args,t.stdin).map((n)=>({branch:n,dir:t.dir})):[]);var j0=(e,t)=>b0("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e,stdio:"ignore",timeout:5000}).status===0,nw=(e,t)=>{if(t===void 0)return null;if(t===null)return e;let n=v0.resolve(e,t);return w0(n)&&ot(n)?n:null},rw=(e,t,n="posix")=>{let r=!1,o=new Map;for(let s of _t(t,n)){if(s.tool!=="git"||nw(e,s.dir)===null)continue;for(let i of L0(li(e,s,o))){let a=nw(e,i.dir);if(a===null||j0(a,i.branch))continue;r=!0;let c=hs(a,i.branch);if(!c.ok)return c}}return r?{ok:!0}:null};var iu=(e,t,n="posix")=>{let r;try{r=rw(e,t,n)}catch(o){if(o instanceof rt)return eu(o);throw o}return r&&!r.ok?{kind:"deny",reason:`branch_policy_denied: ${r.error}`,unblock:null}:{kind:"none"}};var hi=["git","pr","ci","stack","release","task","ledger","evidence","finding","decision","worker","verify-delivery","policy","doctor","help"],au=["--unverified","--overwrite-unintegrated"],jF=new Set(hi),M0=(e)=>au.some((t)=>e===t||e.startsWith(`${t}=`)),F0=(e)=>/^(?:.*[\\/])?workit(?:-cli)?$/u.test(e);var ow=(e)=>`Workit: \`${e}\` overrides a Workit gate, so the user decides this call (no allow rule covers it).`,sw=(e,t="posix")=>{for(let n of Se(e,t)){if(n.unanalyzable){let a=e.replaceAll(/['"\\`]/gu,"");if(!/\bworkit\b/u.test(a))return null;let c=au.find((l)=>a.includes(l));return c?ow(c):null}let r=n.words.findIndex(F0);if(r<0)continue;let o=n.words.slice(r+1),s=o.indexOf("--"),i=(s<0?o:o.slice(0,s)).find(M0);if(i)return ow(i.split("=")[0]??i)}return null};import lu from"node:fs";import B0 from"node:os";import le from"node:path";var mi=()=>({deny:[],allow:[]}),ki=(e)=>{try{return lu.readFileSync(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}},Wt=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e);function iw(e){let t="";for(let n=0;n<e.length;n+=1){let r=e[n];if(r==='"'){let o=/"(?:[^"\\]|\\.)*"/y;o.lastIndex=n;let s=o.exec(e);if(!s)throw Error("unterminated string");t+=s[0],n+=s[0].length-1}else if(r==="/"&&e[n+1]==="/"){while(n<e.length&&e[n]!==`
212
212
  `)n+=1;t+=`
213
- `}else if(r==="/"&&e[n+1]==="*"){let o=e.indexOf("*/",n+2);if(o<0)throw Error("unterminated comment");n=o+1}else t+=r}return JSON.parse(t.replace(/,(\s*[}\]])/gu,"$1"))}function En(e){for(let t=le.resolve(e);;t=le.dirname(t)){if(lu.existsSync(le.join(t,".git")))return t;if(le.dirname(t)===t)return null}}var W0=(e)=>{let t=En(e),n=[];for(let r=le.resolve(e);;r=le.dirname(r))if(n.push(r),!t||r===t||le.dirname(r)===r)return n},yi=(e)=>e.HOME||B0.homedir(),aw={linux:"/etc/claude-code/managed-settings.json",darwin:"/Library/Application Support/ClaudeCode/managed-settings.json",win32:"C:\\Program Files\\ClaudeCode\\managed-settings.json"};function H0(e,t,n=process.platform){let r=t.CLAUDE_PROJECT_DIR||En(e)||e,o=t.CLAUDE_CONFIG_DIR||le.join(yi(t),".claude");return[...aw[n]?[aw[n]]:[],le.join(o,"settings.json"),le.join(r,".claude","settings.json"),le.join(r,".claude","settings.local.json")]}var Z0=(e)=>{let t=/^Bash(?:\((.*)\))?$/su.exec(e.trim());return t?t[1]??"":null};function dw(e,t=process.env){let n=mi();try{for(let r of H0(e,t)){let o=ki(r);if(o===null)continue;let s=JSON.parse(o);if(!Wt(s))return"unreadable";let i=s.permissions;if(i===void 0)continue;if(!Wt(i))return"unreadable";for(let[a,c]of[["deny",n.deny],["ask",n.deny],["allow",n.allow]]){let l=i[a];if(l===void 0)continue;if(!Array.isArray(l))return"unreadable";for(let u of l){if(typeof u!=="string")return"unreadable";let d=Z0(u);if(d!==null)c.push(d)}}}}catch{return"unreadable"}return n}var cw=["opencode.json","opencode.jsonc"],lw=(e,t)=>{if(e===void 0)return!0;if(typeof e==="string")return(e==="allow"?t.allow:t.deny).push(""),["allow","ask","deny"].includes(e);if(!Wt(e))return!1;for(let n of["bash","shell"]){let r=e[n];if(r===void 0)continue;if(typeof r==="string"){if(!["allow","ask","deny"].includes(r))return!1;(r==="allow"?t.allow:t.deny).push("");continue}if(!Wt(r))return!1;for(let[o,s]of Object.entries(r)){if(s!=="allow"&&s!=="ask"&&s!=="deny")return!1;(s==="allow"?t.allow:t.deny).push(o)}}return!0},uw=(e,t)=>{if(!Wt(e))return!1;if(!lw(e.permission,t))return!1;if(e.agent===void 0)return!0;if(!Wt(e.agent))return!1;return Object.values(e.agent).every((n)=>Wt(n)&&lw(n.permission,t))};function pw(e,t=process.env){let n=mi();try{let r=t.XDG_CONFIG_HOME||le.join(yi(t),".config"),o=[...cw.map((s)=>le.join(r,"opencode",s)),...W0(e).flatMap((s)=>cw.flatMap((i)=>[le.join(s,i),le.join(s,".opencode",i)])),...t.OPENCODE_CONFIG?[t.OPENCODE_CONFIG]:[]];for(let s of o){let i=ki(s);if(i!==null&&!uw(iw(i),n))return"unreadable"}if(t.OPENCODE_CONFIG_CONTENT&&!uw(iw(t.OPENCODE_CONFIG_CONTENT),n))return"unreadable"}catch{return"unreadable"}return n}var U0=(e)=>{let t=/\bpattern\s*=\s*\[/u.exec(e);if(!t)return null;let n=[],r=t.index+t[0].length;for(;;){while(/[\s,]/u.test(e[r]??""))r+=1;if(e[r]==="]")break;if(e[r]!=='"')return null;let s=/"((?:[^"\\]|\\.)*)"/y;s.lastIndex=r;let i=s.exec(e);if(!i)return null;n.push(JSON.parse(`"${i[1]}"`)),r=s.lastIndex}let o=/\bdecision\s*=\s*"(\w+)"/u.exec(e)?.[1];if(!n.length||!o||!["allow","prompt","forbidden"].includes(o))return null;return{pattern:n.join(" "),decision:o}};function fw(e,t=process.env){let n=mi();try{let r=t.CODEX_HOME||le.join(yi(t),".codex"),o=En(e)??e;for(let s of[le.join(r,"rules"),le.join(o,".codex","rules")]){let i;try{i=lu.readdirSync(s).filter((a)=>a.endsWith(".rules"))}catch(a){if(a.code==="ENOENT")continue;return"unreadable"}for(let a of i){let c=ki(le.join(s,a))??"";for(let l of c.split(/\bprefix_rule\s*\(/u).slice(1)){let u=U0(l);if(!u)return"unreadable";(u.decision==="allow"?n.allow:n.deny).push(u.pattern)}}}}catch{return"unreadable"}return n}function gw(e,t=process.env){let n=mi();try{let r=En(e)??e;for(let o of[le.join(yi(t),".cursor","cli-config.json"),le.join(r,".cursor","cli.json")]){let s=ki(o);if(s===null)continue;let i=JSON.parse(s);if(!Wt(i))return"unreadable";if(i.permissions===void 0)continue;if(!Wt(i.permissions))return"unreadable";for(let[a,c]of[["deny",n.deny],["allow",n.allow]]){let l=i.permissions[a];if(l===void 0)continue;if(!Array.isArray(l))return"unreadable";for(let u of l){if(typeof u!=="string")return"unreadable";let d=/^Shell(?:\((.*)\))?$/su.exec(u.trim());if(d)c.push(d[1]??"")}}}}catch{return"unreadable"}return n}var cu=(e)=>(e.split(/[\\/]/u).at(-1)??"").toLowerCase().replace(/\.(?:exe|cmd|bat)$/u,""),hw=(e)=>e.trim().split(/[:\s]/u)[0]??"";function K0(e,t){let n=hw(e);if(!n||n==="*"||n.includes("*"))return!0;let r=cu(n);return t.some((o)=>cu(o)===r)}var mw=(e)=>e.trim().replace(/(?::\*| \*|\*)$/u,""),G0=(e)=>{let t=hw(e);if(!t||t.includes("*"))return!0;let n=mw(e).split(/\s+/u);if(cu(n[0])!=="workit")return!1;return["check","--heavy"].slice(0,n.length-1).every((r,o)=>{let s=n[o+1];return s===r||r.startsWith(s)})},J0=(e,t)=>{let n=mw(e);if(!n)return!0;return!n.includes("*")&&t.trim().startsWith(n)};function kw(e,t,n,r={}){if(e==="unreadable")return{ok:!1,why:"named"};if(e.deny.some((o)=>K0(o,t)))return{ok:!1,why:"named"};if(!r.bypass&&e.allow.some(G0)&&!e.allow.some((o)=>J0(o,n)))return{ok:!1,why:"allowlisted"};return{ok:!0}}import uu from"node:fs";import q0 from"node:os";import Ht from"node:path";function V0(e,t=process.platform){if(e.WORKFLOW_TOOLKIT_STATE)return e.WORKFLOW_TOOLKIT_STATE;if(e.XDG_STATE_HOME)return Ht.join(e.XDG_STATE_HOME,"workit");let n=e.HOME||q0.homedir();if(t==="darwin")return Ht.join(n,"Library","Application Support","workit");if(t==="win32")return Ht.join(e.LOCALAPPDATA??Ht.join(n,"AppData","Local"),"workit");return Ht.join(n,".local","state","workit")}var X0="heavy-commands.json",Y0=(e)=>Ht.join(V0(e),X0),pn=/^(?:test|tests|t|tst|unit|integration|e2e|coverage|cov|lint|eslint|typecheck|type-check|types|tsc|check|verify|validate|build|compile|bundle|ci|sonar|cypress|playwright|jest|vitest|mocha|bench|benchmark|all)(?:$|[:_.-])/iu,Q0=new Set(["--version","-v","-V","--help","-h","help","version"]),eC=/^(?:--watch(?:All)?(?:=.*)?|-w|--serve)$/u,cr=/(?:^|[:_.-])(?:watch|dev|serve|start|storybook)(?:$|[:_.-])/iu,W=(...e)=>new Set(e),tC={jest:"any",vitest:"any",mocha:"any",ava:"any",tap:"any",karma:"any",jasmine:"any",nyc:"any",c8:"any",tsc:"any","vue-tsc":"any","svelte-check":"any",eslint:"any",stylelint:"any",tslint:"any",webpack:"any","webpack-cli":"any",rollup:"any",parcel:"any",tsup:"any",vite:W("build","optimize"),next:W("build","lint"),nuxt:W("build","generate"),nuxi:W("build","generate"),astro:W("build","check"),ng:W("build","b","test","t","e2e","lint"),"react-scripts":W("build","test"),playwright:W("test","install"),cypress:W("run"),wdio:"any",testcafe:"any",turbo:"any",lerna:W("run","exec","bootstrap"),"sonar-scanner":"any",sonarless:W("scan"),"sonarless-mcp":W("scan"),go:W("test","build","vet","install","generate"),"golangci-lint":W("run"),gotestsum:"any",staticcheck:"any",cargo:W("build","b","test","t","check","c","clippy","bench","nextest","doc","install","tarpaulin","llvm-cov"),mvn:"any",mvnw:"any",gradle:"any",gradlew:"any",ant:"any",sbt:"any",bazel:W("build","test","run","coverage"),bazelisk:W("build","test","run","coverage"),buck2:W("build","test","run"),dotnet:W("build","test","publish","restore","pack","msbuild"),msbuild:"any",pytest:"any","py.test":"any",tox:"any",nox:"any",mypy:"any",pyright:"any",pylint:"any",coverage:W("run"),maturin:W("build","develop"),pip:W("install","wheel"),pip3:W("install","wheel"),rspec:"any",rails:W("test","assets:precompile"),phpunit:"any",pest:"any",phpstan:"any",psalm:"any",composer:W("install","update","require","test"),mix:W("test","compile","deps.get","dialyzer","credo"),swift:W("build","test"),xcodebuild:"any",flutter:W("build","test"),dart:W("test","compile"),pod:W("install"),cmake:W("--build"),ninja:"any",meson:W("compile","test"),ctest:"any",scons:"any","docker-compose":W("build"),buildah:W("bud","build"),earthly:"any"},nC=new Set(["--prefix","-w","--workspace","-C","--dir","--filter","-F","--cwd","-p","--package","--cache","--registry"]);function He(e,t,n=nC){let r=t;while(r<e.length&&e[r].startsWith("-")){if(e[r]==="--")return r+1;r+=n.has(e[r])?2:1}return r}var du=(e)=>(e?.split(/[\\/]/u).at(-1)??"").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u,""),bw=/^(?:workit|@brainervirus\/workit-cli(?:@.*)?)$/u,rC=/^(?:python[\d.]*|py)$/u,oC=new Set(["ci","clean-install","cit","install-test","it","install","i","in","add","rebuild","update","up"]),sC=new Set(["run","run-script","rum","urn"]),iC=new Set(["test","t","tst"]),aC=new Set(["exec","x","dlx"]);function ww(e,t=0){if(t>6||!e.length)return null;let n=du(e[0]),r=()=>e.slice(0,3).join(" "),o=(a)=>ww(e.slice(a),t+1);if(bw.test(n))return null;if(Q0.has(e[1]??"")&&e.length===2)return null;if(e.some((a)=>a==="--watch"||a.startsWith("--watch=")||a==="--watchAll"))return null;if(n==="npx"||n==="bunx"||n==="pnpx")return o(He(e,1));if(n==="corepack")return o(1);if(n==="npm"||n==="pnpm"||n==="yarn"||n==="bun"||n==="deno"){let a=He(e,1),c=e[a];if(c===void 0)return n==="yarn"?"yarn (install)":null;if(n==="deno"){if(["test","bench","check","compile","lint"].includes(c))return r();if(c==="task"&&pn.test(e[a+1]??""))return r();return null}if(oC.has(c)||iC.has(c))return r();if(n==="bun"&&c==="build")return r();if(aC.has(c))return o(He(e,a+1));if(n==="yarn"&&c==="workspace")return o(a+2);if(n==="yarn"&&c==="workspaces")return e.slice(a+1).some((l)=>pn.test(l))?r():null;if(sC.has(c)){let l=e[He(e,a+1)];if(l===void 0||cr.test(l))return null;if(pn.test(l))return r();return n==="bun"?o(He(e,a+1)):null}if(n==="npm")return null;if(cr.test(c))return null;if(pn.test(c)&&!/\.[cm]?[jt]sx?$/u.test(c))return r();return o(a)}if(rC.test(n)){let a=e.indexOf("-m");return a>0&&e[a+1]?o(a+1):null}if(["uv","poetry","pdm","pipenv","hatch","rye"].includes(n)){let a=He(e,1),c=e[a];if(c==="run")return o(He(e,a+1));if(c==="pip")return o(a);return["sync","install","build","test","add"].includes(c??"")?r():null}if(n==="bundle"){let a=e[He(e,1)];if(a==="exec")return o(He(e,2));return a==="install"||a===void 0?r():null}if(n==="make"||n==="gmake"){let a=e.slice(1).filter((c)=>!c.startsWith("-")&&!c.includes("="));if(a.some((c)=>cr.test(c)))return null;return!a.length||a.some((c)=>pn.test(c))?r():null}if(n==="rake")return e.slice(1).filter((c)=>!c.startsWith("-")&&!c.includes("=")).some((c)=>pn.test(c)||/^spec(?:$|:)/u.test(c))?r():null;if(n==="nx"){let a=He(e,1),c=e[a]??"";if(["run-many","affected"].includes(c))return e.some((l)=>/^(?:-t|--targets?)(?:=|$)/u.test(l))&&!e.some((l)=>cr.test(l.replace(/^--?targets?=/u,"")))?r():null;if(c==="run"){let l=(e[a+1]??"").split(":")[1]??"";return pn.test(l)&&!cr.test(l)?r():null}return pn.test(c)&&!cr.test(c)?r():null}if(n==="docker"||n==="podman"||n==="nerdctl"){let a=He(e,1,new Set(["-H","--host","--context","-c","--config"])),c=e[a];if(c==="build")return r();if(c==="buildx"||c==="image"||c==="builder")return e[He(e,a+1)]==="build"?r():null;if(c==="compose"){let l=He(e,a+1,new Set(["-f","--file","-p"])),u=e[l];if(u==="build")return r();return u==="up"&&e.slice(l+1).includes("--build")?r():null}return null}let s=tC[n];if(!s)return null;if(e.slice(1).some((a)=>eC.test(a)||a==="watch"||a==="dev"))return null;if(s==="any")return r();let i=e.slice(1).find((a)=>!a.startsWith("-")&&!a.startsWith("+")||s.has(a));return i!==void 0&&s.has(i)?r():null}var cC=(e)=>new RegExp(`^${e.replace(/[.+?^${}()|[\]\\]/gu,"\\$&").replaceAll("*",".*")}$`,"u");function lC(e){let t=e.trim().split(/\s+/u).filter(Boolean);return t.length?t.map(cC):null}var uC=(e,t)=>e.length<=t.length&&e.every((n,r)=>r===0?n.test(t[0])||n.test(du(t[0])):n.test(t[r])),dC=(e)=>{try{return JSON.parse(uu.readFileSync(e,"utf8"))}catch{return}},pC=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),fC=(e)=>Array.isArray(e)?e.filter((t)=>typeof t==="string"):[];function gC(e){let t=dC(Y0(e));return pC(t)?fC(t.patterns):[]}function hC(e){return $s(En(e)??Ht.resolve(e))}function yw(e,t){let n=[],r=null;for(let o of e){let s=ww(o);if(s){n.push({line:o,source:"catalog",reason:s});continue}r??=(t.patterns??[...gC(t.env??process.env).map((a)=>({pattern:a,from:"machine"})),...hC(t.cwd).map((a)=>({pattern:a,from:"repo"}))]).flatMap((a)=>{let c=lC(a.pattern);return c?[{...a,matchers:c}]:[]});let i=r.find((a)=>uC(a.matchers,o));if(i)n.push({line:o,source:{pattern:i.pattern,from:i.from},reason:`${i.from} pattern "${i.pattern}"`})}return n}var mC=(e,t)=>{try{return Mb(e,t)}catch{return null}};var kC=(e)=>/^[\w@%+=:,./-]+$/u.test(e)?e:`'${e.replaceAll("'","'\\''")}'`,yC=(e)=>`workit check --heavy -- ${e.map(kC).join(" ")}`;function vw(e,t){let n=t.dialect??"posix";if(n!=="posix"||!En(t.cwd))return{kind:"none"};let r=mC(e,n);if(!r)return{kind:"none"};let o=yw(r,t);if(!o.length)return{kind:"none"};let s=ai(e,n,0,!0),i=s&&!bw.test(du(s[0]))&&yw([s],t)[0],a=i?[{words:r.flat(),text:e}]:o.map((l)=>({words:l.line,text:l.line.join(" ")}));if(t.rules!==null){for(let{words:l,text:u}of a)if(!kw(t.rules,l,u,{bypass:t.bypass}).ok)return{kind:"passthrough",note:""}}if(i){let l=wC(e);return l?{kind:"rewrite",command:l,reason:i.reason}:{kind:"none"}}let c=o.map((l)=>yC(l.line));return{kind:"split",reason:`heavy_command: \`${e.trim()}\` chains heavy work (${o.map((l)=>l.reason).join("; ")}) with other commands, and a chain cannot run under the machine-wide heavy-check lease. Run the heavy part alone, now: \`${c[0]}\`; then run the other parts as their own commands${c.length>1?", each heavy one the same way":""}.`,unblock:c[0]??null}}function Sw(e=process.env){let t=process.platform==="win32"?["workit.exe","workit.cmd","workit"]:["workit"];for(let n of(e.PATH??"").split(Ht.delimiter))for(let r of t){if(!n)continue;try{return uu.accessSync(Ht.join(n,r),uu.constants.X_OK),!0}catch{}}return!1}var bC=/^\s*((?:[A-Za-z_]\w*=(?:'[^']*'|"(?:[^"\\]|\\.)*"|[^\s'"])*\s+)*)/u;function wC(e){let t=e.trim(),n=bC.exec(t)?.[1]??"",r=t.slice(n.length).trim();if(!r)return null;return`${n}workit check --heavy -- ${r}`}import xw from"node:fs";import vC from"node:os";import Rt from"node:path";var SC=new Set("npm npx pnpm pnpx yarn bun bunx deno corepack make gmake docker podman nerdctl python python3 py uv poetry pdm pipenv hatch rye bundle rake nx jest vitest mocha ava tap karma jasmine nyc c8 tsc vue-tsc svelte-check eslint stylelint tslint webpack webpack-cli rollup parcel tsup vite next nuxt nuxi astro ng react-scripts playwright cypress wdio testcafe turbo lerna sonar-scanner sonarless sonarless-mcp go golangci-lint gotestsum staticcheck cargo mvn mvnw gradle gradlew ant sbt bazel bazelisk buck2 dotnet msbuild pytest py.test tox nox mypy pyright pylint coverage maturin pip pip3 rspec rails phpunit pest phpstan psalm composer mix swift xcodebuild flutter dart pod cmake ninja meson ctest scons docker-compose buildah earthly".split(" ")),_w=(e)=>e.split(/[\s;&|()<>`'"]+/u).map((t)=>(t.split(/[\\/]/u).at(-1)??"").toLowerCase().replace(/\.(?:exe|cmd|bat)$/u,"")).filter(Boolean),pu=(e)=>{if(e.WORKFLOW_TOOLKIT_STATE)return e.WORKFLOW_TOOLKIT_STATE;if(e.XDG_STATE_HOME)return Rt.join(e.XDG_STATE_HOME,"workit");let t=e.HOME||vC.homedir();if(process.platform==="darwin")return Rt.join(t,"Library","Application Support","workit");if(process.platform==="win32")return Rt.join(e.LOCALAPPDATA??Rt.join(t,"AppData","Local"),"workit");return Rt.join(t,".local","state","workit")},xC=(e)=>{try{return JSON.parse(xw.readFileSync(e,"utf8"))}catch{return}},_C=(e,t)=>{let n=[],r=xC(Rt.join(pu(t),"heavy-commands.json"));if(Array.isArray(r?.patterns))n.push(...r.patterns);for(let s=Rt.resolve(e);;s=Rt.dirname(s)){if(xw.existsSync(Rt.join(s,".git"))){n.push(...$s(s));break}if(Rt.dirname(s)===s)break}let o=new Set;for(let s of n){if(typeof s!=="string")continue;let i=_w(s)[0];if(!i||i.includes("*"))return null;o.add(i)}return o};function Rw(e,t,n=process.env){try{let r=_w(e);if(r.some((s)=>SC.has(s)||/^python[\d.]*$/u.test(s)))return!0;let o=_C(t,n);return o===null||r.some((s)=>o.has(s))}catch{return!0}}var RC=(e,t,n)=>{switch(e){case"claude_code":return dw(t,n);case"opencode":return pw(t,n);case"codex_cli":case"codex_desktop":return fw(t,n);case"cursor":return gw(t,n);case"pi":return null}};function fu(e,t,n){let r=n.env??process.env;try{if(r.WORKIT_HEAVY_GATE==="0"||!Rw(t,e,r)||!Sw(r))return{kind:"none"};return vw(t,{cwd:e,env:r,dialect:n.dialect??"posix",rules:RC(n.host,e,r),bypass:n.permissionMode==="bypassPermissions"})}catch{return{kind:"none"}}}var $w=(e)=>`workit: this heavy command (${e.reason}) runs under the machine-wide heavy-check lease as \`${e.command}\`: it waits while another heavy check holds the lease (\`workit lock status\` shows who). Run heavy commands that way yourself; \`workit help lock\` explains the lease.`,gu=(e,t)=>({kind:"deny",reason:`heavy_command: \`${e.trim()}\` is heavy (${t.reason}) and must run under the machine-wide heavy-check lease, so parallel agents cannot exhaust this machine's memory and CPU. Run exactly: ${t.command}`,unblock:t.command}),hu=(e)=>({kind:"deny",reason:e.reason,unblock:e.unblock});import{existsSync as NC,realpathSync as DC}from"node:fs";import jw from"node:os";import Z from"node:path";import{spawnSync as $C}from"node:child_process";import{createHash as IC}from"node:crypto";import pt from"node:fs";import ku from"node:os";import $t from"node:path";var OC=900000,TC=30000,Cn={platform:process.platform,run:(e)=>$C("ps",e,{encoding:"utf8",timeout:2000}).stdout??"",start:(e)=>Wr(e)},mu=(e)=>e.split(":")[0].replace(/-w-.*$/su,"")||e,Iw=(e)=>e.replace(/_(?:cli|desktop)$/u,""),EC=(e)=>{try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}},CC=(e)=>{try{if(Cn.platform==="linux"){let n=pt.readFileSync(`/proc/${e}/stat`,"utf8"),r=Number(n.slice(n.lastIndexOf(")")+2).split(" ")[1]),o=pt.readFileSync(`/proc/${e}/cmdline`,"utf8").replaceAll("\x00"," ");return Number.isInteger(r)?{ppid:r,command:o.trim()}:null}if(Cn.platform==="win32")return null;let t=/^\s*(\d+)\s+(.*)$/su.exec(Cn.run(["-o","ppid=,command=","-p",String(e)]));return t?{ppid:Number(t[1]),command:t[2].trim()}:null}catch{return null}},AC=/^(?:\S*\/)?(?:sh|bash|dash|zsh|ash|ksh|fish|env|timeout|npx|npm|bunx|cmd\.exe|pwsh|powershell)(?:\s|$)|launch\.mjs|npx-cli\.js/u,bi=new Map,PC=(e)=>{if(e!=="hook-process")return process.pid;let t=`${Cn.platform}\x00${process.ppid}`;if(bi.has(t))return bi.get(t)??null;if(Cn.platform==="win32")return bi.set(t,null),null;let n=process.ppid;for(let r=0;r<4;r++){let o=CC(n);if(!o||!AC.test(o.command)||o.ppid<=1)break;n=o.ppid}return bi.set(t,n),n},wi=(e)=>e.replace(/[^A-Za-z0-9_.:@/+-]/gu,"-"),Si=(e,t,n=process.env)=>{let r=e.session.id?.trim();if(!r)return null;let o=new Set([mu(wi(r))]);if(e.session.parentId)o.add(mu(wi(e.session.parentId)));if(n.WORKIT_PI_WORKER_SESSION&&n.WORKIT_SESSION_ID)o.add(mu(wi(n.WORKIT_SESSION_ID)));return{host:e.host,session:wi(r),leads:[...o],pid:()=>PC(t)}},Ow=(e)=>{let t=$t.resolve(e);while(!pt.existsSync(t)&&$t.dirname(t)!==t)t=$t.dirname(t);if(pt.existsSync(t)&&!pt.statSync(t).isDirectory())t=$t.dirname(t);let n=t.split($t.sep),r=n.lastIndexOf(".git");if(r>0)t=n.slice(0,r).join($t.sep)||$t.sep;let o=we(t);if(o instanceof Error||!o.shared||!o.top)return null;let s=o.top;try{s=pt.realpathSync.native(s)}catch{}return s},Tw=(e)=>$t.join(Ae(),"live-sessions",`${IC("sha256").update(zC(e)).digest("hex").slice(0,32)}.json`),zC=(e,t=process.platform)=>{let n=$t.resolve(e);try{n=pt.realpathSync.native(n)}catch{}return t==="win32"?n.replaceAll("/","\\").toLowerCase():n},Ew=(e)=>{try{let t=JSON.parse(pt.readFileSync(e,"utf8"));if(t?.version!==1||typeof t.session!=="string"||typeof t.host!=="string"||typeof t.heartbeatAt!=="string"||Number.isNaN(Date.parse(t.heartbeatAt)))return null;return{version:1,session:t.session,leads:Array.isArray(t.leads)?t.leads.filter((n)=>typeof n==="string"):[],host:t.host,pid:typeof t.pid==="number"?t.pid:null,pidStart:typeof t.pidStart==="string"?t.pidStart:null,machine:typeof t.machine==="string"?t.machine:"",checkout:typeof t.checkout==="string"?t.checkout:"",heartbeatAt:t.heartbeatAt}}catch{return null}},yu=(e,t)=>t.getTime()-Date.parse(e.heartbeatAt),Cw=(e,t)=>{if(yu(e,t.now??new Date)>(t.ttlMs??OC))return!1;if(e.machine!==(t.machine??ku.hostname())||e.pid===null)return!0;if(!(t.alive??EC)(e.pid))return!1;if(e.pidStart===null)return!0;let r=Cn.start(e.pid);return r===null||r===e.pidStart},vi=(e,t)=>e.session===t.session||t.leads.some((n)=>n===e.session||e.leads.includes(n)),Aw=(e,t,n)=>{if(vi(e,t))return!0;if(e.machine!==n)return!1;let r=t.pid();if(r===null||e.pid===null||e.pidStart===null)return Iw(e.host)===Iw(t.host);return e.pid===r},Pw=(e,t,n={})=>{try{let r=Ow(e);if(!r)return null;let o=Tw(r),s=Ew(o);if(!s||vi(s,t)||!Cw(s,n))return null;if(Aw(s,t,n.machine??ku.hostname()))return null;return{marker:s,file:o,ageMs:yu(s,n.now??new Date),checkout:r}}catch{return null}},zw=(e,t,n={})=>{try{let r=Ow(e);if(!r)return;let o=Tw(r),s=n.now??new Date,i=n.machine??ku.hostname(),a=Ew(o);if(a){let d=yu(a,s);if(vi(a,t)&&d>=0&&d<TC)return;if(!vi(a,t)&&Cw(a,n)&&!Aw(a,t,i))return}let c=t.pid(),l={version:1,session:t.session,leads:t.leads,host:t.host,pid:c,pidStart:c===null?null:Cn.start(c),machine:i,checkout:r,heartbeatAt:s.toISOString()};pt.mkdirSync($t.dirname(o),{recursive:!0});let u=`${o}.${process.pid}.tmp`;pt.writeFileSync(u,JSON.stringify(l)),pt.renameSync(u,o)}catch{}};var ao={kind:"none"},LC=process.platform==="darwin"||process.platform==="win32",bu=(e)=>{let t="";for(let n=Z.resolve(e);;n=Z.dirname(n))try{return Z.join(DC.native(n),t)}catch{if(Z.dirname(n)===n)return Z.resolve(e);t=t?Z.join(Z.basename(n),t):Z.basename(n)}},jC=(e,t,n,r)=>{let o=(c)=>LC?c.toLowerCase():c,s=Z.relative(o(bu(t)),o(bu(Z.resolve(e,n))));if(s.startsWith("..")||Z.isAbsolute(s))return!0;let i=s.split(Z.sep).join("/"),a=i.split("/");return/\.mdx?$/i.test(i)||a[0]==="docs"||a.includes("plans")||[...r].some((c)=>o(c)===i)},_i=new Set(["sudo","command","env","nohup","time","exec","xargs","busybox"]),An=(e)=>e.filter((t)=>!t.startsWith("-")),Mw=new Set(["sh","bash","zsh","dash","ksh"]),Fw=(e)=>{let t=e;while(t.length&&(_i.has(t[0])||/^\w+=/.test(t[0])))t=t.slice(1);let n=Xl(t);if(!n)return null;if("script"in n)return n.script;let r=Su(n.argv);if(Mw.has((n.argv[0]?.split(/[\\/]/).at(-1)??"").toLowerCase())&&r)return r;return n.argv.map(xu).join(" ")},vu=(e)=>{let t=e;while(t.length&&(_i.has(t[0])||/^\w+=/.test(t[0])))t=t.slice(1);let[n,...r]=t,o=(n?.split(/[\\/]/).at(-1)??"").toLowerCase();if(!o||o==="workit"||o==="npx"&&r.some((s)=>/workit/.test(s)))return[];switch(o){case"touch":case"mkdir":case"rm":case"rmdir":case"tee":case"mv":case"truncate":return An(r);case"cp":case"ln":case"install":{let s=r.indexOf("-t");if(s>=0)return r[s+1]?[r[s+1]]:null;let i=An(r).at(-1);return i?[i]:null}case"dd":return r.filter((s)=>s.startsWith("of=")).map((s)=>s.slice(3));case"sed":case"perl":{if(!r.some((a)=>/^-[a-zA-Z]*i|^--in-place/.test(a)))return[];let s=r.some((a)=>a==="-e"||a==="-f"),i=[];for(let a=0;a<r.length;a++)if(r[a]==="-e"||r[a]==="-f")a++;else if(!r[a].startsWith("-"))i.push(r[a]);return s?i:i.slice(1)}case"patch":return null;case"set-content":case"add-content":case"out-file":case"new-item":case"ni":case"remove-item":case"del":case"copy-item":case"move-item":{let s=r.findIndex((c)=>/^-(?:path|filepath|literalpath|destination)$/i.test(c));if(s>=0)return r[s+1]?[r[s+1]]:null;let i=An(r);if(o==="move-item")return i.length?i:null;let a=o==="copy-item"?i.at(-1):i[0];return a?[a]:null}case"git":{let s=An(r)[0];if(s==="apply")return null;if(s==="restore"||s==="mv"||s==="rm")return An(r).slice(1);if(s==="checkout"&&r.includes("--"))return r.slice(r.indexOf("--")+1);return[]}default:return[]}},Su=(e)=>{if(!Mw.has((e[0]?.split(/[\\/]/).at(-1)??"").toLowerCase()))return null;for(let t=1;t<e.length;t++){let n=e[t];if(/^-[a-z]*c$/.test(n))return e[t+1]??null;if(/^[-+][oO]$/.test(n))t++;else if(!/^[-+]/.test(n))return null}return null},MC=/^-[IinLPdsEa]$/,Nw=(e)=>{let t=[...e.filter((r)=>r!=="{}"&&r!==";"&&r!=="+"),"x"],n=vu(t);return n===null||n.length>0||Bw(t)!==null},Bw=(e)=>{let t=e;while(t.length&&(_i.has(t[0])||/^\w+=/.test(t[0]))){if(t[0]==="xargs"){let c=1;while(t[c]?.startsWith("-"))c+=MC.test(t[c])?2:1;return Nw(t.slice(c))?["."]:null}t=t.slice(1)}let[n,...r]=t,o=(n?.split(/[\\/]/).at(-1)??"").toLowerCase(),s=An(r),i=(c)=>r.some((l)=>c.test(l)),a=(c)=>c.length?c:["."];if(o==="unlink"||o==="shred")return a(s);if(/^(?:chmod|chown|chgrp|chattr)$/.test(o))return a(i(/^--reference/)?s:s.slice(1));if(o==="rsync"){let c=s.at(-1),l=/^[\w.@-]*:/.test(c??"")&&!/^[A-Za-z]:[\\/]/.test(c??"");return c===void 0?["."]:l?[]:[c]}if(o==="find"){let c=r.findIndex((d)=>/^-(?:exec|execdir|ok|okdir)$/.test(d)),l=i(/^-(?:delete|fprint\w*|fls)$/)||c>=0&&Nw(r.slice(c+1)),u=r.findIndex((d)=>/^[-(!]/.test(d));return l?a(u<0?r:r.slice(0,u)):null}if(/^g?awk$/.test(o)){if(!i(/^-i|^--include/))return null;let c=[],l=!i(/^-f$|^--file/);for(let u=0;u<r.length;u++)if(/^(?:-[ifvF]|--(?:include|file|assign|field-separator))$/.test(r[u]))u++;else if(r[u].startsWith("-"))continue;else if(l)l=!1;else c.push(r[u]);return a(c)}if(o==="perl")return i(/^-[a-zA-Z]*[eE]/)?["."]:null;if(/^(?:python[\d.]*|node|bun|deno|ruby|php)$/.test(o))return i(/^-[a-zA-Z]*[ce]$|^--eval$|^-p$/)?["."]:null;return Su(t)===null?null:["."]},FC=(e,t)=>{let n=An([...e]),r=e.indexOf("-t"),o=r>=0?e[r+1]:n.length>1?n.at(-1):".",s=n.filter((l,u)=>r>=0?l!==o:u<n.length-1||n.length===1),i=o===void 0?null:t(o),a=e.some((l)=>/^-[a-zA-Z]*s|^--symbolic$/.test(l)),c=i===null?null:r>=0||s.length>1||NC(i)||/[\\/]$/.test(o??"")?i:Z.dirname(i);return s.flatMap((l)=>{if(a&&c!==null&&!Z.isAbsolute(lo(l)))return[Z.resolve(c,l)];let u=t(l);return u?[u]:[]})},Ri=(e,t=0)=>{let n=[],r=!1;for(let o of Se(e)){let s=t<4?Fw(o.words):null;if(s!==null){let a=Ri(s,t+1);if(a.writes&&a.targets===null)r=!0;else if(a.targets)n.push(...a.targets)}n.push(...o.redirects.filter((a)=>!/^\/dev\/(?:null|stdout|stderr|tty)$/.test(a)));let i=vu(o.words);if(i===null)r=!0;else n.push(...i)}if(!r&&n.length===0)return{writes:!1,targets:null};return{writes:!0,targets:r?null:n}},io=new Map,Dw=(e,t)=>[...t].map((n)=>on(Z.resolve(e,n))??"-").join("\x00"),BC=(e)=>{let t=new sn(e),n=t.listTaskIndex();if(!n.ok)return null;let r=t.currentKey();if(!r.ok)return null;let o=n.data.filter((h)=>h.key===r.data.key&&h.status!=="closed").toSorted((h,f)=>f.updatedAt.localeCompare(h.updatedAt))[0];if(!o)return{blockers:[],root:t.root,plans:new Set};let s=rr(t.root),i=`${o.id}\x00${o.revision}\x00${s.ok&&on(s.value)||"-"}`,a=io.get(t.root);if(a&&a.key===i&&a.planKey===Dw(t.root,a.plans))return a;let c=t.readTask(o.id);if(!c.ok)return null;let l=t.readWorkspace(),u=new Set((On(c.data)?.refs??[]).flatMap((h)=>h.kind==="file"?[h.path]:[])),p={blockers:My(c.data,t.root).filter((h)=>{let f=c.data.policy?.requirements.find((g)=>g.ruleId===h.ruleId&&g.before==="write");return!(f?.acceptanceAllowed&&l.ok&&l.data&&Vs(c.data,l.data,f,t.root).length>0)}),root:t.root,plans:u,key:i,planKey:Dw(t.root,u)};if(io.set(t.root,p),io.size>32)io.delete(io.keys().next().value);return p},WC=new Set(["add","am","apply","checkout","cherry-pick","clean","commit","merge","mv","pull","rebase","reset","restore","revert","rm","stash","switch"]),HC=new Set(["add","clean","rm","mv"]),ZC=new Set(["commit","branch"]),co=".workit-live-target",Ww="WORKIT_LIVE_SESSION=override",Hw=(e,t)=>e.some((n)=>n==="--help"||n==="-h"||n==="--dry-run"||HC.has(t)&&/^-[a-zA-Z]*n[a-zA-Z]*$/.test(n)&&!n.startsWith("--")),UC=(e,t,n)=>{let r;try{r=_t(t,n)}catch{return[]}return r.flatMap((o)=>{if(o.tool!=="git"||o.dir===void 0)return[];let s=o.args.findIndex((c)=>!c.startsWith("-")),i=o.args[s]??"",a=o.args.slice(s+1);if(!WC.has(i)||Hw(a,i))return[];if(i==="stash"&&["list","show"].includes(a[0]??""))return[];return[Z.resolve(e,o.dir??".")]})},KC=new Set(["cd","chdir","set-location","sl"]),GC=new Set(["pushd","push-location"]),JC=new Set(["popd","pop-location"]),$i=Z.resolve(Z.parse(process.cwd()).root,".workit-unknown-dir"),Lw=(e,t,n=!1)=>{let r=n?$i:void 0,o=t.slice(1).find((i)=>!i.startsWith("-")||i==="-"),s=o===void 0?void 0:lo(o);if(s==="-"||s&&/^~|[$`*?]/.test(s))return r;if(e===void 0)return r;return s===void 0?jw.homedir():Z.resolve(e,s)},xu=(e)=>/^[\w@%+=:,./-]+$/.test(e)?e:`'${e.replaceAll("'","'\\''")}'`,lo=(e)=>{let t=/^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(e);return t?(process.env.HOME||jw.homedir())+e.slice(t[0].length):e},xi=(e,t,n,r=0,o=!1)=>{let s=[],i=e,a=[],c=[],l=(u)=>{let d=lo(u);return Z.isAbsolute(d)?d:i===void 0?null:Z.resolve(i,d)};for(let u of Se(t,n)){if(u.group==="open"){c.push({dir:i,stack:[...a]});continue}if(u.group==="close"){let m=c.pop();if(m)({dir:i,stack:a}=m);continue}let d=u.words.findIndex((m)=>!/^\w+=/.test(m)),p=d<0?[]:u.words.slice(d),h=(p[0]?.split(/[\\/]/).at(-1)??"").toLowerCase();if(KC.has(h)){i=Lw(i,p,o);continue}if(GC.has(h)){a.push(i),i=Lw(i,p,o);continue}if(JC.has(h)){i=a.length?a.pop():o?$i:void 0;continue}let f=r<4?Fw(p)??(o?Su(p):null):null;if(f!==null&&i!==void 0)s.push(...xi(qC(i,p),f,"posix",r+1,o));if(o&&i!==void 0){let m=i;for(let b of r<4?u.subs??[]:[])s.push(...xi(m,b,n,r+1,!0));let k=u.unanalyzable?["."]:f===null?Bw(p):null;for(let b of k??[]){let v=l(b);if(v)s.push(b==="."?Z.join(v,co):v)}let y=p.findIndex((b)=>/^ln$/i.test(b.split(/[\\/]/).at(-1)??""));if(y>=0&&p.slice(0,y).every((b)=>_i.has(b)))s.push(...FC(p.slice(y+1),l))}for(let m of u.redirects)if(!/^\/dev\/(?:null|stdout|stderr|tty)$/.test(m)){let k=l(m);if(k)s.push(k)}let g=vu(u.words);if(g===null){if(i!==void 0)s.push(Z.join(i,co))}else for(let m of g){let k=l(m);if(k)s.push(k)}if(i!==void 0)for(let m of Bt(u.words.map(xu).join(" "),"posix")){let{at:k,args:y}=Zw(i,m);if(y[0]==="git"&&ZC.has(y[1]??"")&&!Hw(y.slice(2),""))s.push(Z.join(k,co))}}return s},qC=(e,t)=>{for(let n of Bt(t.map(xu).join(" "),"posix")){let{at:r,args:o}=Zw(e,n);if(o[0]==="check"||o[0]==="lock"&&o[1]==="run")return r}return e},Zw=(e,t)=>{let{rest:n,cwd:r}=oo(t);return{at:r===null?e:Z.resolve(e,lo(r)),args:n}},_u=(e,t,n="posix",r=!1)=>{try{return[...xi(e,t,n,0,r),...UC(e,t,n).map((o)=>Z.join(o,co))]}catch{return[]}},VC=(e,t)=>{let n=Se(e,t);if(n.length!==1||n[0].group||n[0].subs?.length)return!1;let r=n[0].words,o=r.findIndex((s)=>!/^\w+=/.test(s));return o>0&&r.slice(0,o).includes(Ww)},XC={claude_code:"Claude Code",opencode:"OpenCode",codex_cli:"Codex CLI",codex_desktop:"Codex Desktop",cursor:"Cursor",pi:"Pi"},YC=(e)=>{let t=Math.max(0,Math.round(e/1000));return t<120?`${t}s`:`${Math.round(t/60)} min`},QC=({marker:e,checkout:t,ageMs:n,file:r})=>{let o=`Work in your own worktree (\`git worktree add <path> -b <branch>\`, or \`workit fanout worktree create <slice>\`). Only if the user confirms that session is finished: release it with \`rm '${r}'\`, or prefix one command with ${Ww}.`;return{kind:"deny",reason:`workit live-session guard: ${t} belongs to another live agent session, ${XC[e.host]??e.host} session ${e.session}${e.pid===null?"":` (pid ${e.pid})`}, last active ${YC(n)} ago. Do not edit a checkout another session is working in; read-only commands stay allowed. ${o}`,unblock:o}},Uw=(e)=>{let t=new Set;return e.filter((n)=>{let r=Z.dirname(n);if(t.has(r))return!1;return t.add(r),!0})},Kw=(e,t,n)=>{try{for(let r of Uw(t)){let o=Pw(r,e,n);if(o&&om(o.checkout))return QC(o)}}catch{}return ao},Gw=(e,t,n)=>{for(let r of Uw(t))zw(r,e,n)},Ru=(e,t)=>t?.length?t.map((n)=>Z.resolve(e,n)):[Z.join(e,co)],Jw=(e,t)=>{let n=Ae();return t.find((o)=>eA(n,e,lo(o),process.platform,bu))??null},eA=(e,t,n,r=process.platform,o=(s)=>s)=>{let s=r==="win32",i=s?Z.win32:Z.posix,a=(u)=>s||r==="darwin"?u.toLowerCase():u,c=s?n.replace(/^\/([a-zA-Z])(?=\/|$)/,"$1:"):n,l=i.relative(a(o(i.resolve(e))),a(o(i.resolve(t,c))));if(l.startsWith("..")||i.isAbsolute(l))return!1;return l.split(i.sep)[0].startsWith("issued")},tA=(e)=>{if(process.platform!=="win32"||!e.includes("\\"))return!1;let t=(n)=>n.replaceAll("\\","/").toLowerCase();return t(e).includes(`${t(Ae())}/issued`)&&Ri(e).writes},qw=(e)=>({kind:"deny",reason:`workit issued-registry guard: ${e} is under Workit's issued-session state. Issued ids and tokens are written only by Workit's SubagentStart hook. Run the verifier or reviewer agent so the host issues its own session; never edit the issued registries by hand.`,unblock:"Issued ids and tokens are written only by Workit's SubagentStart hook. Run the verifier or reviewer agent so the host issues its own session; never edit the issued registries by hand."});function $u(e,t,n,r){let o=t?.length?Jw(e,t):null;if(o)return qw(o);if(!n)return wu(e,t);let s=Ru(e,t),i=Kw(n,s,r);if(i.kind!=="none")return i;let a=wu(e,t);if(a.kind==="none")Gw(n,s,r);return a}function Iu(e,t,n,r="posix",o){try{let c=Jw(e,xi(e,t,r))??(tA(t)?"the issued registry":null);if(c)return qw(c)}catch{}let s=Ri(t),i=[];if(n)i=_u(e,t,r);if(n&&i.length){let c=Kw(n,i,o);if(c.kind!=="none"){if(!VC(t,r))return c;nA(e,n,t)}}let a=s.writes?wu(e,s.targets):ao;if(n&&i.length&&a.kind==="none")Gw(n,i,o);return a}var nA=(e,t,n)=>{try{if(!ot(e))return;ln(e,{type:"live_session.override",actor:{host:t.host,session:t.session,agentId:null},session:t.session,command:n.slice(0,200)})}catch{}};function wu(e,t){try{let n=BC(e);if(!n||n.blockers.length===0)return ao;if(t?.length&&t.every((o)=>jC(e,n.root,o,n.plans)))return ao;return{kind:"deny",reason:`workit before-write gate: ${n.blockers.map((o)=>`${o.ruleId}: ${o.reason}`).join("; ")}. Markdown, docs/, plans/ and files outside the checkout stay writable.`,unblock:n.blockers[0].reason}}catch{return ao}}import{spawnSync as wA}from"node:child_process";import Vw from"node:os";import Ii from"node:path";var rA=()=>{try{return Vw.userInfo().homedir}catch{return Vw.homedir()}},oA={resolve:rA},Ti=()=>Ii.join(oA.resolve(),".config","workit"),sA=()=>{let e=Ii.resolve(qi());return e===Ii.resolve(Ti())?null:`the config directory is redirected to ${e} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${Ii.join(Ti(),"workspaces.json")}, so the D4 defaults apply`},Eu=["push","pr","merge","release","rerun"],iA=Object.freeze({push:!0,pr:!0,merge:!1,release:!1,rerun:!0}),Ei=["commit","pr","green","merged"],Oi="commit",aA=(e)=>typeof e==="string"&&Ei.includes(e),cA=(e,t)=>Ei.indexOf(t)>Ei.indexOf(e);function lA(e){let t=e?.defaultEndpoint;if(t===void 0)return{raw:t,endpoint:Oi};if(aA(t))return{raw:t,endpoint:t};return{raw:t,endpoint:Oi,issue:`defaultEndpoint ${JSON.stringify(t)} is not one of ${Ei.join(", ")}; using ${Oi}`}}function uA(e,t){if(e==="commit")return{endpoint:e};let n=(r)=>`${r} grant missing; ${tv(t.workspace,r)}`;if(t.grants.push===!1)return{endpoint:"commit",reason:n("push")};if(t.grants.pr===!1)return{endpoint:"commit",reason:n("pr")};if(t.configured.length>0&&!t.accountConfigured)return{endpoint:"commit",reason:`vcs.account missing; ${ev(t.workspace)}`};if(e==="merged"&&t.grants.merge===!1)return{endpoint:"green",reason:n("merge")};return{endpoint:e}}function dA(e,t){let{raw:n,endpoint:r,issue:o}=lA(e),s=uA(r,t);return{defaultEndpoint:r,configuredEndpoint:n??null,effectiveEndpoint:s.endpoint,...s.reason?{endpointReason:s.reason}:{},...o?{endpointIssue:o}:{}}}var pA=["proportional","self","independent"],Xw=["independent","proportional","self"],fA="proportional",gA=(e)=>{let t=e?.verification;return pA.includes(t)?t:fA};var hA=(e)=>e===!0||e===!1||e==="verified",Ou=(e,t)=>t==="verified"&&e!=="merge"?!0:t,mA=(e)=>{if(e===!0)return{push:!0,pr:!0,merge:"verified"};if(!Array.isArray(e))return null;let t={};for(let n of e)if(n==="push"||n==="pr")t[n]=!0;else if(n==="merge")t.merge="verified";return Object.keys(t).length>0?t:null};function kA(e){let t=e??{},n=t.autonomy;if(n&&typeof n==="object"&&!Array.isArray(n)){let o={};for(let s of Eu){let i=n[s];if(hA(i))o[s]=Ou(s,i)}return{grants:o,source:"autonomy"}}let r=mA(t.autoApprove);return r?{grants:r,source:"autoApprove"}:{grants:{},source:"default"}}function Tu(e){let{grants:t,source:n}=kA(e),r={...iA,...t},o=Eu.filter((a)=>t[a]!==void 0),s=Boolean(e?.vcs?.account),i=e?.name??null;return{workspace:i,grants:r,configured:o,source:n,accountConfigured:s,...dA(e,{workspace:i,grants:r,configured:o,accountConfigured:s}),verification:gA(e)}}function Yw(e,t,n,r,o=!1){let s=null,i="";try{if(t instanceof Error)throw t;s=Tu(ic(t,Ti()))}catch(m){i=m.message}if(!o&&s?.workspace===e.workspace)return e;let a=!s||s.configured.length>0&&!s.accountConfigured,c={...e.grants},l={...e.unblocks},u=[];for(let m of Eu){let k=!a&&s.grants[m];if(!bA(m,k,c[m]))continue;c[m]=k,l[m]=s?a?ev(s.workspace):tv(s.workspace,m):`ask the user to fix: ${i}`,u.push(m)}let d=!a&&s.effectiveEndpoint||Oi,p=cA(d,e.effectiveEndpoint);if(p)u.push("defaultEndpoint");let h=s?.verification??"independent",f=Xw.indexOf(e.verification)>Xw.indexOf(h);if(f)u.push("verification");if(u.length===0)return e;let g=`${n}: ${u.join(", ")} capped at ${s?`workspace ${s.workspace}`:`nothing (${i})`}; ${r}`;return{...e,grants:c,unblocks:l,...p?{effectiveEndpoint:d,endpointReason:void 0}:{},verification:f?h:e.verification,note:e.note?`${e.note}; ${g}`:g}}function Qw(e){let t=sA();if(t)return{...Tu(null),note:t};let n=process.env.WORKFLOW_WORKSPACE_NAME?.trim()||void 0,r=Tu(ic(e,Ti(),n));if(n)r=Yw(r,e,`WORKFLOW_WORKSPACE_NAME=${n}`,"a name never raises grants");let o=sc(e);for(let s of o instanceof Error?[o]:o)r=Yw(r,s,s instanceof Error?"git":`checkout ${s}`,"a worktree or submodule never exceeds it",!0);return r}var yA=(e)=>e==="merge"?"verified":"true",ev=(e)=>`set vcs.account for workspace "${e??"?"}" in ~/.config/workit/workspaces.json`,tv=(e,t)=>`ask the user to run, in their own terminal: workit grant set ${e??"<workspace>"} ${t}=${yA(t)}`;var bA=(e,t,n)=>{let r=(o)=>o===!0?2:o==="verified"?1:0;return r(Ou(e,n))>r(Ou(e,t))};function nv(e){try{let t=new sn(e),n=t.listTaskIndex(),r=t.currentKey();if(!n.ok||!r.ok)return null;let o=n.data.filter((i)=>i.key===r.data.key&&i.status!=="closed").toSorted((i,a)=>a.updatedAt.localeCompare(i.updatedAt))[0],s=o?t.readTask(o.id):null;return s?.ok===!0?On(s.data):null}catch{return null}}var uo={kind:"none"},vA=/[??؟](?=[\s*_`"')\]>]*(?:\s|$))|¿/,SA=/\b(?:let me know|want me to|should I|shall I|would you like|do you want|if you(?:'d| would) like|may I|can I go ahead)\b/i,xA=/[[(]\s*y(?:es)?\s*\/\s*n(?:o)?\s*[\])]/i,_A=/^\s*(?:[-*+•]|\d+[.)]|[a-z][.)])\s+/i,ov=(e)=>{if(!e)return!1;let t=e.replace(/```[\s\S]*?(?:```|$)/g,`
213
+ `}else if(r==="/"&&e[n+1]==="*"){let o=e.indexOf("*/",n+2);if(o<0)throw Error("unterminated comment");n=o+1}else t+=r}return JSON.parse(t.replace(/,(\s*[}\]])/gu,"$1"))}function En(e){for(let t=le.resolve(e);;t=le.dirname(t)){if(lu.existsSync(le.join(t,".git")))return t;if(le.dirname(t)===t)return null}}var W0=(e)=>{let t=En(e),n=[];for(let r=le.resolve(e);;r=le.dirname(r))if(n.push(r),!t||r===t||le.dirname(r)===r)return n},yi=(e)=>e.HOME||B0.homedir(),aw={linux:"/etc/claude-code/managed-settings.json",darwin:"/Library/Application Support/ClaudeCode/managed-settings.json",win32:"C:\\Program Files\\ClaudeCode\\managed-settings.json"};function H0(e,t,n=process.platform){let r=t.CLAUDE_PROJECT_DIR||En(e)||e,o=t.CLAUDE_CONFIG_DIR||le.join(yi(t),".claude");return[...aw[n]?[aw[n]]:[],le.join(o,"settings.json"),le.join(r,".claude","settings.json"),le.join(r,".claude","settings.local.json")]}var Z0=(e)=>{let t=/^Bash(?:\((.*)\))?$/su.exec(e.trim());return t?t[1]??"":null};function dw(e,t=process.env){let n=mi();try{for(let r of H0(e,t)){let o=ki(r);if(o===null)continue;let s=JSON.parse(o);if(!Wt(s))return"unreadable";let i=s.permissions;if(i===void 0)continue;if(!Wt(i))return"unreadable";for(let[a,c]of[["deny",n.deny],["ask",n.deny],["allow",n.allow]]){let l=i[a];if(l===void 0)continue;if(!Array.isArray(l))return"unreadable";for(let u of l){if(typeof u!=="string")return"unreadable";let d=Z0(u);if(d!==null)c.push(d)}}}}catch{return"unreadable"}return n}var cw=["opencode.json","opencode.jsonc"],lw=(e,t)=>{if(e===void 0)return!0;if(typeof e==="string")return(e==="allow"?t.allow:t.deny).push(""),["allow","ask","deny"].includes(e);if(!Wt(e))return!1;for(let n of["bash","shell"]){let r=e[n];if(r===void 0)continue;if(typeof r==="string"){if(!["allow","ask","deny"].includes(r))return!1;(r==="allow"?t.allow:t.deny).push("");continue}if(!Wt(r))return!1;for(let[o,s]of Object.entries(r)){if(s!=="allow"&&s!=="ask"&&s!=="deny")return!1;(s==="allow"?t.allow:t.deny).push(o)}}return!0},uw=(e,t)=>{if(!Wt(e))return!1;if(!lw(e.permission,t))return!1;if(e.agent===void 0)return!0;if(!Wt(e.agent))return!1;return Object.values(e.agent).every((n)=>Wt(n)&&lw(n.permission,t))};function pw(e,t=process.env){let n=mi();try{let r=t.XDG_CONFIG_HOME||le.join(yi(t),".config"),o=[...cw.map((s)=>le.join(r,"opencode",s)),...W0(e).flatMap((s)=>cw.flatMap((i)=>[le.join(s,i),le.join(s,".opencode",i)])),...t.OPENCODE_CONFIG?[t.OPENCODE_CONFIG]:[]];for(let s of o){let i=ki(s);if(i!==null&&!uw(iw(i),n))return"unreadable"}if(t.OPENCODE_CONFIG_CONTENT&&!uw(iw(t.OPENCODE_CONFIG_CONTENT),n))return"unreadable"}catch{return"unreadable"}return n}var U0=(e)=>{let t=/\bpattern\s*=\s*\[/u.exec(e);if(!t)return null;let n=[],r=t.index+t[0].length;for(;;){while(/[\s,]/u.test(e[r]??""))r+=1;if(e[r]==="]")break;if(e[r]!=='"')return null;let s=/"((?:[^"\\]|\\.)*)"/y;s.lastIndex=r;let i=s.exec(e);if(!i)return null;n.push(JSON.parse(`"${i[1]}"`)),r=s.lastIndex}let o=/\bdecision\s*=\s*"(\w+)"/u.exec(e)?.[1];if(!n.length||!o||!["allow","prompt","forbidden"].includes(o))return null;return{pattern:n.join(" "),decision:o}};function fw(e,t=process.env){let n=mi();try{let r=t.CODEX_HOME||le.join(yi(t),".codex"),o=En(e)??e;for(let s of[le.join(r,"rules"),le.join(o,".codex","rules")]){let i;try{i=lu.readdirSync(s).filter((a)=>a.endsWith(".rules"))}catch(a){if(a.code==="ENOENT")continue;return"unreadable"}for(let a of i){let c=ki(le.join(s,a))??"";for(let l of c.split(/\bprefix_rule\s*\(/u).slice(1)){let u=U0(l);if(!u)return"unreadable";(u.decision==="allow"?n.allow:n.deny).push(u.pattern)}}}}catch{return"unreadable"}return n}function gw(e,t=process.env){let n=mi();try{let r=En(e)??e;for(let o of[le.join(yi(t),".cursor","cli-config.json"),le.join(r,".cursor","cli.json")]){let s=ki(o);if(s===null)continue;let i=JSON.parse(s);if(!Wt(i))return"unreadable";if(i.permissions===void 0)continue;if(!Wt(i.permissions))return"unreadable";for(let[a,c]of[["deny",n.deny],["allow",n.allow]]){let l=i.permissions[a];if(l===void 0)continue;if(!Array.isArray(l))return"unreadable";for(let u of l){if(typeof u!=="string")return"unreadable";let d=/^Shell(?:\((.*)\))?$/su.exec(u.trim());if(d)c.push(d[1]??"")}}}}catch{return"unreadable"}return n}var cu=(e)=>(e.split(/[\\/]/u).at(-1)??"").toLowerCase().replace(/\.(?:exe|cmd|bat)$/u,""),hw=(e)=>e.trim().split(/[:\s]/u)[0]??"";function K0(e,t){let n=hw(e);if(!n||n==="*"||n.includes("*"))return!0;let r=cu(n);return t.some((o)=>cu(o)===r)}var mw=(e)=>e.trim().replace(/(?::\*| \*|\*)$/u,""),G0=(e)=>{let t=hw(e);if(!t||t.includes("*"))return!0;let n=mw(e).split(/\s+/u);if(cu(n[0])!=="workit")return!1;return["check","--heavy"].slice(0,n.length-1).every((r,o)=>{let s=n[o+1];return s===r||r.startsWith(s)})},J0=(e,t)=>{let n=mw(e);if(!n)return!0;return!n.includes("*")&&t.trim().startsWith(n)};function kw(e,t,n,r={}){if(e==="unreadable")return{ok:!1,why:"named"};if(e.deny.some((o)=>K0(o,t)))return{ok:!1,why:"named"};if(!r.bypass&&e.allow.some(G0)&&!e.allow.some((o)=>J0(o,n)))return{ok:!1,why:"allowlisted"};return{ok:!0}}import uu from"node:fs";import q0 from"node:os";import Ht from"node:path";function V0(e,t=process.platform){if(e.WORKFLOW_TOOLKIT_STATE)return e.WORKFLOW_TOOLKIT_STATE;if(e.XDG_STATE_HOME)return Ht.join(e.XDG_STATE_HOME,"workit");let n=e.HOME||q0.homedir();if(t==="darwin")return Ht.join(n,"Library","Application Support","workit");if(t==="win32")return Ht.join(e.LOCALAPPDATA??Ht.join(n,"AppData","Local"),"workit");return Ht.join(n,".local","state","workit")}var X0="heavy-commands.json",Y0=(e)=>Ht.join(V0(e),X0),pn=/^(?:test|tests|t|tst|unit|integration|e2e|coverage|cov|lint|eslint|typecheck|type-check|types|tsc|check|verify|validate|build|compile|bundle|ci|sonar|cypress|playwright|jest|vitest|mocha|bench|benchmark|all)(?:$|[:_.-])/iu,Q0=new Set(["--version","-v","-V","--help","-h","help","version"]),eC=/^(?:--watch(?:All)?(?:=.*)?|-w|--serve)$/u,cr=/(?:^|[:_.-])(?:watch|dev|serve|start|storybook)(?:$|[:_.-])/iu,W=(...e)=>new Set(e),tC={jest:"any",vitest:"any",mocha:"any",ava:"any",tap:"any",karma:"any",jasmine:"any",nyc:"any",c8:"any",tsc:"any","vue-tsc":"any","svelte-check":"any",eslint:"any",stylelint:"any",tslint:"any",webpack:"any","webpack-cli":"any",rollup:"any",parcel:"any",tsup:"any",vite:W("build","optimize"),next:W("build","lint"),nuxt:W("build","generate"),nuxi:W("build","generate"),astro:W("build","check"),ng:W("build","b","test","t","e2e","lint"),"react-scripts":W("build","test"),playwright:W("test","install"),cypress:W("run"),wdio:"any",testcafe:"any",turbo:"any",lerna:W("run","exec","bootstrap"),"sonar-scanner":"any",sonarless:W("scan"),"sonarless-mcp":W("scan"),go:W("test","build","vet","install","generate"),"golangci-lint":W("run"),gotestsum:"any",staticcheck:"any",cargo:W("build","b","test","t","check","c","clippy","bench","nextest","doc","install","tarpaulin","llvm-cov"),mvn:"any",mvnw:"any",gradle:"any",gradlew:"any",ant:"any",sbt:"any",bazel:W("build","test","run","coverage"),bazelisk:W("build","test","run","coverage"),buck2:W("build","test","run"),dotnet:W("build","test","publish","restore","pack","msbuild"),msbuild:"any",pytest:"any","py.test":"any",tox:"any",nox:"any",mypy:"any",pyright:"any",pylint:"any",coverage:W("run"),maturin:W("build","develop"),pip:W("install","wheel"),pip3:W("install","wheel"),rspec:"any",rails:W("test","assets:precompile"),phpunit:"any",pest:"any",phpstan:"any",psalm:"any",composer:W("install","update","require","test"),mix:W("test","compile","deps.get","dialyzer","credo"),swift:W("build","test"),xcodebuild:"any",flutter:W("build","test"),dart:W("test","compile"),pod:W("install"),cmake:W("--build"),ninja:"any",meson:W("compile","test"),ctest:"any",scons:"any","docker-compose":W("build"),buildah:W("bud","build"),earthly:"any"},nC=new Set(["--prefix","-w","--workspace","-C","--dir","--filter","-F","--cwd","-p","--package","--cache","--registry"]);function He(e,t,n=nC){let r=t;while(r<e.length&&e[r].startsWith("-")){if(e[r]==="--")return r+1;r+=n.has(e[r])?2:1}return r}var du=(e)=>(e?.split(/[\\/]/u).at(-1)??"").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u,""),bw=/^(?:workit|@brainervirus\/workit-cli(?:@.*)?)$/u,rC=/^(?:python[\d.]*|py)$/u,oC=new Set(["ci","clean-install","cit","install-test","it","install","i","in","add","rebuild","update","up"]),sC=new Set(["run","run-script","rum","urn"]),iC=new Set(["test","t","tst"]),aC=new Set(["exec","x","dlx"]);function ww(e,t=0){if(t>6||!e.length)return null;let n=du(e[0]),r=()=>e.slice(0,3).join(" "),o=(a)=>ww(e.slice(a),t+1);if(bw.test(n))return null;if(Q0.has(e[1]??"")&&e.length===2)return null;if(e.some((a)=>a==="--watch"||a.startsWith("--watch=")||a==="--watchAll"))return null;if(n==="npx"||n==="bunx"||n==="pnpx")return o(He(e,1));if(n==="corepack")return o(1);if(n==="npm"||n==="pnpm"||n==="yarn"||n==="bun"||n==="deno"){let a=He(e,1),c=e[a];if(c===void 0)return n==="yarn"?"yarn (install)":null;if(n==="deno"){if(["test","bench","check","compile","lint"].includes(c))return r();if(c==="task"&&pn.test(e[a+1]??""))return r();return null}if(oC.has(c)||iC.has(c))return r();if(n==="bun"&&c==="build")return r();if(aC.has(c))return o(He(e,a+1));if(n==="yarn"&&c==="workspace")return o(a+2);if(n==="yarn"&&c==="workspaces")return e.slice(a+1).some((l)=>pn.test(l))?r():null;if(sC.has(c)){let l=e[He(e,a+1)];if(l===void 0||cr.test(l))return null;if(pn.test(l))return r();return n==="bun"?o(He(e,a+1)):null}if(n==="npm")return null;if(cr.test(c))return null;if(pn.test(c)&&!/\.[cm]?[jt]sx?$/u.test(c))return r();return o(a)}if(rC.test(n)){let a=e.indexOf("-m");return a>0&&e[a+1]?o(a+1):null}if(["uv","poetry","pdm","pipenv","hatch","rye"].includes(n)){let a=He(e,1),c=e[a];if(c==="run")return o(He(e,a+1));if(c==="pip")return o(a);return["sync","install","build","test","add"].includes(c??"")?r():null}if(n==="bundle"){let a=e[He(e,1)];if(a==="exec")return o(He(e,2));return a==="install"||a===void 0?r():null}if(n==="make"||n==="gmake"){let a=e.slice(1).filter((c)=>!c.startsWith("-")&&!c.includes("="));if(a.some((c)=>cr.test(c)))return null;return!a.length||a.some((c)=>pn.test(c))?r():null}if(n==="rake")return e.slice(1).filter((c)=>!c.startsWith("-")&&!c.includes("=")).some((c)=>pn.test(c)||/^spec(?:$|:)/u.test(c))?r():null;if(n==="nx"){let a=He(e,1),c=e[a]??"";if(["run-many","affected"].includes(c))return e.some((l)=>/^(?:-t|--targets?)(?:=|$)/u.test(l))&&!e.some((l)=>cr.test(l.replace(/^--?targets?=/u,"")))?r():null;if(c==="run"){let l=(e[a+1]??"").split(":")[1]??"";return pn.test(l)&&!cr.test(l)?r():null}return pn.test(c)&&!cr.test(c)?r():null}if(n==="docker"||n==="podman"||n==="nerdctl"){let a=He(e,1,new Set(["-H","--host","--context","-c","--config"])),c=e[a];if(c==="build")return r();if(c==="buildx"||c==="image"||c==="builder")return e[He(e,a+1)]==="build"?r():null;if(c==="compose"){let l=He(e,a+1,new Set(["-f","--file","-p"])),u=e[l];if(u==="build")return r();return u==="up"&&e.slice(l+1).includes("--build")?r():null}return null}let s=tC[n];if(!s)return null;if(e.slice(1).some((a)=>eC.test(a)||a==="watch"||a==="dev"))return null;if(s==="any")return r();let i=e.slice(1).find((a)=>!a.startsWith("-")&&!a.startsWith("+")||s.has(a));return i!==void 0&&s.has(i)?r():null}var cC=(e)=>new RegExp(`^${e.replace(/[.+?^${}()|[\]\\]/gu,"\\$&").replaceAll("*",".*")}$`,"u");function lC(e){let t=e.trim().split(/\s+/u).filter(Boolean);return t.length?t.map(cC):null}var uC=(e,t)=>e.length<=t.length&&e.every((n,r)=>r===0?n.test(t[0])||n.test(du(t[0])):n.test(t[r])),dC=(e)=>{try{return JSON.parse(uu.readFileSync(e,"utf8"))}catch{return}},pC=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),fC=(e)=>Array.isArray(e)?e.filter((t)=>typeof t==="string"):[];function gC(e){let t=dC(Y0(e));return pC(t)?fC(t.patterns):[]}function hC(e){return $s(En(e)??Ht.resolve(e))}function yw(e,t){let n=[],r=null;for(let o of e){let s=ww(o);if(s){n.push({line:o,source:"catalog",reason:s});continue}r??=(t.patterns??[...gC(t.env??process.env).map((a)=>({pattern:a,from:"machine"})),...hC(t.cwd).map((a)=>({pattern:a,from:"repo"}))]).flatMap((a)=>{let c=lC(a.pattern);return c?[{...a,matchers:c}]:[]});let i=r.find((a)=>uC(a.matchers,o));if(i)n.push({line:o,source:{pattern:i.pattern,from:i.from},reason:`${i.from} pattern "${i.pattern}"`})}return n}var mC=(e,t)=>{try{return Mb(e,t)}catch{return null}};var kC=(e)=>/^[\w@%+=:,./-]+$/u.test(e)?e:`'${e.replaceAll("'","'\\''")}'`,yC=(e)=>`workit check --heavy -- ${e.map(kC).join(" ")}`;function vw(e,t){let n=t.dialect??"posix";if(n!=="posix"||!En(t.cwd))return{kind:"none"};let r=mC(e,n);if(!r)return{kind:"none"};let o=yw(r,t);if(!o.length)return{kind:"none"};let s=ai(e,n,0,!0),i=s&&!bw.test(du(s[0]))&&yw([s],t)[0],a=i?[{words:r.flat(),text:e}]:o.map((l)=>({words:l.line,text:l.line.join(" ")}));if(t.rules!==null){for(let{words:l,text:u}of a)if(!kw(t.rules,l,u,{bypass:t.bypass}).ok)return{kind:"passthrough",note:""}}if(i){let l=wC(e);return l?{kind:"rewrite",command:l,reason:i.reason}:{kind:"none"}}let c=o.map((l)=>yC(l.line));return{kind:"split",reason:`heavy_command: \`${e.trim()}\` chains heavy work (${o.map((l)=>l.reason).join("; ")}) with other commands, and a chain cannot run under the machine-wide heavy-check lease. Run the heavy part alone, now: \`${c[0]}\`; then run the other parts as their own commands${c.length>1?", each heavy one the same way":""}.`,unblock:c[0]??null}}function Sw(e=process.env){let t=process.platform==="win32"?["workit.exe","workit.cmd","workit"]:["workit"];for(let n of(e.PATH??"").split(Ht.delimiter))for(let r of t){if(!n)continue;try{return uu.accessSync(Ht.join(n,r),uu.constants.X_OK),!0}catch{}}return!1}var bC=/^\s*((?:[A-Za-z_]\w*=(?:'[^']*'|"(?:[^"\\]|\\.)*"|[^\s'"])*\s+)*)/u;function wC(e){let t=e.trim(),n=bC.exec(t)?.[1]??"",r=t.slice(n.length).trim();if(!r)return null;return`${n}workit check --heavy -- ${r}`}import xw from"node:fs";import vC from"node:os";import Rt from"node:path";var SC=new Set("npm npx pnpm pnpx yarn bun bunx deno corepack make gmake docker podman nerdctl python python3 py uv poetry pdm pipenv hatch rye bundle rake nx jest vitest mocha ava tap karma jasmine nyc c8 tsc vue-tsc svelte-check eslint stylelint tslint webpack webpack-cli rollup parcel tsup vite next nuxt nuxi astro ng react-scripts playwright cypress wdio testcafe turbo lerna sonar-scanner sonarless sonarless-mcp go golangci-lint gotestsum staticcheck cargo mvn mvnw gradle gradlew ant sbt bazel bazelisk buck2 dotnet msbuild pytest py.test tox nox mypy pyright pylint coverage maturin pip pip3 rspec rails phpunit pest phpstan psalm composer mix swift xcodebuild flutter dart pod cmake ninja meson ctest scons docker-compose buildah earthly".split(" ")),_w=(e)=>e.split(/[\s;&|()<>`'"]+/u).map((t)=>(t.split(/[\\/]/u).at(-1)??"").toLowerCase().replace(/\.(?:exe|cmd|bat)$/u,"")).filter(Boolean),pu=(e)=>{if(e.WORKFLOW_TOOLKIT_STATE)return e.WORKFLOW_TOOLKIT_STATE;if(e.XDG_STATE_HOME)return Rt.join(e.XDG_STATE_HOME,"workit");let t=e.HOME||vC.homedir();if(process.platform==="darwin")return Rt.join(t,"Library","Application Support","workit");if(process.platform==="win32")return Rt.join(e.LOCALAPPDATA??Rt.join(t,"AppData","Local"),"workit");return Rt.join(t,".local","state","workit")},xC=(e)=>{try{return JSON.parse(xw.readFileSync(e,"utf8"))}catch{return}},_C=(e,t)=>{let n=[],r=xC(Rt.join(pu(t),"heavy-commands.json"));if(Array.isArray(r?.patterns))n.push(...r.patterns);for(let s=Rt.resolve(e);;s=Rt.dirname(s)){if(xw.existsSync(Rt.join(s,".git"))){n.push(...$s(s));break}if(Rt.dirname(s)===s)break}let o=new Set;for(let s of n){if(typeof s!=="string")continue;let i=_w(s)[0];if(!i||i.includes("*"))return null;o.add(i)}return o};function Rw(e,t,n=process.env){try{let r=_w(e);if(r.some((s)=>SC.has(s)||/^python[\d.]*$/u.test(s)))return!0;let o=_C(t,n);return o===null||r.some((s)=>o.has(s))}catch{return!0}}var RC=(e,t,n)=>{switch(e){case"claude_code":return dw(t,n);case"opencode":return pw(t,n);case"codex_cli":case"codex_desktop":return fw(t,n);case"cursor":return gw(t,n);case"pi":return null}};function fu(e,t,n){let r=n.env??process.env;try{if(r.WORKIT_HEAVY_GATE==="0"||!Rw(t,e,r)||!Sw(r))return{kind:"none"};return vw(t,{cwd:e,env:r,dialect:n.dialect??"posix",rules:RC(n.host,e,r),bypass:n.permissionMode==="bypassPermissions"})}catch{return{kind:"none"}}}var $w=(e)=>`workit: this heavy command (${e.reason}) runs under the machine-wide heavy-check lease as \`${e.command}\`: it waits while another heavy check holds the lease (\`workit lock status\` shows who). Run heavy commands that way yourself; \`workit help lock\` explains the lease.`,gu=(e,t)=>({kind:"deny",reason:`heavy_command: \`${e.trim()}\` is heavy (${t.reason}) and must run under the machine-wide heavy-check lease, so parallel agents cannot exhaust this machine's memory and CPU. Run exactly: ${t.command}`,unblock:t.command}),hu=(e)=>({kind:"deny",reason:e.reason,unblock:e.unblock});import{existsSync as NC,realpathSync as DC}from"node:fs";import jw from"node:os";import Z from"node:path";import{spawnSync as $C}from"node:child_process";import{createHash as IC}from"node:crypto";import pt from"node:fs";import ku from"node:os";import $t from"node:path";var OC=900000,TC=30000,Cn={platform:process.platform,run:(e)=>$C("ps",e,{encoding:"utf8",timeout:2000}).stdout??"",start:(e)=>Wr(e)},mu=(e)=>e.split(":")[0].replace(/-w-.*$/su,"")||e,Iw=(e)=>e.replace(/_(?:cli|desktop)$/u,""),EC=(e)=>{try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}},CC=(e)=>{try{if(Cn.platform==="linux"){let n=pt.readFileSync(`/proc/${e}/stat`,"utf8"),r=Number(n.slice(n.lastIndexOf(")")+2).split(" ")[1]),o=pt.readFileSync(`/proc/${e}/cmdline`,"utf8").replaceAll("\x00"," ");return Number.isInteger(r)?{ppid:r,command:o.trim()}:null}if(Cn.platform==="win32")return null;let t=/^\s*(\d+)\s+(.*)$/su.exec(Cn.run(["-o","ppid=,command=","-p",String(e)]));return t?{ppid:Number(t[1]),command:t[2].trim()}:null}catch{return null}},AC=/^(?:\S*\/)?(?:sh|bash|dash|zsh|ash|ksh|fish|env|timeout|npx|npm|bunx|cmd\.exe|pwsh|powershell)(?:\s|$)|launch\.mjs|npx-cli\.js/u,bi=new Map,PC=(e)=>{if(e!=="hook-process")return process.pid;let t=`${Cn.platform}\x00${process.ppid}`;if(bi.has(t))return bi.get(t)??null;if(Cn.platform==="win32")return bi.set(t,null),null;let n=process.ppid;for(let r=0;r<4;r++){let o=CC(n);if(!o||!AC.test(o.command)||o.ppid<=1)break;n=o.ppid}return bi.set(t,n),n},wi=(e)=>e.replace(/[^A-Za-z0-9_.:@/+-]/gu,"-"),Si=(e,t,n=process.env)=>{let r=e.session.id?.trim();if(!r)return null;let o=new Set([mu(wi(r))]);if(e.session.parentId)o.add(mu(wi(e.session.parentId)));if(n.WORKIT_PI_WORKER_SESSION&&n.WORKIT_SESSION_ID)o.add(mu(wi(n.WORKIT_SESSION_ID)));return{host:e.host,session:wi(r),leads:[...o],pid:()=>PC(t)}},Ow=(e)=>{let t=$t.resolve(e);while(!pt.existsSync(t)&&$t.dirname(t)!==t)t=$t.dirname(t);if(pt.existsSync(t)&&!pt.statSync(t).isDirectory())t=$t.dirname(t);let n=t.split($t.sep),r=n.lastIndexOf(".git");if(r>0)t=n.slice(0,r).join($t.sep)||$t.sep;let o=we(t);if(o instanceof Error||!o.shared||!o.top)return null;let s=o.top;try{s=pt.realpathSync.native(s)}catch{}return s},Tw=(e)=>$t.join(Ae(),"live-sessions",`${IC("sha256").update(zC(e)).digest("hex").slice(0,32)}.json`),zC=(e,t=process.platform)=>{let n=$t.resolve(e);try{n=pt.realpathSync.native(n)}catch{}return t==="win32"?n.replaceAll("/","\\").toLowerCase():n},Ew=(e)=>{try{let t=JSON.parse(pt.readFileSync(e,"utf8"));if(t?.version!==1||typeof t.session!=="string"||typeof t.host!=="string"||typeof t.heartbeatAt!=="string"||Number.isNaN(Date.parse(t.heartbeatAt)))return null;return{version:1,session:t.session,leads:Array.isArray(t.leads)?t.leads.filter((n)=>typeof n==="string"):[],host:t.host,pid:typeof t.pid==="number"?t.pid:null,pidStart:typeof t.pidStart==="string"?t.pidStart:null,machine:typeof t.machine==="string"?t.machine:"",checkout:typeof t.checkout==="string"?t.checkout:"",heartbeatAt:t.heartbeatAt}}catch{return null}},yu=(e,t)=>t.getTime()-Date.parse(e.heartbeatAt),Cw=(e,t)=>{if(yu(e,t.now??new Date)>(t.ttlMs??OC))return!1;if(e.machine!==(t.machine??ku.hostname())||e.pid===null)return!0;if(!(t.alive??EC)(e.pid))return!1;if(e.pidStart===null)return!0;let r=Cn.start(e.pid);return r===null||r===e.pidStart},vi=(e,t)=>e.session===t.session||t.leads.some((n)=>n===e.session||e.leads.includes(n)),Aw=(e,t,n)=>{if(vi(e,t))return!0;if(e.machine!==n)return!1;let r=t.pid();if(r===null||e.pid===null||e.pidStart===null)return Iw(e.host)===Iw(t.host);return e.pid===r},Pw=(e,t,n={})=>{try{let r=Ow(e);if(!r)return null;let o=Tw(r),s=Ew(o);if(!s||vi(s,t)||!Cw(s,n))return null;if(Aw(s,t,n.machine??ku.hostname()))return null;return{marker:s,file:o,ageMs:yu(s,n.now??new Date),checkout:r}}catch{return null}},zw=(e,t,n={})=>{try{let r=Ow(e);if(!r)return;let o=Tw(r),s=n.now??new Date,i=n.machine??ku.hostname(),a=Ew(o);if(a){let d=yu(a,s);if(vi(a,t)&&d>=0&&d<TC)return;if(!vi(a,t)&&Cw(a,n)&&!Aw(a,t,i))return}let c=t.pid(),l={version:1,session:t.session,leads:t.leads,host:t.host,pid:c,pidStart:c===null?null:Cn.start(c),machine:i,checkout:r,heartbeatAt:s.toISOString()};pt.mkdirSync($t.dirname(o),{recursive:!0});let u=`${o}.${process.pid}.tmp`;pt.writeFileSync(u,JSON.stringify(l)),pt.renameSync(u,o)}catch{}};var ao={kind:"none"},LC=process.platform==="darwin"||process.platform==="win32",bu=(e)=>{let t="";for(let n=Z.resolve(e);;n=Z.dirname(n))try{return Z.join(DC.native(n),t)}catch{if(Z.dirname(n)===n)return Z.resolve(e);t=t?Z.join(Z.basename(n),t):Z.basename(n)}},jC=(e,t,n,r)=>{let o=(c)=>LC?c.toLowerCase():c,s=Z.relative(o(bu(t)),o(bu(Z.resolve(e,n))));if(s.startsWith("..")||Z.isAbsolute(s))return!0;let i=s.split(Z.sep).join("/"),a=i.split("/");return/\.mdx?$/i.test(i)||a[0]==="docs"||a.includes("plans")||[...r].some((c)=>o(c)===i)},_i=new Set(["sudo","command","env","nohup","time","exec","xargs","busybox"]),An=(e)=>e.filter((t)=>!t.startsWith("-")),Mw=new Set(["sh","bash","zsh","dash","ksh"]),Fw=(e)=>{let t=e;while(t.length&&(_i.has(t[0])||/^\w+=/.test(t[0])))t=t.slice(1);let n=Xl(t);if(!n)return null;if("script"in n)return n.script;let r=Su(n.argv);if(Mw.has((n.argv[0]?.split(/[\\/]/).at(-1)??"").toLowerCase())&&r)return r;return n.argv.map(xu).join(" ")},vu=(e)=>{let t=e;while(t.length&&(_i.has(t[0])||/^\w+=/.test(t[0])))t=t.slice(1);let[n,...r]=t,o=(n?.split(/[\\/]/).at(-1)??"").toLowerCase();if(!o||o==="workit"||o==="npx"&&r.some((s)=>/workit/.test(s)))return[];switch(o){case"touch":case"mkdir":case"rm":case"rmdir":case"tee":case"mv":case"truncate":return An(r);case"cp":case"ln":case"install":{let s=r.indexOf("-t");if(s>=0)return r[s+1]?[r[s+1]]:null;let i=An(r).at(-1);return i?[i]:null}case"dd":return r.filter((s)=>s.startsWith("of=")).map((s)=>s.slice(3));case"sed":case"perl":{if(!r.some((a)=>/^-[a-zA-Z]*i|^--in-place/.test(a)))return[];let s=r.some((a)=>a==="-e"||a==="-f"),i=[];for(let a=0;a<r.length;a++)if(r[a]==="-e"||r[a]==="-f")a++;else if(!r[a].startsWith("-"))i.push(r[a]);return s?i:i.slice(1)}case"patch":return null;case"set-content":case"add-content":case"out-file":case"new-item":case"ni":case"remove-item":case"del":case"copy-item":case"move-item":{let s=r.findIndex((c)=>/^-(?:path|filepath|literalpath|destination)$/i.test(c));if(s>=0)return r[s+1]?[r[s+1]]:null;let i=An(r);if(o==="move-item")return i.length?i:null;let a=o==="copy-item"?i.at(-1):i[0];return a?[a]:null}case"git":{let s=An(r)[0];if(s==="apply")return null;if(s==="restore"||s==="mv"||s==="rm")return An(r).slice(1);if(s==="checkout"&&r.includes("--"))return r.slice(r.indexOf("--")+1);return[]}default:return[]}},Su=(e)=>{if(!Mw.has((e[0]?.split(/[\\/]/).at(-1)??"").toLowerCase()))return null;for(let t=1;t<e.length;t++){let n=e[t];if(/^-[a-z]*c$/.test(n))return e[t+1]??null;if(/^[-+][oO]$/.test(n))t++;else if(!/^[-+]/.test(n))return null}return null},MC=/^-[IinLPdsEa]$/,Nw=(e)=>{let t=[...e.filter((r)=>r!=="{}"&&r!==";"&&r!=="+"),"x"],n=vu(t);return n===null||n.length>0||Bw(t)!==null},Bw=(e)=>{let t=e;while(t.length&&(_i.has(t[0])||/^\w+=/.test(t[0]))){if(t[0]==="xargs"){let c=1;while(t[c]?.startsWith("-"))c+=MC.test(t[c])?2:1;return Nw(t.slice(c))?["."]:null}t=t.slice(1)}let[n,...r]=t,o=(n?.split(/[\\/]/).at(-1)??"").toLowerCase(),s=An(r),i=(c)=>r.some((l)=>c.test(l)),a=(c)=>c.length?c:["."];if(o==="unlink"||o==="shred")return a(s);if(/^(?:chmod|chown|chgrp|chattr)$/.test(o))return a(i(/^--reference/)?s:s.slice(1));if(o==="rsync"){let c=s.at(-1),l=/^[\w.@-]*:/.test(c??"")&&!/^[A-Za-z]:[\\/]/.test(c??"");return c===void 0?["."]:l?[]:[c]}if(o==="find"){let c=r.findIndex((d)=>/^-(?:exec|execdir|ok|okdir)$/.test(d)),l=i(/^-(?:delete|fprint\w*|fls)$/)||c>=0&&Nw(r.slice(c+1)),u=r.findIndex((d)=>/^[-(!]/.test(d));return l?a(u<0?r:r.slice(0,u)):null}if(/^g?awk$/.test(o)){if(!i(/^-i|^--include/))return null;let c=[],l=!i(/^-f$|^--file/);for(let u=0;u<r.length;u++)if(/^(?:-[ifvF]|--(?:include|file|assign|field-separator))$/.test(r[u]))u++;else if(r[u].startsWith("-"))continue;else if(l)l=!1;else c.push(r[u]);return a(c)}if(o==="perl")return i(/^-[a-zA-Z]*[eE]/)?["."]:null;if(/^(?:python[\d.]*|node|bun|deno|ruby|php)$/.test(o))return i(/^-[a-zA-Z]*[ce]$|^--eval$|^-p$/)?["."]:null;return Su(t)===null?null:["."]},FC=(e,t)=>{let n=An([...e]),r=e.indexOf("-t"),o=r>=0?e[r+1]:n.length>1?n.at(-1):".",s=n.filter((l,u)=>r>=0?l!==o:u<n.length-1||n.length===1),i=o===void 0?null:t(o),a=e.some((l)=>/^-[a-zA-Z]*s|^--symbolic$/.test(l)),c=i===null?null:r>=0||s.length>1||NC(i)||/[\\/]$/.test(o??"")?i:Z.dirname(i);return s.flatMap((l)=>{if(a&&c!==null&&!Z.isAbsolute(lo(l)))return[Z.resolve(c,l)];let u=t(l);return u?[u]:[]})},Ri=(e,t=0)=>{let n=[],r=!1;for(let o of Se(e)){let s=t<4?Fw(o.words):null;if(s!==null){let a=Ri(s,t+1);if(a.writes&&a.targets===null)r=!0;else if(a.targets)n.push(...a.targets)}n.push(...o.redirects.filter((a)=>!/^\/dev\/(?:null|stdout|stderr|tty)$/.test(a)));let i=vu(o.words);if(i===null)r=!0;else n.push(...i)}if(!r&&n.length===0)return{writes:!1,targets:null};return{writes:!0,targets:r?null:n}},io=new Map,Dw=(e,t)=>[...t].map((n)=>on(Z.resolve(e,n))??"-").join("\x00"),BC=(e)=>{let t=new sn(e),n=t.listTaskIndex();if(!n.ok)return null;let r=t.currentKey();if(!r.ok)return null;let o=n.data.filter((h)=>h.key===r.data.key&&h.status!=="closed").toSorted((h,f)=>f.updatedAt.localeCompare(h.updatedAt))[0];if(!o)return{blockers:[],root:t.root,plans:new Set};let s=rr(t.root),i=`${o.id}\x00${o.revision}\x00${s.ok&&on(s.value)||"-"}`,a=io.get(t.root);if(a&&a.key===i&&a.planKey===Dw(t.root,a.plans))return a;let c=t.readTask(o.id);if(!c.ok)return null;let l=t.readWorkspace(),u=new Set((On(c.data)?.refs??[]).flatMap((h)=>h.kind==="file"?[h.path]:[])),p={blockers:My(c.data,t.root).filter((h)=>{let f=c.data.policy?.requirements.find((g)=>g.ruleId===h.ruleId&&g.before==="write");return!(f?.acceptanceAllowed&&l.ok&&l.data&&Vs(c.data,l.data,f,t.root).length>0)}),root:t.root,plans:u,key:i,planKey:Dw(t.root,u)};if(io.set(t.root,p),io.size>32)io.delete(io.keys().next().value);return p},WC=new Set(["add","am","apply","checkout","cherry-pick","clean","commit","merge","mv","pull","rebase","reset","restore","revert","rm","stash","switch"]),HC=new Set(["add","clean","rm","mv"]),ZC=new Set(["commit","branch","stage","unstage"]),co=".workit-live-target",Ww="WORKIT_LIVE_SESSION=override",Hw=(e,t)=>e.some((n)=>n==="--help"||n==="-h"||n==="--dry-run"||HC.has(t)&&/^-[a-zA-Z]*n[a-zA-Z]*$/.test(n)&&!n.startsWith("--")),UC=(e,t,n)=>{let r;try{r=_t(t,n)}catch{return[]}return r.flatMap((o)=>{if(o.tool!=="git"||o.dir===void 0)return[];let s=o.args.findIndex((c)=>!c.startsWith("-")),i=o.args[s]??"",a=o.args.slice(s+1);if(!WC.has(i)||Hw(a,i))return[];if(i==="stash"&&["list","show"].includes(a[0]??""))return[];return[Z.resolve(e,o.dir??".")]})},KC=new Set(["cd","chdir","set-location","sl"]),GC=new Set(["pushd","push-location"]),JC=new Set(["popd","pop-location"]),$i=Z.resolve(Z.parse(process.cwd()).root,".workit-unknown-dir"),Lw=(e,t,n=!1)=>{let r=n?$i:void 0,o=t.slice(1).find((i)=>!i.startsWith("-")||i==="-"),s=o===void 0?void 0:lo(o);if(s==="-"||s&&/^~|[$`*?]/.test(s))return r;if(e===void 0)return r;return s===void 0?jw.homedir():Z.resolve(e,s)},xu=(e)=>/^[\w@%+=:,./-]+$/.test(e)?e:`'${e.replaceAll("'","'\\''")}'`,lo=(e)=>{let t=/^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(e);return t?(process.env.HOME||jw.homedir())+e.slice(t[0].length):e},xi=(e,t,n,r=0,o=!1)=>{let s=[],i=e,a=[],c=[],l=(u)=>{let d=lo(u);return Z.isAbsolute(d)?d:i===void 0?null:Z.resolve(i,d)};for(let u of Se(t,n)){if(u.group==="open"){c.push({dir:i,stack:[...a]});continue}if(u.group==="close"){let m=c.pop();if(m)({dir:i,stack:a}=m);continue}let d=u.words.findIndex((m)=>!/^\w+=/.test(m)),p=d<0?[]:u.words.slice(d),h=(p[0]?.split(/[\\/]/).at(-1)??"").toLowerCase();if(KC.has(h)){i=Lw(i,p,o);continue}if(GC.has(h)){a.push(i),i=Lw(i,p,o);continue}if(JC.has(h)){i=a.length?a.pop():o?$i:void 0;continue}let f=r<4?Fw(p)??(o?Su(p):null):null;if(f!==null&&i!==void 0)s.push(...xi(qC(i,p),f,"posix",r+1,o));if(o&&i!==void 0){let m=i;for(let b of r<4?u.subs??[]:[])s.push(...xi(m,b,n,r+1,!0));let k=u.unanalyzable?["."]:f===null?Bw(p):null;for(let b of k??[]){let v=l(b);if(v)s.push(b==="."?Z.join(v,co):v)}let y=p.findIndex((b)=>/^ln$/i.test(b.split(/[\\/]/).at(-1)??""));if(y>=0&&p.slice(0,y).every((b)=>_i.has(b)))s.push(...FC(p.slice(y+1),l))}for(let m of u.redirects)if(!/^\/dev\/(?:null|stdout|stderr|tty)$/.test(m)){let k=l(m);if(k)s.push(k)}let g=vu(u.words);if(g===null){if(i!==void 0)s.push(Z.join(i,co))}else for(let m of g){let k=l(m);if(k)s.push(k)}if(i!==void 0)for(let m of Bt(u.words.map(xu).join(" "),"posix")){let{at:k,args:y}=Zw(i,m);if(y[0]==="git"&&ZC.has(y[1]??"")&&!Hw(y.slice(2),""))s.push(Z.join(k,co))}}return s},qC=(e,t)=>{for(let n of Bt(t.map(xu).join(" "),"posix")){let{at:r,args:o}=Zw(e,n);if(o[0]==="check"||o[0]==="lock"&&o[1]==="run")return r}return e},Zw=(e,t)=>{let{rest:n,cwd:r}=oo(t);return{at:r===null?e:Z.resolve(e,lo(r)),args:n}},_u=(e,t,n="posix",r=!1)=>{try{return[...xi(e,t,n,0,r),...UC(e,t,n).map((o)=>Z.join(o,co))]}catch{return[]}},VC=(e,t)=>{let n=Se(e,t);if(n.length!==1||n[0].group||n[0].subs?.length)return!1;let r=n[0].words,o=r.findIndex((s)=>!/^\w+=/.test(s));return o>0&&r.slice(0,o).includes(Ww)},XC={claude_code:"Claude Code",opencode:"OpenCode",codex_cli:"Codex CLI",codex_desktop:"Codex Desktop",cursor:"Cursor",pi:"Pi"},YC=(e)=>{let t=Math.max(0,Math.round(e/1000));return t<120?`${t}s`:`${Math.round(t/60)} min`},QC=({marker:e,checkout:t,ageMs:n,file:r})=>{let o=`Work in your own worktree (\`git worktree add <path> -b <branch>\`, or \`workit fanout worktree create <slice>\`). Only if the user confirms that session is finished: release it with \`rm '${r}'\`, or prefix one command with ${Ww}.`;return{kind:"deny",reason:`workit live-session guard: ${t} belongs to another live agent session, ${XC[e.host]??e.host} session ${e.session}${e.pid===null?"":` (pid ${e.pid})`}, last active ${YC(n)} ago. Do not edit a checkout another session is working in; read-only commands stay allowed. ${o}`,unblock:o}},Uw=(e)=>{let t=new Set;return e.filter((n)=>{let r=Z.dirname(n);if(t.has(r))return!1;return t.add(r),!0})},Kw=(e,t,n)=>{try{for(let r of Uw(t)){let o=Pw(r,e,n);if(o&&om(o.checkout))return QC(o)}}catch{}return ao},Gw=(e,t,n)=>{for(let r of Uw(t))zw(r,e,n)},Ru=(e,t)=>t?.length?t.map((n)=>Z.resolve(e,n)):[Z.join(e,co)],Jw=(e,t)=>{let n=Ae();return t.find((o)=>eA(n,e,lo(o),process.platform,bu))??null},eA=(e,t,n,r=process.platform,o=(s)=>s)=>{let s=r==="win32",i=s?Z.win32:Z.posix,a=(u)=>s||r==="darwin"?u.toLowerCase():u,c=s?n.replace(/^\/([a-zA-Z])(?=\/|$)/,"$1:"):n,l=i.relative(a(o(i.resolve(e))),a(o(i.resolve(t,c))));if(l.startsWith("..")||i.isAbsolute(l))return!1;return l.split(i.sep)[0].startsWith("issued")},tA=(e)=>{if(process.platform!=="win32"||!e.includes("\\"))return!1;let t=(n)=>n.replaceAll("\\","/").toLowerCase();return t(e).includes(`${t(Ae())}/issued`)&&Ri(e).writes},qw=(e)=>({kind:"deny",reason:`workit issued-registry guard: ${e} is under Workit's issued-session state. Issued ids and tokens are written only by Workit's SubagentStart hook. Run the verifier or reviewer agent so the host issues its own session; never edit the issued registries by hand.`,unblock:"Issued ids and tokens are written only by Workit's SubagentStart hook. Run the verifier or reviewer agent so the host issues its own session; never edit the issued registries by hand."});function $u(e,t,n,r){let o=t?.length?Jw(e,t):null;if(o)return qw(o);if(!n)return wu(e,t);let s=Ru(e,t),i=Kw(n,s,r);if(i.kind!=="none")return i;let a=wu(e,t);if(a.kind==="none")Gw(n,s,r);return a}function Iu(e,t,n,r="posix",o){try{let c=Jw(e,xi(e,t,r))??(tA(t)?"the issued registry":null);if(c)return qw(c)}catch{}let s=Ri(t),i=[];if(n)i=_u(e,t,r);if(n&&i.length){let c=Kw(n,i,o);if(c.kind!=="none"){if(!VC(t,r))return c;nA(e,n,t)}}let a=s.writes?wu(e,s.targets):ao;if(n&&i.length&&a.kind==="none")Gw(n,i,o);return a}var nA=(e,t,n)=>{try{if(!ot(e))return;ln(e,{type:"live_session.override",actor:{host:t.host,session:t.session,agentId:null},session:t.session,command:n.slice(0,200)})}catch{}};function wu(e,t){try{let n=BC(e);if(!n||n.blockers.length===0)return ao;if(t?.length&&t.every((o)=>jC(e,n.root,o,n.plans)))return ao;return{kind:"deny",reason:`workit before-write gate: ${n.blockers.map((o)=>`${o.ruleId}: ${o.reason}`).join("; ")}. Markdown, docs/, plans/ and files outside the checkout stay writable.`,unblock:n.blockers[0].reason}}catch{return ao}}import{spawnSync as wA}from"node:child_process";import Vw from"node:os";import Ii from"node:path";var rA=()=>{try{return Vw.userInfo().homedir}catch{return Vw.homedir()}},oA={resolve:rA},Ti=()=>Ii.join(oA.resolve(),".config","workit"),sA=()=>{let e=Ii.resolve(qi());return e===Ii.resolve(Ti())?null:`the config directory is redirected to ${e} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${Ii.join(Ti(),"workspaces.json")}, so the D4 defaults apply`},Eu=["push","pr","merge","release","rerun"],iA=Object.freeze({push:!0,pr:!0,merge:!1,release:!1,rerun:!0}),Ei=["commit","pr","green","merged"],Oi="commit",aA=(e)=>typeof e==="string"&&Ei.includes(e),cA=(e,t)=>Ei.indexOf(t)>Ei.indexOf(e);function lA(e){let t=e?.defaultEndpoint;if(t===void 0)return{raw:t,endpoint:Oi};if(aA(t))return{raw:t,endpoint:t};return{raw:t,endpoint:Oi,issue:`defaultEndpoint ${JSON.stringify(t)} is not one of ${Ei.join(", ")}; using ${Oi}`}}function uA(e,t){if(e==="commit")return{endpoint:e};let n=(r)=>`${r} grant missing; ${tv(t.workspace,r)}`;if(t.grants.push===!1)return{endpoint:"commit",reason:n("push")};if(t.grants.pr===!1)return{endpoint:"commit",reason:n("pr")};if(t.configured.length>0&&!t.accountConfigured)return{endpoint:"commit",reason:`vcs.account missing; ${ev(t.workspace)}`};if(e==="merged"&&t.grants.merge===!1)return{endpoint:"green",reason:n("merge")};return{endpoint:e}}function dA(e,t){let{raw:n,endpoint:r,issue:o}=lA(e),s=uA(r,t);return{defaultEndpoint:r,configuredEndpoint:n??null,effectiveEndpoint:s.endpoint,...s.reason?{endpointReason:s.reason}:{},...o?{endpointIssue:o}:{}}}var pA=["proportional","self","independent"],Xw=["independent","proportional","self"],fA="proportional",gA=(e)=>{let t=e?.verification;return pA.includes(t)?t:fA};var hA=(e)=>e===!0||e===!1||e==="verified",Ou=(e,t)=>t==="verified"&&e!=="merge"?!0:t,mA=(e)=>{if(e===!0)return{push:!0,pr:!0,merge:"verified"};if(!Array.isArray(e))return null;let t={};for(let n of e)if(n==="push"||n==="pr")t[n]=!0;else if(n==="merge")t.merge="verified";return Object.keys(t).length>0?t:null};function kA(e){let t=e??{},n=t.autonomy;if(n&&typeof n==="object"&&!Array.isArray(n)){let o={};for(let s of Eu){let i=n[s];if(hA(i))o[s]=Ou(s,i)}return{grants:o,source:"autonomy"}}let r=mA(t.autoApprove);return r?{grants:r,source:"autoApprove"}:{grants:{},source:"default"}}function Tu(e){let{grants:t,source:n}=kA(e),r={...iA,...t},o=Eu.filter((a)=>t[a]!==void 0),s=Boolean(e?.vcs?.account),i=e?.name??null;return{workspace:i,grants:r,configured:o,source:n,accountConfigured:s,...dA(e,{workspace:i,grants:r,configured:o,accountConfigured:s}),verification:gA(e)}}function Yw(e,t,n,r,o=!1){let s=null,i="";try{if(t instanceof Error)throw t;s=Tu(ic(t,Ti()))}catch(m){i=m.message}if(!o&&s?.workspace===e.workspace)return e;let a=!s||s.configured.length>0&&!s.accountConfigured,c={...e.grants},l={...e.unblocks},u=[];for(let m of Eu){let k=!a&&s.grants[m];if(!bA(m,k,c[m]))continue;c[m]=k,l[m]=s?a?ev(s.workspace):tv(s.workspace,m):`ask the user to fix: ${i}`,u.push(m)}let d=!a&&s.effectiveEndpoint||Oi,p=cA(d,e.effectiveEndpoint);if(p)u.push("defaultEndpoint");let h=s?.verification??"independent",f=Xw.indexOf(e.verification)>Xw.indexOf(h);if(f)u.push("verification");if(u.length===0)return e;let g=`${n}: ${u.join(", ")} capped at ${s?`workspace ${s.workspace}`:`nothing (${i})`}; ${r}`;return{...e,grants:c,unblocks:l,...p?{effectiveEndpoint:d,endpointReason:void 0}:{},verification:f?h:e.verification,note:e.note?`${e.note}; ${g}`:g}}function Qw(e){let t=sA();if(t)return{...Tu(null),note:t};let n=process.env.WORKFLOW_WORKSPACE_NAME?.trim()||void 0,r=Tu(ic(e,Ti(),n));if(n)r=Yw(r,e,`WORKFLOW_WORKSPACE_NAME=${n}`,"a name never raises grants");let o=sc(e);for(let s of o instanceof Error?[o]:o)r=Yw(r,s,s instanceof Error?"git":`checkout ${s}`,"a worktree or submodule never exceeds it",!0);return r}var yA=(e)=>e==="merge"?"verified":"true",ev=(e)=>`set vcs.account for workspace "${e??"?"}" in ~/.config/workit/workspaces.json`,tv=(e,t)=>`ask the user to run, in their own terminal: workit grant set ${e??"<workspace>"} ${t}=${yA(t)}`;var bA=(e,t,n)=>{let r=(o)=>o===!0?2:o==="verified"?1:0;return r(Ou(e,n))>r(Ou(e,t))};function nv(e){try{let t=new sn(e),n=t.listTaskIndex(),r=t.currentKey();if(!n.ok||!r.ok)return null;let o=n.data.filter((i)=>i.key===r.data.key&&i.status!=="closed").toSorted((i,a)=>a.updatedAt.localeCompare(i.updatedAt))[0],s=o?t.readTask(o.id):null;return s?.ok===!0?On(s.data):null}catch{return null}}var uo={kind:"none"},vA=/[??؟](?=[\s*_`"')\]>]*(?:\s|$))|¿/,SA=/\b(?:let me know|want me to|should I|shall I|would you like|do you want|if you(?:'d| would) like|may I|can I go ahead)\b/i,xA=/[[(]\s*y(?:es)?\s*\/\s*n(?:o)?\s*[\])]/i,_A=/^\s*(?:[-*+•]|\d+[.)]|[a-z][.)])\s+/i,ov=(e)=>{if(!e)return!1;let t=e.replace(/```[\s\S]*?(?:```|$)/g,`
214
214
 
215
215
  `).split(/\n\s*\n/).map((r)=>r.trim()).filter(Boolean);while(t.length>1&&t.at(-1).split(`
216
216
  `).every((r)=>_A.test(r)))t.pop();let n=t.slice(-2).join(`
package/dist/workit.js CHANGED
@@ -9431,7 +9431,7 @@ var package_default;
9431
9431
  var init_package = __esm(() => {
9432
9432
  package_default = {
9433
9433
  name: "@brainervirus/workit-cli",
9434
- version: "8.44.3",
9434
+ version: "8.45.0",
9435
9435
  private: false,
9436
9436
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
9437
9437
  keywords: [
@@ -9469,13 +9469,13 @@ var init_package = __esm(() => {
9469
9469
  },
9470
9470
  dependencies: {
9471
9471
  "@babel/parser": "7.29.9",
9472
- "@brainervirus/workit-cursor": "^8.44.3",
9472
+ "@brainervirus/workit-cursor": "^8.45.0",
9473
9473
  "@inkjs/ui": "2.0.0",
9474
9474
  ink: "7.1.1",
9475
9475
  react: "19.2.8"
9476
9476
  },
9477
9477
  devDependencies: {
9478
- "@brainervirus/workit-core": "^8.44.3"
9478
+ "@brainervirus/workit-core": "^8.45.0"
9479
9479
  },
9480
9480
  engines: {
9481
9481
  node: ">=24"
@@ -81248,7 +81248,7 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
81248
81248
 
81249
81249
  // packages/workit-core/src/git/ops.ts
81250
81250
  import { spawnSync as spawnSync21 } from "node:child_process";
81251
- import { existsSync as existsSync27, readFileSync as readFileSync28 } from "node:fs";
81251
+ import { copyFileSync as copyFileSync8, existsSync as existsSync27, readdirSync as readdirSync14, readFileSync as readFileSync28, rmSync as rmSync11 } from "node:fs";
81252
81252
  import path62 from "node:path";
81253
81253
  function operationInProgress(cwd) {
81254
81254
  const markers = [
@@ -81519,6 +81519,54 @@ function resyncCommittedPaths(cwd, paths) {
81519
81519
  if (stale.length)
81520
81520
  git5(cwd, ["reset", "-q", "HEAD", "--", ...stale.map((file) => `:(top,literal)${file}`)]);
81521
81521
  }
81522
+ function partiallyStaged(cwd, paths) {
81523
+ const names = (...args) => nulList(git5(cwd, ["diff", "--name-only", "-z", "--no-renames", ...args, "--", ...paths]).stdout);
81524
+ const unstaged = new Set(names());
81525
+ return names("--cached").filter((file) => unstaged.has(file));
81526
+ }
81527
+ function sweepPrivateIndexes(dir) {
81528
+ let names;
81529
+ try {
81530
+ names = readdirSync14(dir);
81531
+ } catch {
81532
+ return;
81533
+ }
81534
+ for (const name of names) {
81535
+ const match = PRIVATE_INDEX.exec(name);
81536
+ if (!match)
81537
+ continue;
81538
+ const pid = Number(match[1]);
81539
+ const stale = Date.now() - Number(match[2]) > PRIVATE_INDEX_TTL_MS || pid !== process.pid && !processAlive(pid);
81540
+ if (stale)
81541
+ rmSync11(path62.join(dir, name), { force: true });
81542
+ }
81543
+ }
81544
+ function pathCommitIndex(cwd, paths, env) {
81545
+ const where = (name) => path62.resolve(cwd, git5(cwd, ["rev-parse", "--git-path", name]).stdout.trim());
81546
+ const file = where(`workit-commit-${process.pid}-${Date.now()}.index`);
81547
+ sweepPrivateIndexes(path62.dirname(file));
81548
+ try {
81549
+ copyFileSync8(where("index"), file);
81550
+ } catch (error) {
81551
+ return {
81552
+ error: `could not copy the index: ${error instanceof Error ? error.message : String(error)}`
81553
+ };
81554
+ }
81555
+ const indexEnv = { ...env, GIT_INDEX_FILE: file };
81556
+ const staged = (...pathspec) => nulList(git5(cwd, ["diff", "--cached", "--name-only", "-z", "--no-renames", "--", ...pathspec], {
81557
+ env: indexEnv
81558
+ }).stdout);
81559
+ const inside = new Set(staged(...paths));
81560
+ const outside = staged().filter((name) => !inside.has(name));
81561
+ if (outside.length) {
81562
+ const reset = git5(cwd, ["reset", "-q", "--", ...outside.map(literalTop)], { env: indexEnv });
81563
+ if (!reset.ok) {
81564
+ rmSync11(file, { force: true });
81565
+ return { error: `could not leave out the other staged changes: ${gitError(reset)}` };
81566
+ }
81567
+ }
81568
+ return { file };
81569
+ }
81522
81570
  function gitCommit(cwd, input) {
81523
81571
  const given = input.message?.trim() ?? "";
81524
81572
  if (!given && !input.amend)
@@ -81532,6 +81580,10 @@ function gitCommit(cwd, input) {
81532
81580
  const paths = input.paths ?? [];
81533
81581
  if (input.all && paths.length)
81534
81582
  return failure3("invalid_input", "pass --all or paths, not both");
81583
+ if (input.staged && (input.all || paths.length || input.whole))
81584
+ return failure3("invalid_input", "--staged commits the index as is: drop --all, --whole and paths");
81585
+ if (input.whole && !paths.length)
81586
+ return failure3("invalid_input", "--whole applies to named paths: workit git commit --whole -- <paths>");
81535
81587
  const progress = operationInProgress(cwd);
81536
81588
  if (progress && !progress.commitAllowed)
81537
81589
  return inProgressFailure(progress.operation, "commit");
@@ -81604,19 +81656,36 @@ function gitCommit(cwd, input) {
81604
81656
  if (forged !== undefined)
81605
81657
  return failure3("invalid_input", `forged_session_trailer: the message would carry "Workit-Session: ${forged}", which workit did not add; workit writes that trailer itself`, "drop the Workit-Session line (or the trailer.<alias>.key config that expands into it)");
81606
81658
  args.push("-m", finalMessage);
81659
+ let keptPartial = [];
81660
+ let partialIndex = null;
81607
81661
  if (paths.length) {
81608
81662
  if (paths.some((value) => value.startsWith("-") || !value.trim()))
81609
81663
  return failure3("invalid_input", "paths must not be empty or start with -");
81664
+ keptPartial = input.whole ? [] : partiallyStaged(cwd, paths);
81665
+ const partial = new Set(keptPartial);
81666
+ const top = git5(cwd, ["rev-parse", "--show-prefix"]).stdout.trim();
81610
81667
  const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
81611
- const addable = paths.filter((value) => existsSync27(path62.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
81668
+ const addable = paths.filter((value) => !partial.has(path62.posix.normalize(`${top}${value.replaceAll("\\", "/")}`)) && (existsSync27(path62.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`))));
81612
81669
  if (addable.length) {
81613
- const added = git5(cwd, ["add", "-A", "--", ...addable]);
81670
+ const added = git5(cwd, [
81671
+ "add",
81672
+ "-A",
81673
+ "--",
81674
+ ...addable,
81675
+ ...keptPartial.map((file) => `:(exclude,top,literal)${file}`)
81676
+ ]);
81614
81677
  if (!added.ok)
81615
81678
  return failure3("failed", `git add failed: ${gitError(added)}`);
81616
81679
  }
81617
81680
  if (changeRequired && git5(cwd, ["diff", "--cached", "--quiet", "HEAD", "--", ...paths]).ok)
81618
81681
  return nothingToCommit(`${paths.join(", ")} has no change to commit`);
81619
- args.push("--", ...paths);
81682
+ if (keptPartial.length) {
81683
+ const built = pathCommitIndex(cwd, paths, input.env ?? process.env);
81684
+ if ("error" in built)
81685
+ return failure3("failed", built.error);
81686
+ partialIndex = built.file;
81687
+ } else
81688
+ args.push("--", ...paths);
81620
81689
  } else if (input.all) {
81621
81690
  const added = git5(cwd, ["add", "-A"]);
81622
81691
  if (!added.ok)
@@ -81627,15 +81696,27 @@ function gitCommit(cwd, input) {
81627
81696
  const staged = git5(cwd, ["diff", "--cached", "--name-only", "-z"]);
81628
81697
  if (staged.ok && !staged.stdout.replaceAll("\x00", "")) {
81629
81698
  const dirt = dirtEntries(cwd);
81699
+ if (input.staged)
81700
+ return failure3("blocked", `nothing_staged: --staged commits the index, and nothing is staged${dirt.length ? ` (${dirt.length} unstaged change(s))` : ""}`, "workit git stage --patch <file|-> (selected hunks) or workit git stage -- <paths>, then commit --staged");
81630
81701
  if (!dirt.length)
81631
81702
  return nothingToCommit("the working tree is clean");
81632
81703
  return failure3("blocked", `nothing_staged: nothing is staged and workit never commits unrelated changes implicitly (${dirt.length} changed: ${dirt.slice(0, 5).map((entry) => entry.slice(3)).join(", ")}${dirt.length > 5 ? ", …" : ""})`, `workit git commit -m '<msg>' -- <paths> # or --all to commit every change`);
81633
81704
  }
81634
81705
  }
81635
- const committed = git5(cwd, args, {
81636
- timeoutMs: COMMIT_TIMEOUT_MS,
81637
- env: { ...input.env ?? process.env, WORKIT_TRAILERS: trailersOn ? "on" : "off" }
81638
- });
81706
+ let committed;
81707
+ try {
81708
+ committed = git5(cwd, args, {
81709
+ timeoutMs: COMMIT_TIMEOUT_MS,
81710
+ env: {
81711
+ ...input.env ?? process.env,
81712
+ WORKIT_TRAILERS: trailersOn ? "on" : "off",
81713
+ ...partialIndex ? { GIT_INDEX_FILE: partialIndex } : {}
81714
+ }
81715
+ });
81716
+ } finally {
81717
+ if (partialIndex)
81718
+ rmSync11(partialIndex, { force: true });
81719
+ }
81639
81720
  if (!committed.ok) {
81640
81721
  const output = gitOutput(committed);
81641
81722
  const refusal = hookRefusal(output);
@@ -81687,6 +81768,7 @@ ${refusal}` : ""}`);
81687
81768
  sessionTrailer,
81688
81769
  amended: previous,
81689
81770
  notes,
81771
+ keptPartial,
81690
81772
  recorded: row.ok ? { id: String(row.value.id) } : { error: row.error }
81691
81773
  });
81692
81774
  }
@@ -82124,7 +82206,14 @@ ${run.stdout ?? ""}`).split(/\r?\n/u).map((value) => value.trimEnd()).filter((va
82124
82206
  ...lines.slice(-half)
82125
82207
  ].join(`
82126
82208
  `);
82127
- }, validRefName = (cwd, name) => !name.startsWith("-") && git5(cwd, ["check-ref-format", "--branch", name]).ok, nulList = (text) => text.split("\x00").filter(Boolean), SESSION_SAFE, EXTRA_TRAILER, SESSION_KEY, TRAILER_LINE, sessionValues = (trailers) => trailers.filter((trailer) => SESSION_KEY.test(trailer)).map((trailer) => trailer.slice(trailer.indexOf(":") + 1).trim()), TRAILER_CONFIG, nothingToCommit = (what) => failure3("failed", `nothing_to_commit: ${what}`, "workit git commit --allow-empty -m '<msg>' # only to record an empty commit on purpose"), SHA, SHA_PREFIX, isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), lineOfTag = (tag, lines) => lines.filter((line) => tag.startsWith(line.tagPrefix) && /^\d/u.test(tag.slice(line.tagPrefix.length))).toSorted((a, b) => b.tagPrefix.length - a.tagPrefix.length)[0] ?? null;
82209
+ }, validRefName = (cwd, name) => !name.startsWith("-") && git5(cwd, ["check-ref-format", "--branch", name]).ok, nulList = (text) => text.split("\x00").filter(Boolean), SESSION_SAFE, EXTRA_TRAILER, SESSION_KEY, TRAILER_LINE, sessionValues = (trailers) => trailers.filter((trailer) => SESSION_KEY.test(trailer)).map((trailer) => trailer.slice(trailer.indexOf(":") + 1).trim()), TRAILER_CONFIG, nothingToCommit = (what) => failure3("failed", `nothing_to_commit: ${what}`, "workit git commit --allow-empty -m '<msg>' # only to record an empty commit on purpose"), literalTop = (file) => `:(top,literal)${file}`, PRIVATE_INDEX, PRIVATE_INDEX_TTL_MS, processAlive = (pid) => {
82210
+ try {
82211
+ process.kill(pid, 0);
82212
+ return true;
82213
+ } catch (error) {
82214
+ return error.code === "EPERM";
82215
+ }
82216
+ }, SHA, SHA_PREFIX, isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), lineOfTag = (tag, lines) => lines.filter((line) => tag.startsWith(line.tagPrefix) && /^\d/u.test(tag.slice(line.tagPrefix.length))).toSorted((a, b) => b.tagPrefix.length - a.tagPrefix.length)[0] ?? null;
82128
82217
  var init_ops = __esm(() => {
82129
82218
  init_branch();
82130
82219
  init_branch_policy();
@@ -82143,6 +82232,8 @@ var init_ops = __esm(() => {
82143
82232
  SESSION_KEY = /^workit-session\s*:/iu;
82144
82233
  TRAILER_LINE = /^[A-Za-z0-9][A-Za-z0-9-]*\s*:/u;
82145
82234
  TRAILER_CONFIG = ["-c", "trailer.separators=:", "-c", "trailer.where=end"];
82235
+ PRIVATE_INDEX = /^workit-commit-(\d+)-(\d+)\.index(?:\.lock)?$/u;
82236
+ PRIVATE_INDEX_TTL_MS = 60 * 60000;
82146
82237
  SHA = /^[0-9a-f]{40,64}$/u;
82147
82238
  SHA_PREFIX = /^[0-9a-f]{7,39}$/u;
82148
82239
  });
@@ -87455,7 +87546,7 @@ var init_write_gate = __esm(() => {
87455
87546
  "switch"
87456
87547
  ]);
87457
87548
  DRY_N = new Set(["add", "clean", "rm", "mv"]);
87458
- MUTATING_WORKIT_GIT = new Set(["commit", "branch"]);
87549
+ MUTATING_WORKIT_GIT = new Set(["commit", "branch", "stage", "unstage"]);
87459
87550
  CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
87460
87551
  PUSHD2 = new Set(["pushd", "push-location"]);
87461
87552
  POPD2 = new Set(["popd", "pop-location"]);
@@ -89588,6 +89679,44 @@ var init_ci = __esm(() => {
89588
89679
  init_forge_common();
89589
89680
  });
89590
89681
 
89682
+ // packages/workit-core/src/git/stage.ts
89683
+ function gitStage(cwd, input) {
89684
+ const top = git5(cwd, ["rev-parse", "--show-toplevel"]);
89685
+ if (!top.ok)
89686
+ return failure3("invalid_input", "not inside a git work tree");
89687
+ if ("patch" in input) {
89688
+ if (!input.patch.trim())
89689
+ return failure3("invalid_input", "the patch is empty");
89690
+ const root = top.stdout.trim();
89691
+ const apply = (...flags) => git5(root, ["apply", "--cached", "--recount", ...flags, "-"], { input: input.patch });
89692
+ const checked = apply("--check");
89693
+ if (!checked.ok)
89694
+ return failure3("failed", `patch_does_not_apply: ${gitError(checked, 6)}`, "regenerate it from `git diff -- <file>` (the index is the base: `git diff` shows only unstaged hunks) and keep whole hunks");
89695
+ const applied = apply();
89696
+ if (!applied.ok)
89697
+ return failure3("failed", `git apply --cached failed: ${gitError(applied)}`);
89698
+ return success2({ staged: stagedNow(cwd) });
89699
+ }
89700
+ if (badPaths(input.paths))
89701
+ return failure3("invalid_input", "paths must not be empty or start with -");
89702
+ const added = git5(cwd, ["add", "-A", "--", ...input.paths]);
89703
+ if (!added.ok)
89704
+ return failure3("failed", `git add failed: ${gitError(added)}`);
89705
+ return success2({ staged: stagedNow(cwd) });
89706
+ }
89707
+ function gitUnstage(cwd, paths) {
89708
+ if (badPaths(paths))
89709
+ return failure3("invalid_input", "paths must not be empty or start with -");
89710
+ const reset = git5(cwd, ["reset", "-q", "--", ...paths]);
89711
+ if (!reset.ok)
89712
+ return failure3("failed", `git reset failed: ${gitError(reset)}`);
89713
+ return success2({ staged: stagedNow(cwd) });
89714
+ }
89715
+ var stagedNow = (cwd) => git5(cwd, ["diff", "--cached", "--name-only", "-z", "--no-renames"]).stdout.split("\x00").filter(Boolean), badPaths = (paths) => !paths.length || paths.some((value) => value.startsWith("-") || !value.trim());
89716
+ var init_stage = __esm(() => {
89717
+ init_ops();
89718
+ });
89719
+
89591
89720
  // packages/workit-cli/src/verbs/implicit-task.ts
89592
89721
  async function ensureImplicitTask(io, branch = null) {
89593
89722
  try {
@@ -89677,6 +89806,8 @@ function parseCommit(argv) {
89677
89806
  amend: false,
89678
89807
  noEdit: false,
89679
89808
  allowEmpty: false,
89809
+ staged: false,
89810
+ whole: false,
89680
89811
  paths: []
89681
89812
  };
89682
89813
  for (let index = 0;index < argv.length; index += 1) {
@@ -89738,6 +89869,10 @@ async function commit(argv, io) {
89738
89869
  return usage4(io, parsed, COMMIT_USAGE);
89739
89870
  if (parsed.all && parsed.paths.length)
89740
89871
  return usage4(io, "pass --all or paths, not both", COMMIT_USAGE);
89872
+ if (parsed.staged && (parsed.all || parsed.paths.length || parsed.whole))
89873
+ return usage4(io, "--staged commits the index as is: drop --all, --whole and paths", COMMIT_USAGE);
89874
+ if (parsed.whole && !parsed.paths.length)
89875
+ return usage4(io, "--whole applies to named paths (-- <paths…>)", COMMIT_USAGE);
89741
89876
  if (parsed.noEdit && !parsed.amend)
89742
89877
  return usage4(io, "--no-edit only applies with --amend", COMMIT_USAGE);
89743
89878
  const given = parsed.messages.length + parsed.files.length > 0;
@@ -89754,6 +89889,8 @@ async function commit(argv, io) {
89754
89889
  message,
89755
89890
  all: parsed.all,
89756
89891
  paths: parsed.paths,
89892
+ whole: parsed.whole,
89893
+ staged: parsed.staged,
89757
89894
  amend: parsed.amend,
89758
89895
  allowEmpty: parsed.allowEmpty,
89759
89896
  trailers: parsed.trailers,
@@ -89762,6 +89899,9 @@ async function commit(argv, io) {
89762
89899
  });
89763
89900
  if (!result.ok)
89764
89901
  return forgeFail(io, result);
89902
+ if (result.data.keptPartial.length)
89903
+ io.stderr(`note: committed only the staged part of ${result.data.keptPartial.join(", ")}; the unstaged rest stays in the working tree (--whole commits the whole file)
89904
+ `);
89765
89905
  await ensureImplicitTask(io);
89766
89906
  return emit(io, ok2(result.data), (data) => [
89767
89907
  `${data.branch} ${short2(data.sha)} ${data.message.split(`
@@ -89772,6 +89912,48 @@ async function commit(argv, io) {
89772
89912
  ...data.session ? [] : ["note: WORKIT_SESSION_ID is unset; this commit has no session author"]
89773
89913
  ]);
89774
89914
  }
89915
+ function readPatch(file, io) {
89916
+ try {
89917
+ return file === "-" ? readFileSync31(0, "utf8") : readFileSync31(path73.resolve(io.cwd, file), "utf8");
89918
+ } catch (error) {
89919
+ return {
89920
+ error: `cannot read --patch ${file}: ${error instanceof Error ? error.message : String(error)}`
89921
+ };
89922
+ }
89923
+ }
89924
+ function stage(argv, io) {
89925
+ const flags = parseFlags(argv, { patch: "value" });
89926
+ if (typeof flags === "string")
89927
+ return usage4(io, flags, STAGE_USAGE);
89928
+ const patchFile = flags.values.patch;
89929
+ if (patchFile !== undefined && flags.positionals.length)
89930
+ return usage4(io, "pass --patch or paths, not both", STAGE_USAGE);
89931
+ if (patchFile === undefined && !flags.positionals.length)
89932
+ return usage4(io, "missing --patch <file|-> or paths", STAGE_USAGE);
89933
+ let result;
89934
+ if (patchFile === undefined)
89935
+ result = gitStage(io.cwd, { paths: flags.positionals });
89936
+ else {
89937
+ const patch = readPatch(patchFile, io);
89938
+ if (typeof patch !== "string")
89939
+ return usage4(io, patch.error, STAGE_USAGE);
89940
+ result = gitStage(io.cwd, { patch });
89941
+ }
89942
+ if (!result.ok)
89943
+ return forgeFail(io, result);
89944
+ return emit(io, ok2(result.data), stagedLines);
89945
+ }
89946
+ function unstage(argv, io) {
89947
+ const flags = parseFlags(argv, {});
89948
+ if (typeof flags === "string")
89949
+ return usage4(io, flags, UNSTAGE_USAGE);
89950
+ if (!flags.positionals.length)
89951
+ return usage4(io, "missing paths", UNSTAGE_USAGE);
89952
+ const result = gitUnstage(io.cwd, flags.positionals);
89953
+ if (!result.ok)
89954
+ return forgeFail(io, result);
89955
+ return emit(io, ok2(result.data), stagedLines);
89956
+ }
89775
89957
  async function push(argv, io) {
89776
89958
  if (argv.includes("--force") || argv.includes("-f"))
89777
89959
  return usage4(io, "workit never force-pushes blindly; use --force-with-lease (the lease is the tip workit last recorded)", PUSH_USAGE);
@@ -89884,17 +90066,24 @@ async function run17(argv, io) {
89884
90066
  return branch(rest, io);
89885
90067
  if (sub === "commit")
89886
90068
  return commit(rest, io);
90069
+ if (sub === "stage")
90070
+ return stage(rest, io);
90071
+ if (sub === "unstage")
90072
+ return unstage(rest, io);
89887
90073
  if (sub === "push")
89888
90074
  return push(rest, io);
89889
90075
  if (sub === "trailers")
89890
90076
  return trailers(rest, io);
89891
90077
  return usage4(io, sub && !sub.startsWith("-") ? `unknown git subcommand "${sub}"` : "missing git subcommand", USAGE10);
89892
90078
  }
89893
- var BRANCH_USAGE = "workit git branch <name> | --kind feature|bugfix|release|hotfix --slug <s> [--base <b>] [--track <t>] [--carry] [--json]", COMMIT_USAGE = "workit git commit -m|--message <msg>… | -F|--file <file|-> [--trailer <key: value>]… [--amend [--no-edit]] [--allow-empty] [-a|--all | [--] <paths…>] [--json]", PUSH_USAGE = "workit git push [--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag>[,…]] [--json]", USAGE10 = "workit git branch|commit|push|trailers ... (workit help git)", short2 = (sha) => sha ? sha.slice(0, 12) : "(none)", COMMIT_SWITCHES, READ_ONLY;
90079
+ var BRANCH_USAGE = "workit git branch <name> | --kind feature|bugfix|release|hotfix --slug <s> [--base <b>] [--track <t>] [--carry] [--json]", COMMIT_USAGE = "workit git commit -m|--message <msg>… | -F|--file <file|-> [--trailer <key: value>]… [--amend [--no-edit]] [--allow-empty] [-a|--all | --staged | [--whole] [--] <paths…>] [--json]", STAGE_USAGE = "workit git stage --patch <file|-> | [--] <paths…> [--json]", UNSTAGE_USAGE = "workit git unstage [--] <paths…> [--json]", PUSH_USAGE = "workit git push [--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag>[,…]] [--json]", USAGE10 = "workit git branch|commit|stage|unstage|push|trailers ... (workit help git)", short2 = (sha) => sha ? sha.slice(0, 12) : "(none)", COMMIT_SWITCHES, stagedLines = (data) => [
90080
+ data.staged.length ? `staged (${data.staged.length}): ${data.staged.join(", ")}` : "nothing is staged"
90081
+ ], READ_ONLY;
89894
90082
  var init_git2 = __esm(() => {
89895
90083
  init_autonomy();
89896
90084
  init_branch();
89897
90085
  init_ops();
90086
+ init_stage();
89898
90087
  init_workspaces();
89899
90088
  init_ledger();
89900
90089
  init_implicit_task();
@@ -89905,7 +90094,9 @@ var init_git2 = __esm(() => {
89905
90094
  "--all": "all",
89906
90095
  "--amend": "amend",
89907
90096
  "--no-edit": "noEdit",
89908
- "--allow-empty": "allowEmpty"
90097
+ "--allow-empty": "allowEmpty",
90098
+ "--staged": "staged",
90099
+ "--whole": "whole"
89909
90100
  };
89910
90101
  READ_ONLY = new Set(["status", "diff", "log", "fetch", "show", "blame"]);
89911
90102
  });
@@ -108338,7 +108529,7 @@ var init_rules = __esm(() => {
108338
108529
 
108339
108530
  // packages/workit-cli/src/test-audit/audit.ts
108340
108531
  import { spawnSync as spawnSync30 } from "node:child_process";
108341
- import { existsSync as existsSync29, readdirSync as readdirSync14, readFileSync as readFileSync32, statSync as statSync10 } from "node:fs";
108532
+ import { existsSync as existsSync29, readdirSync as readdirSync15, readFileSync as readFileSync32, statSync as statSync10 } from "node:fs";
108342
108533
  import path77 from "node:path";
108343
108534
  function git7(cwd, args) {
108344
108535
  const run = spawnSync30("git", ["-c", "core.quotepath=off", ...args], {
@@ -108349,7 +108540,7 @@ function git7(cwd, args) {
108349
108540
  return { ok: run.status === 0, stdout: run.stdout ?? "" };
108350
108541
  }
108351
108542
  function walkTests(dir, out) {
108352
- for (const entry of readdirSync14(dir, { withFileTypes: true })) {
108543
+ for (const entry of readdirSync15(dir, { withFileTypes: true })) {
108353
108544
  if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
108354
108545
  continue;
108355
108546
  const full = path77.join(dir, entry.name);
@@ -108485,16 +108676,16 @@ import {
108485
108676
  lstatSync as lstatSync9,
108486
108677
  mkdirSync as mkdirSync13,
108487
108678
  mkdtempSync as mkdtempSync6,
108488
- readdirSync as readdirSync15,
108679
+ readdirSync as readdirSync16,
108489
108680
  readFileSync as readFileSync33,
108490
108681
  readlinkSync as readlinkSync3,
108491
108682
  realpathSync as realpathSync11,
108492
108683
  renameSync as renameSync8,
108493
- rmSync as rmSync11,
108684
+ rmSync as rmSync12,
108494
108685
  statSync as statSync11,
108495
108686
  symlinkSync,
108496
108687
  writeFileSync as writeFileSync15,
108497
- copyFileSync as copyFileSync8
108688
+ copyFileSync as copyFileSync9
108498
108689
  } from "node:fs";
108499
108690
  import os26 from "node:os";
108500
108691
  import path78 from "node:path";
@@ -108582,7 +108773,7 @@ function removeStaleCopies(tmp = os26.tmpdir()) {
108582
108773
  let removed = 0;
108583
108774
  let names = [];
108584
108775
  try {
108585
- names = readdirSync15(tmp);
108776
+ names = readdirSync16(tmp);
108586
108777
  } catch {
108587
108778
  return 0;
108588
108779
  }
@@ -108603,7 +108794,7 @@ function removeStaleCopies(tmp = os26.tmpdir()) {
108603
108794
  continue;
108604
108795
  }
108605
108796
  try {
108606
- rmSync11(dir, { recursive: true, force: true });
108797
+ rmSync12(dir, { recursive: true, force: true });
108607
108798
  removed += 1;
108608
108799
  } catch {}
108609
108800
  }
@@ -108611,7 +108802,7 @@ function removeStaleCopies(tmp = os26.tmpdir()) {
108611
108802
  }
108612
108803
  function linkNodeModules(origin, target, repo, copy) {
108613
108804
  mkdirSync13(target, { recursive: true });
108614
- for (const entry of readdirSync15(origin, { withFileTypes: true })) {
108805
+ for (const entry of readdirSync16(origin, { withFileTypes: true })) {
108615
108806
  const from = path78.join(origin, entry.name);
108616
108807
  const to = path78.join(target, entry.name);
108617
108808
  if (entry.name.startsWith("@") && entry.isDirectory()) {
@@ -108651,7 +108842,7 @@ function copySymlink(repo, tree, from, to) {
108651
108842
  return;
108652
108843
  }
108653
108844
  if (real && statSync11(real).isFile())
108654
- copyFileSync8(real, to);
108845
+ copyFileSync9(real, to);
108655
108846
  else
108656
108847
  symlinkSync(readlinkSync3(from), to);
108657
108848
  }
@@ -108701,7 +108892,7 @@ function copyWorkingTree(repo) {
108701
108892
  if (stat.isSymbolicLink())
108702
108893
  copySymlink(repo, tree, from, to);
108703
108894
  else if (stat.isFile())
108704
- copyFileSync8(from, to);
108895
+ copyFileSync9(from, to);
108705
108896
  let parent = path78.dirname(relative);
108706
108897
  while (parent !== "." && !dirs.has(parent)) {
108707
108898
  dirs.add(parent);
@@ -108820,7 +109011,7 @@ async function runMutation(options) {
108820
109011
  for (const child of active)
108821
109012
  killTree(child);
108822
109013
  restore();
108823
- rmSync11(copyDir, { recursive: true, force: true });
109014
+ rmSync12(copyDir, { recursive: true, force: true });
108824
109015
  };
108825
109016
  const onSignal = (signal) => {
108826
109017
  cleanup();
@@ -109900,7 +110091,7 @@ var VERBS = [
109900
110091
  withSubcommands({
109901
110092
  name: "git",
109902
110093
  group: "delivery",
109903
- summary: "Policy-checked branch and commit (Workit-Session trailer); push with a lease and a verified remote tip",
110094
+ summary: "Policy-checked branch, hunk staging and commit (Workit-Session trailer); push with a lease and a verified remote tip",
109904
110095
  subcommands: [
109905
110096
  {
109906
110097
  name: "branch",
@@ -109909,8 +110100,18 @@ var VERBS = [
109909
110100
  },
109910
110101
  {
109911
110102
  name: "commit",
109912
- usage: "workit git commit -m|--message <msg>… | -F|--file <file|-> [--trailer <key: value>]… [--amend [--no-edit]] [--allow-empty] [-a|--all | [--] <paths…>]",
109913
- summary: "Commit (or --amend) with a linted Conventional Commit message, the session trailer (unless the workspace sets trailers: false) and any --trailer"
110103
+ usage: "workit git commit -m|--message <msg>… | -F|--file <file|-> [--trailer <key: value>]… [--amend [--no-edit]] [--allow-empty] [-a|--all | --staged | [--whole] [--] <paths…>]",
110104
+ summary: "Commit (or --amend) with a linted Conventional Commit message, the session trailer (unless the workspace sets trailers: false) and any --trailer; a path staged in part commits its staged hunks only (--whole for all of it), --staged commits exactly the index"
110105
+ },
110106
+ {
110107
+ name: "stage",
110108
+ usage: "workit git stage --patch <file|-> | [--] <paths…>",
110109
+ summary: "Stage selected hunks without git add -p: apply a unified diff to the index only (checked first); or stage whole paths"
110110
+ },
110111
+ {
110112
+ name: "unstage",
110113
+ usage: "workit git unstage [--] <paths…>",
110114
+ summary: "Put paths back to HEAD in the index; the working tree keeps the changes"
109914
110115
  },
109915
110116
  {
109916
110117
  name: "push",
@@ -109929,6 +110130,8 @@ var VERBS = [
109929
110130
  'workit git commit -m "fix(cli): answer help flags first" --all',
109930
110131
  'workit git commit -m "feat: x" --trailer "Co-Authored-By: Name <email>" --all',
109931
110132
  "workit git commit --amend --no-edit -- src/forgotten.ts",
110133
+ "workit git stage --patch hunks.patch # a git diff trimmed to the hunks to commit",
110134
+ 'workit git commit --staged -m "fix(a): one focused change"',
109932
110135
  "workit git push --set-upstream"
109933
110136
  ],
109934
110137
  load: () => Promise.resolve().then(() => (init_git2(), exports_git))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-claude-code",
3
- "version": "8.44.3",
3
+ "version": "8.45.0",
4
4
  "private": false,
5
5
  "description": "Workit Claude Code plugin — session and per-turn task context, branch policy on git shell commands, workit method skills, and verifier/reviewer/implementer agents",
6
6
  "keywords": [
@@ -39,8 +39,8 @@
39
39
  "build": "bun scripts/build.ts"
40
40
  },
41
41
  "devDependencies": {
42
- "@brainervirus/workit-cli": "^8.44.3",
43
- "@brainervirus/workit-core": "^8.44.3"
42
+ "@brainervirus/workit-cli": "^8.45.0",
43
+ "@brainervirus/workit-core": "^8.45.0"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=24"
@@ -30,7 +30,7 @@ description: Build a requested change in small verified steps - follow local pat
30
30
  change a screenshot or console/network check (chrome devtools or
31
31
  agent-browser), an API a quoted real response. App not runnable? Say so
32
32
  plainly, never claim success.
33
- 6. Commit: `workit git commit -m "<type>: <what>" -- <paths>` (or `--all`).
33
+ 6. Commit: `workit git commit -m "<type>: <what>" -- <paths>` (or `--all`). One file holding two changes: stage one change's hunks with `workit git stage --patch <file>` (a `git diff -- <file>` cut to them), then `workit git commit -m "<msg>" --staged` (exactly the index); a path staged in part commits only its staged hunks (`--whole` takes the file).
34
34
  No endpoint named? Stop here and state the next command. Hand delivery to
35
35
  ship, which pushes and opens the PR with its body shape (call the Skill tool with `workit:ship`), only
36
36
  when that was requested, or the request implies delivery and the effective
@@ -49,7 +49,7 @@ the same check. Fix round and recheck both failed: a decider (call the Skill too
49
49
  5. **CI.** Local gates mirror CI: push and continue; `workit ci wait` once on
50
50
  the final head, in the background where the host allows. Red: read `logTail`, classify. Flake or infra: one
51
51
  `workit ci rerun --failed --reason flake|infra` per head. Real: reproduce
52
- with `workit check`, fix the root cause, batch every fix in one push. A tool warning is a finding: fix it in this PR in the right layer, or record the false positive with evidence; pre-existing ones get their own PR.
52
+ with `workit check`, fix the root cause, batch every fix in one push, one focused commit per fix (unrelated hunks in one file: `workit git stage --patch <file>`, then `workit git commit -m "<msg>" --staged`). A tool warning is a finding: fix it in this PR in the right layer, or record the false positive with evidence; pre-existing ones get their own PR.
53
53
  6. **Verified.** The lane in `workit pr status` decides: none, no verdict; self, your `--self` verdict; focused or full (or `verification: self|independent`), one non-author verifier per PR after the last push, never per push (call the Skill tool with `workit:review`), on Claude Code with the `model` and `effort` of `workit models show --role verifier`. A docs-only push (or test-only under a unit verdict) keeps the verdict (`carried`); `reverify: focused` re-checks only the new diff, reusing green CI; one verdict at a stack's top covers its unchanged lower PRs. Land only when
54
54
  granted: `workit stack land` or `workit pr merge`; `--unverified --reason` if user-asked.
55
55
  Never pipe a delivery verb through `grep`: read its exit code, or use `--json`.