@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.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/workit-hook.js +1 -1
- package/dist/workit.js +232 -29
- package/package.json +3 -3
- package/skills/implement/SKILL.md +1 -1
- package/skills/ship/SKILL.md +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workit",
|
|
3
3
|
"displayName": "Workit",
|
|
4
|
-
"version": "8.
|
|
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"
|
package/dist/workit-hook.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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, [
|
|
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
|
-
|
|
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
|
-
|
|
81636
|
-
|
|
81637
|
-
|
|
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"),
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
108684
|
+
rmSync as rmSync12,
|
|
108494
108685
|
statSync as statSync11,
|
|
108495
108686
|
symlinkSync,
|
|
108496
108687
|
writeFileSync as writeFileSync15,
|
|
108497
|
-
copyFileSync as
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
43
|
-
"@brainervirus/workit-core": "^8.
|
|
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
|
package/skills/ship/SKILL.md
CHANGED
|
@@ -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`.
|