@chief-clancy/terminal 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- "use strict";var E=require("node:fs");function r(){return{decision:"approve"}}function u(t){return{decision:"block",reason:t}}function p(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var l={};var k=0;function g(t){try{let e=JSON.parse(t);return p(e)?e:l}catch{return l}}function f(t){let e=t.argv[2];if(e)return g(e);try{let n=t.readFileSync(k,"utf8");return g(n)}catch{return l}}var i=["main","master","develop"],A=/\bgit\s+push\b/,R=/\s--force\b/,S=/\s-f\b/,b=/--force-with-lease/,T=/\bgit\s+reset\s+--hard\b/,O=/\bgit\s+clean\s+(.*)/,y=/(?:^|\s)-[a-zA-Z]*f/,P=/(?:^|\s)-[a-zA-Z]*n/,D=/\bgit\s+checkout\s+--\s+\./,F=/\bgit\s+restore\s+\.(?:\s*$|\s*[;&|])/,N=/\bgit\s+branch\s+.*-D\b/,x="Blocked: git push --force destroys remote history. Use --force-with-lease instead.",B=t=>`Blocked: direct push to protected branch '${t}'. Create a PR instead.`,L="Blocked: git reset --hard discards all uncommitted changes.",I="Blocked: git clean -f deletes untracked files. Use -n for a dry run first.",H="Blocked: git checkout -- . discards all unstaged changes.",U="Blocked: git restore . discards all unstaged changes.",M="Blocked: git branch -D force-deletes without merge check. Use -d for safe deletion.";function _(t){return t?i.includes(t)?[...i]:[...i,t]:[...i]}function G(t){let e=/\bgit\s+push\b[^&|;]*/.exec(t);return e?e[0]:null}function v(t){let e=G(t);if(!e)return null;let n=R.test(e)||S.test(e),o=b.test(e);return n&&!o?x:null}function J(t,e){if(!A.test(t))return null;let n=t.split(/\s+/),o=n.indexOf("push");if(o<0)return null;let c=(n.slice(o+1).filter(a=>!a.startsWith("-"))[1]??"").split(":")[0],h=e.find(a=>c===a);return h?B(h):null}function w(t){return T.test(t)?L:null}function Y(t){let e=O.exec(t);if(!e)return null;let n=e[1],o=y.test(n),s=P.test(n);return o&&!s?I:null}function j(t){return D.test(t)?H:null}function z(t){return F.test(t)?U:null}function K(t){return N.test(t)?M:null}function m(t,e){return t?[()=>v(t),()=>J(t,e),()=>w(t),()=>Y(t),()=>j(t),()=>z(t),()=>K(t)].map(s=>s()).find(Boolean)??null:null}try{process.env.CLANCY_BRANCH_GUARD==="false"&&(console.log(JSON.stringify(r())),process.exit(0));let e=f({argv:process.argv,readFileSync:E.readFileSync}),n=e.tool_name??"",o=e.tool_input??{},s=typeof o.command=="string"?o.command:"";n==="Bash"||(console.log(JSON.stringify(r())),process.exit(0));let d=_(process.env.CLANCY_BASE_BRANCH),c=m(s,d);console.log(JSON.stringify(c?u(c):r()))}catch{console.log(JSON.stringify(r()))}
1
+ "use strict";var _=require("node:fs");function r(){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function u(t){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:t}}}function p(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var l={};var C=0;function m(t){try{let e=JSON.parse(t);return p(e)?e:l}catch{return l}}function f(t){let e=t.argv[2];if(e)return m(e);try{let o=t.readFileSync(C,"utf8");return m(o)}catch{return l}}var i=["main","master","develop"],R=/\bgit\s+push\b/,S=/\s--force\b/,A=/\s-f\b/,T=/--force-with-lease/,b=/\bgit\s+reset\s+--hard\b/,O=/\bgit\s+clean\s+(.*)/,D=/(?:^|\s)-[a-zA-Z]*f/,P=/(?:^|\s)-[a-zA-Z]*n/,y=/\bgit\s+checkout\s+--\s+\./,N=/\bgit\s+restore\s+\.(?:\s*$|\s*[;&|])/,F=/\bgit\s+branch\s+.*-D\b/,x="Blocked: git push --force destroys remote history. Use --force-with-lease instead.",B=t=>`Blocked: direct push to protected branch '${t}'. Create a PR instead.`,L="Blocked: git reset --hard discards all uncommitted changes.",U="Blocked: git clean -f deletes untracked files. Use -n for a dry run first.",I="Blocked: git checkout -- . discards all unstaged changes.",H="Blocked: git restore . discards all unstaged changes.",M="Blocked: git branch -D force-deletes without merge check. Use -d for safe deletion.";function g(t){return t?i.includes(t)?[...i]:[...i,t]:[...i]}function G(t){let e=/\bgit\s+push\b[^&|;]*/.exec(t);return e?e[0]:null}function v(t){let e=G(t);if(!e)return null;let o=S.test(e)||A.test(e),n=T.test(e);return o&&!n?x:null}function w(t,e){if(!R.test(t))return null;let o=t.split(/\s+/),n=o.indexOf("push");if(n<0)return null;let c=(o.slice(n+1).filter(a=>!a.startsWith("-"))[1]??"").split(":")[0],d=e.find(a=>c===a);return d?B(d):null}function J(t){return b.test(t)?L:null}function Y(t){let e=O.exec(t);if(!e)return null;let o=e[1],n=D.test(o),s=P.test(o);return n&&!s?U:null}function j(t){return y.test(t)?I:null}function z(t){return N.test(t)?H:null}function K(t){return F.test(t)?M:null}function E(t,e){return t?[()=>v(t),()=>w(t,e),()=>J(t),()=>Y(t),()=>j(t),()=>z(t),()=>K(t)].map(s=>s()).find(Boolean)??null:null}try{process.env.CLANCY_BRANCH_GUARD==="false"&&(console.log(JSON.stringify(r())),process.exit(0));let e=f({argv:process.argv,readFileSync:_.readFileSync}),o=e.tool_name??"",n=e.tool_input??{},s=typeof n.command=="string"?n.command:"";o==="Bash"||(console.log(JSON.stringify(r())),process.exit(0));let h=g(process.env.CLANCY_BASE_BRANCH),c=E(s,h);console.log(JSON.stringify(c?u(c):r()))}catch{console.log(JSON.stringify(r()))}
@@ -1,9 +1,9 @@
1
- "use strict";var g=require("node:fs"),k=require("node:os");function x(e,t){return{hookSpecificOutput:{hookEventName:e,additionalContext:t}}}var P=require("node:path");function l(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function y(e,t){let n=(0,P.join)(e,".clancy","lock.json");try{let r=JSON.parse(t.readFileSync(n,"utf8"));return l(r)?r:null}catch{return null}}var M=require("node:stream/consumers");var w={},G=3e3;function Y(e){try{let t=JSON.parse(e);return l(t)?t:w}catch{return w}}function H(e){return new Promise(t=>{setTimeout(()=>t(w),e)})}function S(e){let t=e.timeoutMs??G,n=(0,M.text)(e.stdin).then(Y);return Promise.race([n,H(t)])}var L=require("node:path");function b(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"")}function C(e,t){return(0,L.join)(t.tmpdir(),`clancy-ctx-${b(e)}.json`)}function I(e,t){return(0,L.join)(t.tmpdir(),`clancy-ctx-${b(e)}-warned.json`)}var J=35,B=25,q=60,K=5,V=80,X=100,N=30;function A(e,t,n){return e||t>=K||n}function D(e,t,n){let r={message:null,debounce:t};if(!e||e.timestamp!==void 0&&n-e.timestamp>q)return r;let o=e.remaining_percentage;if(!(o<=J))return r;let m=t.callsSinceWarn+1,a=o<=B,d=a?"critical":"warning",p=t.lastLevel===null,c=t.lastLevel==="warning";return A(p,m,a&&c)?{message:a?Z(e.used_pct,o):z(e.used_pct,o),debounce:{callsSinceWarn:0,lastLevel:d}}:{message:null,debounce:{callsSinceWarn:m,lastLevel:t.lastLevel}}}function O(e,t){let n={message:null,debounce:t},{startedAt:r,timeLimitMinutes:i,nowMs:o}=e;if(!r||i<=0)return n;let s=new Date(r).getTime();if(isNaN(s))return n;let a=o-s,d=Math.floor(a/6e4),p=i*6e4,c=Math.floor(a/p*100);if(c<V)return n;let f=t.callsSinceWarn+1,u=c>=X,E=u?"critical":"warning",$=t.lastLevel===null,j=t.lastLevel==="warning";return A($,f,u&&j)?{message:u?tt(d,i):Q(d,i,c),debounce:{callsSinceWarn:0,lastLevel:E}}:{message:null,debounce:{callsSinceWarn:f,lastLevel:t.lastLevel}}}var v={callsSinceWarn:0,lastLevel:null},h={context:v,time:v};function F(e){try{let t=JSON.parse(e);return l(t)?{context:_(t.context),time:_(t.time)}:h}catch{return h}}function W(e){try{let t=JSON.parse(e);if(!l(t))return null;let n=t.remaining_percentage,r=t.used_pct;if(!(typeof n=="number"&&typeof r=="number"&&Number.isFinite(n)&&Number.isFinite(r)))return null;let o={remaining_percentage:n,used_pct:r},s=t.timestamp;return typeof s=="number"&&Number.isFinite(s)?{...o,timestamp:s}:o}catch{return null}}function R(e){if(e===void 0)return N;let t=Number(e);return Number.isFinite(t)?t:N}function _(e){if(!l(e))return v;let t=e.callsSinceWarn,n=typeof t=="number"?t:0,r=e.lastLevel;return{callsSinceWarn:n,lastLevel:r==="warning"||r==="critical"?r:null}}function z(e,t){return`CONTEXT WARNING: Usage at ${e}%. Remaining: ${t}%. Context is getting limited. Stop exploring and move to implementation. Avoid reading additional files unless strictly necessary. Commit completed work as soon as it is ready.`}function Z(e,t){return`CONTEXT CRITICAL: Usage at ${e}%. Remaining: ${t}%. Context is nearly exhausted. Stop reading files and wrap up immediately:
1
+ "use strict";var g=require("node:fs"),k=require("node:os");function x(e,t){return{hookSpecificOutput:{hookEventName:e,additionalContext:t}}}var P=require("node:path");function l(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function y(e,t){let n=(0,P.join)(e,".clancy","lock.json");try{let r=JSON.parse(t.readFileSync(n,"utf8"));return l(r)?r:null}catch{return null}}var N=require("node:stream/consumers");var w={},G=3e3;function Y(e){try{let t=JSON.parse(e);return l(t)?t:w}catch{return w}}function H(e){return new Promise(t=>{setTimeout(()=>t(w),e)})}function S(e){let t=e.timeoutMs??G,n=(0,N.text)(e.stdin).then(Y);return Promise.race([n,H(t)])}var L=require("node:path");function C(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"")}function b(e,t){return(0,L.join)(t.tmpdir(),`clancy-ctx-${C(e)}.json`)}function v(e,t){return(0,L.join)(t.tmpdir(),`clancy-ctx-${C(e)}-warned.json`)}var J=35,B=25,q=60,K=5,V=80,X=100,M=30;function D(e,t,n){return e||t>=K||n}function O(e,t,n){let r={message:null,debounce:t};if(!e||e.timestamp!==void 0&&n-e.timestamp>q)return r;let i=e.remaining_percentage;if(!(i<=J))return r;let m=t.callsSinceWarn+1,a=i<=B,d=a?"critical":"warning",p=t.lastLevel===null,c=t.lastLevel==="warning";return D(p,m,a&&c)?{message:a?Z(e.used_pct,i):z(e.used_pct,i),debounce:{callsSinceWarn:0,lastLevel:d}}:{message:null,debounce:{callsSinceWarn:m,lastLevel:t.lastLevel}}}function A(e,t){let n={message:null,debounce:t},{startedAt:r,timeLimitMinutes:o,nowMs:i}=e;if(!r||o<=0)return n;let s=new Date(r).getTime();if(isNaN(s))return n;let a=i-s,d=Math.floor(a/6e4),p=o*6e4,c=Math.floor(a/p*100);if(c<V)return n;let f=t.callsSinceWarn+1,u=c>=X,E=u?"critical":"warning",$=t.lastLevel===null,j=t.lastLevel==="warning";return D($,f,u&&j)?{message:u?tt(d,o):Q(d,o,c),debounce:{callsSinceWarn:0,lastLevel:E}}:{message:null,debounce:{callsSinceWarn:f,lastLevel:t.lastLevel}}}var I={callsSinceWarn:0,lastLevel:null},h={context:I,time:I};function F(e){try{let t=JSON.parse(e);return l(t)?{context:_(t.context),time:_(t.time)}:h}catch{return h}}function W(e){try{let t=JSON.parse(e);if(!l(t))return null;let n=t.remaining_percentage,r=t.used_pct;if(!(typeof n=="number"&&typeof r=="number"&&Number.isFinite(n)&&Number.isFinite(r)))return null;let i={remaining_percentage:n,used_pct:r},s=t.timestamp;return typeof s=="number"&&Number.isFinite(s)?{...i,timestamp:s}:i}catch{return null}}function R(e){if(e===void 0)return M;let t=Number(e);return Number.isFinite(t)?t:M}function _(e){if(!l(e))return I;let t=e.callsSinceWarn,n=typeof t=="number"?t:0,r=e.lastLevel;return{callsSinceWarn:n,lastLevel:r==="warning"||r==="critical"?r:null}}function z(e,t){return`CONTEXT WARNING: Usage at ${e}%. Remaining: ${t}%. Context is getting limited. Stop exploring and move to implementation. Avoid reading additional files unless strictly necessary. Commit completed work as soon as it is ready.`}function Z(e,t){return`CONTEXT CRITICAL: Usage at ${e}%. Remaining: ${t}%. Context is nearly exhausted. Stop reading files and wrap up immediately:
2
2
  1. Commit whatever work is staged on the current feature branch
3
3
  2. Append a WIP entry to .clancy/progress.txt: YYYY-MM-DD HH:MM | TICKET-KEY | Summary | WIP \u2014 context exhausted
4
4
  3. Inform the user what was completed and what remains.
5
5
  Do NOT start any new work.`}function Q(e,t,n){return`TIME WARNING: Ticket implementation at ${e}min of ${t}min limit (${n}%).
6
6
  Wrap up implementation and prepare for delivery. Avoid starting new approaches.`}function tt(e,t){return`TIME CRITICAL: Time limit reached (${e}min of ${t}min).
7
7
  STOP implementation immediately. Commit current work, push the branch,
8
- and create the PR with whatever is ready. Log a WIP entry if incomplete.`}S({stdin:process.stdin}).then(et).catch(()=>{});function et(e){let t=e.session_id??"";if(!t)return;let n=e.cwd??process.cwd(),r={readFileSync:g.readFileSync},i={tmpdir:k.tmpdir},o=I(t,i),s=nt(o,r),m=C(t,i),a=U(m,r),d=a?W(a):null,p=Math.floor(Date.now()/1e3),c=D(d,s.context,p),T=y(n,r),f=R(process.env.CLANCY_TIME_LIMIT),u=O({startedAt:T?.startedAt,timeLimitMinutes:f,nowMs:Date.now()},s.time);rt(o,s,{context:c,time:u}),it(c,u)}function U(e,t){try{return t.readFileSync(e,"utf8")}catch{return null}}function nt(e,t){let n=U(e,t);return n?F(n):h}function rt(e,t,n){if(!(n.context.debounce!==t.context||n.time.debounce!==t.time))return;let i={context:n.context.debounce,time:n.time.debounce};try{(0,g.writeFileSync)(e,JSON.stringify(i))}catch{}}function it(e,t){let n=[e.message,t.message].filter(i=>i!==null);if(n.length===0)return;let r=x("PostToolUse",n.join(`
8
+ and create the PR with whatever is ready. Log a WIP entry if incomplete.`}S({stdin:process.stdin}).then(et).catch(()=>{});function et(e){let t=e.session_id??"";if(!t)return;let n=e.cwd??process.cwd(),r={readFileSync:g.readFileSync},o={tmpdir:k.tmpdir},i=v(t,o),s=nt(i,r),m=b(t,o),a=U(m,r),d=a?W(a):null,p=Math.floor(Date.now()/1e3),c=O(d,s.context,p),T=y(n,r),f=R(process.env.CLANCY_TIME_LIMIT),u=A({startedAt:T?.startedAt,timeLimitMinutes:f,nowMs:Date.now()},s.time);rt(i,s,{context:c,time:u}),ot(c,u)}function U(e,t){try{return t.readFileSync(e,"utf8")}catch{return null}}function nt(e,t){let n=U(e,t);return n?F(n):h}function rt(e,t,n){if(!(n.context.debounce!==t.context||n.time.debounce!==t.time))return;let o={context:n.context.debounce,time:n.time.debounce};try{(0,g.writeFileSync)(e,JSON.stringify(o))}catch{}}function ot(e,t){let n=[e.message,t.message].filter(o=>o!==null);if(n.length===0)return;let r=x("PostToolUse",n.join(`
9
9
  `));process.stdout.write(JSON.stringify(r))}
@@ -1,2 +1,2 @@
1
- "use strict";var x=require("node:fs");function o(){return{decision:"approve"}}function i(e){return{decision:"block",reason:e}}function f(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var a={};var P=0;function g(e){try{let t=JSON.parse(e);return f(t)?t:a}catch{return a}}function c(e){let t=e.argv[2];if(t)return g(t);try{let n=e.readFileSync(P,"utf8");return g(n)}catch{return a}}function r(e,t,n){return new RegExp(`(?:${e})\\s*[:=]\\s*["']?${t}{${n},}["']?`,"i")}var l="[A-Za-z0-9\\-_.]",h="[A-Za-z0-9+/=]",v="[A-Za-z0-9/+=]",b=[{name:"Generic API key",regex:r("api[_-]?key|apikey",l,20)},{name:"Generic secret",regex:r("secret|private[_-]?key",l,20)},{name:"Generic token",regex:r("auth[_-]?token|access[_-]?token|bearer",l,20)},{name:"Generic password",regex:r("password|passwd|pwd",`[^\\s"']`,8)},{name:"AWS Secret Key",regex:r("aws_secret_access_key|aws_secret",v,40)},{name:"Atlassian API token",regex:r("jira_api_token|atlassian[_-]?token",h,24)},{name:"AWS Access Key",regex:/AKIA[0-9A-Z]{16}/},{name:"GitHub PAT (classic)",regex:/ghp_[A-Za-z0-9]{36}/},{name:"GitHub PAT (fine-grained)",regex:/github_pat_[A-Za-z0-9_]{82}/},{name:"GitHub OAuth token",regex:/gho_[A-Za-z0-9]{36}/},{name:"Slack token",regex:/xox[bpors]-[0-9]{10,}-[A-Za-z0-9-]+/},{name:"Stripe key",regex:/(?:sk|pk)_(?:live|test)_[A-Za-z0-9]{24,}/},{name:"Linear API key",regex:/lin_api_[A-Za-z0-9]{40,}/},{name:"Private key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/},{name:"Database connection string",regex:/(?:mongodb|postgres|mysql|redis):\/\/[^\s"']+:[^\s"']+@/i}],w=[".clancy/.env",".env.local",".env.example",".env.development",".env.test"];function m(e){return w.some(t=>e.endsWith(t))}function A(e){return e?b.filter(({regex:t})=>t.test(e)).map(({name:t})=>t):[]}function T(e){if(!(typeof e=="object"&&e!==null))return;let n=e.new_string;return typeof n=="string"?n:void 0}function d(e,t){if(e==="Write"){let n=t.content;return typeof n=="string"?n:null}if(e==="Edit"){let n=t.new_string;return typeof n=="string"?n:null}if(e==="MultiEdit"){let n=t.edits;return Array.isArray(n)?n.map(T).filter(Boolean).join(`
2
- `):null}return null}try{let e=c({argv:process.argv,readFileSync:x.readFileSync}),t=e.tool_name??"",n=e.tool_input??{},s=typeof n.file_path=="string"?n.file_path:"",u=d(t,n),_=u!==null,y=s!==""&&m(s);(!_||y)&&(console.log(JSON.stringify(o())),process.exit(0));let p=A(u);if(p.length>0){let k=p.join(", "),S=`Credential guard: blocked writing to ${s}. Detected: ${k}. Move credentials to .clancy/.env instead.`;console.log(JSON.stringify(i(S)))}else console.log(JSON.stringify(o()))}catch{console.log(JSON.stringify(o()))}
1
+ "use strict";var x=require("node:fs");function r(){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function i(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:e}}}function f(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var a={};var P=0;function m(e){try{let t=JSON.parse(e);return f(t)?t:a}catch{return a}}function c(e){let t=e.argv[2];if(t)return m(t);try{let n=e.readFileSync(P,"utf8");return m(n)}catch{return a}}function o(e,t,n){return new RegExp(`(?:${e})\\s*[:=]\\s*["']?${t}{${n},}["']?`,"i")}var l="[A-Za-z0-9\\-_.]",h="[A-Za-z0-9+/=]",v="[A-Za-z0-9/+=]",T=[{name:"Generic API key",regex:o("api[_-]?key|apikey",l,20)},{name:"Generic secret",regex:o("secret|private[_-]?key",l,20)},{name:"Generic token",regex:o("auth[_-]?token|access[_-]?token|bearer",l,20)},{name:"Generic password",regex:o("password|passwd|pwd",`[^\\s"']`,8)},{name:"AWS Secret Key",regex:o("aws_secret_access_key|aws_secret",v,40)},{name:"Atlassian API token",regex:o("jira_api_token|atlassian[_-]?token",h,24)},{name:"AWS Access Key",regex:/AKIA[0-9A-Z]{16}/},{name:"GitHub PAT (classic)",regex:/ghp_[A-Za-z0-9]{36}/},{name:"GitHub PAT (fine-grained)",regex:/github_pat_[A-Za-z0-9_]{82}/},{name:"GitHub OAuth token",regex:/gho_[A-Za-z0-9]{36}/},{name:"Slack token",regex:/xox[bpors]-[0-9]{10,}-[A-Za-z0-9-]+/},{name:"Stripe key",regex:/(?:sk|pk)_(?:live|test)_[A-Za-z0-9]{24,}/},{name:"Linear API key",regex:/lin_api_[A-Za-z0-9]{40,}/},{name:"Private key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/},{name:"Database connection string",regex:/(?:mongodb|postgres|mysql|redis):\/\/[^\s"']+:[^\s"']+@/i}],b=[".clancy/.env",".env.local",".env.example",".env.development",".env.test"];function g(e){return b.some(t=>e.endsWith(t))}function A(e){return e?T.filter(({regex:t})=>t.test(e)).map(({name:t})=>t):[]}function w(e){if(!(typeof e=="object"&&e!==null))return;let n=e.new_string;return typeof n=="string"?n:void 0}function d(e,t){if(e==="Write"){let n=t.content;return typeof n=="string"?n:null}if(e==="Edit"){let n=t.new_string;return typeof n=="string"?n:null}if(e==="MultiEdit"){let n=t.edits;return Array.isArray(n)?n.map(w).filter(Boolean).join(`
2
+ `):null}return null}try{let e=c({argv:process.argv,readFileSync:x.readFileSync}),t=e.tool_name??"",n=e.tool_input??{},s=typeof n.file_path=="string"?n.file_path:"",u=d(t,n),y=u!==null,_=s!==""&&g(s);(!y||_)&&(console.log(JSON.stringify(r())),process.exit(0));let p=A(u);if(p.length>0){let k=p.join(", "),S=`Credential guard: blocked writing to ${s}. Detected: ${k}. Move credentials to .clancy/.env instead.`;console.log(JSON.stringify(i(S)))}else console.log(JSON.stringify(r()))}catch{console.log(JSON.stringify(r()))}
@@ -1 +1 @@
1
- "use strict";var u=require("node:fs"),f=require("node:os");function l(t,r){return{hookSpecificOutput:{hookEventName:t,additionalContext:r}}}var x=require("node:stream/consumers");function a(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var p={},D=3e3;function F(t){try{let r=JSON.parse(t);return a(r)?r:p}catch{return p}}function T(t){return new Promise(r=>{setTimeout(()=>r(p),t)})}function d(t){let r=t.timeoutMs??D,n=(0,x.text)(t.stdin).then(F);return Promise.race([n,T(r)])}var P=require("node:path");function h(t){return String(t).replace(/[^a-zA-Z0-9_-]/g,"")}function m(t,r){return(0,P.join)(r.tmpdir(),`clancy-drift-${h(t)}`)}var s=require("node:path");var j=(0,s.join)(".clancy","version.json"),g=(0,s.join)(".claude","commands","clancy","VERSION");function S(t,r){return!t||!r?!1:t.trim()!==r.trim()}function y(t,r){try{return r.readFileSync(t,"utf8")}catch{return null}}function I(t,r){let n=y((0,s.join)(t,j),r);if(!n)return null;try{let o=JSON.parse(n);if(!a(o))return null;let e=o.version;return typeof e=="string"?e:null}catch{return null}}function O(t,r,n){let o=(0,s.join)(t,g),e=(0,s.join)(r,g),i=y(o,n);if(i)return i.trim();let c=y(e,n);return c?c.trim():null}function b(t,r){return`DRIFT WARNING: Clancy runtime files are outdated (runtime: ${t}, commands: ${r}). Run /clancy:update to sync your installation.`}d({stdin:process.stdin}).then(t=>{let r=t.session_id??"";if(!r)return;let n=m(r,{tmpdir:f.tmpdir});try{(0,u.writeFileSync)(n,"1",{flag:"wx"})}catch{return}let o=t.cwd??process.cwd(),e={readFileSync:u.readFileSync},i=I(o,e),c=O(o,(0,f.homedir)(),e);if(!i||!c||!S(i,c))return;let N=b(i,c),w=l("PostToolUse",N);process.stdout.write(JSON.stringify(w))}).catch(()=>{});
1
+ "use strict";var u=require("node:fs"),f=require("node:os");function l(t,r){return{hookSpecificOutput:{hookEventName:t,additionalContext:r}}}var h=require("node:stream/consumers");function a(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var p={},w=3e3;function T(t){try{let r=JSON.parse(t);return a(r)?r:p}catch{return p}}function k(t){return new Promise(r=>{setTimeout(()=>r(p),t)})}function m(t){let r=t.timeoutMs??w,n=(0,h.text)(t.stdin).then(T);return Promise.race([n,k(r)])}var P=require("node:path");function x(t){return String(t).replace(/[^a-zA-Z0-9_-]/g,"")}function d(t,r){return(0,P.join)(r.tmpdir(),`clancy-drift-${x(t)}`)}var s=require("node:path");var F=(0,s.join)(".clancy","version.json"),g=(0,s.join)(".claude","commands","clancy","VERSION");function S(t,r){return!t||!r?!1:t.trim()!==r.trim()}function y(t,r){try{return r.readFileSync(t,"utf8")}catch{return null}}function O(t,r){let n=y((0,s.join)(t,F),r);if(!n)return null;try{let o=JSON.parse(n);if(!a(o))return null;let e=o.version;return typeof e=="string"?e:null}catch{return null}}function I(t,r,n){let o=(0,s.join)(t,g),e=(0,s.join)(r,g),i=y(o,n);if(i)return i.trim();let c=y(e,n);return c?c.trim():null}function D(t,r){return`DRIFT WARNING: Clancy runtime files are outdated (runtime: ${t}, commands: ${r}). Run /clancy:update to sync your installation.`}m({stdin:process.stdin}).then(t=>{let r=t.session_id??"";if(!r)return;let n=d(r,{tmpdir:f.tmpdir});try{(0,u.writeFileSync)(n,"1",{flag:"wx"})}catch{return}let o=t.cwd??process.cwd(),e={readFileSync:u.readFileSync},i=O(o,e),c=I(o,(0,f.homedir)(),e);if(!i||!c||!S(i,c))return;let N=D(i,c),b=l("PostToolUse",N);process.stdout.write(JSON.stringify(b))}).catch(()=>{});
@@ -1,2 +1,2 @@
1
- "use strict";var d=require("node:fs");function c(t,n){return{hookSpecificOutput:{hookEventName:t,additionalContext:n}}}var p=require("node:path");function o(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function s(t,n){let e=(0,p.join)(t,".clancy","lock.json");try{let r=JSON.parse(n.readFileSync(e,"utf8"));return o(r)?r:null}catch{return null}}var m=require("node:stream/consumers");var a={},x=3e3;function P(t){try{let n=JSON.parse(t);return o(n)?n:a}catch{return a}}function T(t){return new Promise(n=>{setTimeout(()=>n(a),t)})}function u(t){let n=t.timeoutMs??x,e=(0,m.text)(t.stdin).then(P);return Promise.race([e,T(n)])}function f(t){let{ticketKey:n,ticketBranch:e}=t;if(!n||!e)return null;let r=t.ticketTitle||"Unknown",i=t.targetBranch??"main",l=t.parentKey!==void 0&&t.parentKey!=="none"&&t.parentKey!==""?`Parent: ${t.parentKey}.`:void 0,y=t.description?`Requirements: ${t.description.slice(0,2e3)}`:void 0;return[`CONTEXT RESTORED: You are implementing ticket [${n}] ${r}.`,`Branch: ${e} targeting ${i}.`,l,y,"Continue your implementation. Do not start over."].filter(Boolean).join(`
2
- `)}u({stdin:process.stdin}).then(t=>{let n=t.cwd??process.cwd(),e=s(n,{readFileSync:d.readFileSync});if(!e)return;let r=f(e);if(!r)return;let i=c("PostCompact",r);process.stdout.write(JSON.stringify(i))}).catch(()=>{});
1
+ "use strict";var d=require("node:fs");function c(t,e){return{hookSpecificOutput:{hookEventName:t,additionalContext:e}}}var p=require("node:path");function r(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function s(t,e){let n=(0,p.join)(t,".clancy","lock.json");try{let o=JSON.parse(e.readFileSync(n,"utf8"));return r(o)?o:null}catch{return null}}var m=require("node:stream/consumers");var a={},P=3e3;function x(t){try{let e=JSON.parse(t);return r(e)?e:a}catch{return a}}function h(t){return new Promise(e=>{setTimeout(()=>e(a),t)})}function u(t){let e=t.timeoutMs??P,n=(0,m.text)(t.stdin).then(x);return Promise.race([n,h(e)])}function f(t){let{ticketKey:e,ticketBranch:n}=t;if(!e||!n)return null;let o=t.ticketTitle||"Unknown",i=t.targetBranch??"main",l=t.parentKey!==void 0&&t.parentKey!=="none"&&t.parentKey!==""?`Parent: ${t.parentKey}.`:void 0,y=t.description?`Requirements: ${t.description.slice(0,2e3)}`:void 0;return[`CONTEXT RESTORED: You are implementing ticket [${e}] ${o}.`,`Branch: ${n} targeting ${i}.`,l,y,"Continue your implementation. Do not start over."].filter(Boolean).join(`
2
+ `)}u({stdin:process.stdin}).then(t=>{let e=t.cwd??process.cwd(),n=s(e,{readFileSync:d.readFileSync});if(!n)return;let o=f(n);if(!o)return;let i=c("PostCompact",o);process.stdout.write(JSON.stringify(i))}).catch(()=>{});
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Autopilot runtime entry point — wire real Node.js I/O into runAutopilot.
3
+ *
4
+ * This file is the entry point for the `clancy-autopilot.js` bundle.
5
+ * Substantially more wiring than the implement entry point: env var
6
+ * parsing, iteration closure (full runImplement call per iteration),
7
+ * session report generation, webhook notifications, and quiet hours.
8
+ *
9
+ * Built by esbuild into a self-contained ESM bundle with zero npm deps.
10
+ */
11
+ import type { ConsoleLike, SpawnSyncFn } from '../shared/types.js';
12
+ import type { CostFs, EnvFileSystem, ExecGit, FetchFn, LockFs, PipelineDeps, PipelineResult, ProgressFs, QualityFs, RunContext } from '@chief-clancy/core';
13
+ import { sendNotification } from '../notify/index.js';
14
+ import { buildSessionReport } from '../session-report/index.js';
15
+ type RunPipelineFn = (ctx: RunContext, deps: PipelineDeps) => Promise<PipelineResult>;
16
+ type IterationOpts = {
17
+ readonly projectRoot: string;
18
+ readonly exec: ExecGit;
19
+ readonly lockFs: LockFs;
20
+ readonly progressFs: ProgressFs;
21
+ readonly costFs: CostFs;
22
+ readonly envFs: EnvFileSystem;
23
+ readonly qualityFs: QualityFs;
24
+ readonly spawn: SpawnSyncFn;
25
+ readonly fetch: FetchFn;
26
+ readonly runPipeline: RunPipelineFn;
27
+ readonly argv: readonly string[];
28
+ };
29
+ type ReportFactoryOpts = {
30
+ readonly progressFs: ProgressFs;
31
+ readonly qualityFs: QualityFs;
32
+ readonly projectRoot: string;
33
+ readonly console: ConsoleLike;
34
+ readonly readCostsFile: (path: string) => string;
35
+ readonly writeFile: (path: string, content: string) => void;
36
+ readonly mkdir: (path: string) => void;
37
+ readonly buildSessionReport: typeof buildSessionReport;
38
+ };
39
+ type SendNotificationFn = typeof sendNotification;
40
+ /**
41
+ * Parse MAX_ITERATIONS from an env var string.
42
+ *
43
+ * Returns the default (5) for missing, empty, non-numeric, zero,
44
+ * or negative values. Floors decimals.
45
+ *
46
+ * @param value - The raw env var value (may be undefined).
47
+ * @returns A positive integer for the iteration cap.
48
+ */
49
+ export declare function parseMaxIterations(value: string | undefined): number;
50
+ /**
51
+ * Build the `runIteration` closure for autopilot.
52
+ *
53
+ * Each call constructs a fresh context and deps, runs the pipeline,
54
+ * and returns the result. Uses `isAfk: true` since autopilot is
55
+ * unattended mode.
56
+ *
57
+ * @param opts - Shared I/O resources for the pipeline.
58
+ * @returns An async function that runs one implement iteration.
59
+ */
60
+ export declare function buildRunIteration(opts: IterationOpts): () => Promise<PipelineResult>;
61
+ /**
62
+ * Build the `buildReport` closure for autopilot.
63
+ *
64
+ * Captures all I/O resources and delegates to `buildSessionReport`
65
+ * with the loop timing parameters.
66
+ *
67
+ * @param opts - Shared I/O resources for report generation.
68
+ * @returns A function that generates a session report markdown string.
69
+ */
70
+ export declare function buildReportFactory(opts: ReportFactoryOpts): (loopStartTime: number, loopEndTime: number) => string;
71
+ /**
72
+ * Build the `sendNotification` closure for autopilot.
73
+ *
74
+ * Captures the fetch function and delegates to the notify module.
75
+ *
76
+ * @param fetchFn - The fetch implementation to use.
77
+ * @param send - The notification sender (injected for testability).
78
+ * @returns An async function matching AutopilotOpts.sendNotification.
79
+ */
80
+ export declare function buildNotify(fetchFn: FetchFn, send?: SendNotificationFn): (url: string, message: string) => Promise<void>;
81
+ export {};
82
+ //# sourceMappingURL=entrypoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../../src/runner/autopilot/entrypoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,OAAO,EACP,OAAO,EACP,MAAM,EACN,YAAY,EACZ,cAAc,EACd,UAAU,EACV,SAAS,EACT,UAAU,EACX,MAAM,oBAAoB,CAAC;AAmB5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAKhE,KAAK,aAAa,GAAG,CACnB,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,YAAY,KACf,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;CACxD,CAAC;AAEF,KAAK,kBAAkB,GAAG,OAAO,gBAAgB,CAAC;AAMlD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKpE;AAID;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,GAClB,MAAM,OAAO,CAAC,cAAc,CAAC,CAsB/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,iBAAiB,GACtB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,CAaxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,kBAAqC,GAC1C,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAEjD"}
@@ -0,0 +1,149 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ import { setTimeout as sleep } from 'node:timers/promises';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { createContext, runPipeline } from '@chief-clancy/core';
7
+ import { buildPipelineDeps } from '../dep-factory/index.js';
8
+ import { makeCostFs, makeEnvFs, makeExecGit, makeLockFs, makeProgressFs, makeQualityFs, } from '../implement/entrypoint.js';
9
+ import { sendNotification } from '../notify/index.js';
10
+ import { buildSessionReport } from '../session-report/index.js';
11
+ import { runAutopilot } from './autopilot.js';
12
+ // ─── Env var parsing ────────────────────────────────────────────────────────
13
+ const DEFAULT_MAX_ITERATIONS = 5;
14
+ /**
15
+ * Parse MAX_ITERATIONS from an env var string.
16
+ *
17
+ * Returns the default (5) for missing, empty, non-numeric, zero,
18
+ * or negative values. Floors decimals.
19
+ *
20
+ * @param value - The raw env var value (may be undefined).
21
+ * @returns A positive integer for the iteration cap.
22
+ */
23
+ export function parseMaxIterations(value) {
24
+ if (!value)
25
+ return DEFAULT_MAX_ITERATIONS;
26
+ const parsed = Math.floor(Number(value));
27
+ return parsed > 0 ? parsed : DEFAULT_MAX_ITERATIONS;
28
+ }
29
+ // ─── Closure factories ──────────────────────────────────────────────────────
30
+ /**
31
+ * Build the `runIteration` closure for autopilot.
32
+ *
33
+ * Each call constructs a fresh context and deps, runs the pipeline,
34
+ * and returns the result. Uses `isAfk: true` since autopilot is
35
+ * unattended mode.
36
+ *
37
+ * @param opts - Shared I/O resources for the pipeline.
38
+ * @returns An async function that runs one implement iteration.
39
+ */
40
+ export function buildRunIteration(opts) {
41
+ return async () => {
42
+ const ctx = createContext({
43
+ projectRoot: opts.projectRoot,
44
+ argv: opts.argv,
45
+ isAfk: true,
46
+ });
47
+ const deps = buildPipelineDeps({
48
+ projectRoot: opts.projectRoot,
49
+ exec: opts.exec,
50
+ lockFs: opts.lockFs,
51
+ progressFs: opts.progressFs,
52
+ costFs: opts.costFs,
53
+ envFs: opts.envFs,
54
+ qualityFs: opts.qualityFs,
55
+ spawn: opts.spawn,
56
+ fetch: opts.fetch,
57
+ });
58
+ return opts.runPipeline(ctx, deps);
59
+ };
60
+ }
61
+ /**
62
+ * Build the `buildReport` closure for autopilot.
63
+ *
64
+ * Captures all I/O resources and delegates to `buildSessionReport`
65
+ * with the loop timing parameters.
66
+ *
67
+ * @param opts - Shared I/O resources for report generation.
68
+ * @returns A function that generates a session report markdown string.
69
+ */
70
+ export function buildReportFactory(opts) {
71
+ return (loopStartTime, loopEndTime) => opts.buildSessionReport({
72
+ progressFs: opts.progressFs,
73
+ qualityFs: opts.qualityFs,
74
+ readCostsFile: opts.readCostsFile,
75
+ writeFile: opts.writeFile,
76
+ mkdir: opts.mkdir,
77
+ console: opts.console,
78
+ projectRoot: opts.projectRoot,
79
+ loopStartTime,
80
+ loopEndTime,
81
+ });
82
+ }
83
+ /**
84
+ * Build the `sendNotification` closure for autopilot.
85
+ *
86
+ * Captures the fetch function and delegates to the notify module.
87
+ *
88
+ * @param fetchFn - The fetch implementation to use.
89
+ * @param send - The notification sender (injected for testability).
90
+ * @returns An async function matching AutopilotOpts.sendNotification.
91
+ */
92
+ export function buildNotify(fetchFn, send = sendNotification) {
93
+ return (url, message) => send({ webhookUrl: url, message, fetch: fetchFn });
94
+ }
95
+ // ─── Main ───────────────────────────────────────────────────────────────────
96
+ async function main() {
97
+ const projectRoot = process.cwd();
98
+ const env = process.env;
99
+ const exec = makeExecGit(projectRoot);
100
+ const lockFs = makeLockFs();
101
+ const progressFs = makeProgressFs();
102
+ const costFs = makeCostFs();
103
+ const envFs = makeEnvFs();
104
+ const qualityFs = makeQualityFs();
105
+ const fetchFn = globalThis.fetch.bind(globalThis);
106
+ const spawnFn = (cmd, args, opts) => spawnSync(cmd, [...args], { ...opts, stdio: [...opts.stdio] });
107
+ await runAutopilot({
108
+ maxIterations: parseMaxIterations(env.MAX_ITERATIONS),
109
+ runIteration: buildRunIteration({
110
+ projectRoot,
111
+ exec,
112
+ lockFs,
113
+ progressFs,
114
+ costFs,
115
+ envFs,
116
+ qualityFs,
117
+ spawn: spawnFn,
118
+ fetch: fetchFn,
119
+ runPipeline,
120
+ argv: process.argv,
121
+ }),
122
+ buildReport: buildReportFactory({
123
+ progressFs,
124
+ qualityFs,
125
+ projectRoot,
126
+ console,
127
+ readCostsFile: (path) => readFileSync(path, 'utf8'),
128
+ writeFile: (path, content) => writeFileSync(path, content, 'utf8'),
129
+ mkdir: (path) => mkdirSync(path, { recursive: true }),
130
+ buildSessionReport,
131
+ }),
132
+ sendNotification: buildNotify(fetchFn),
133
+ sleep: (ms) => sleep(ms),
134
+ console,
135
+ clock: Date.now,
136
+ quietStart: env.CLANCY_QUIET_START,
137
+ quietEnd: env.CLANCY_QUIET_END,
138
+ webhookUrl: env.CLANCY_NOTIFY_WEBHOOK,
139
+ });
140
+ }
141
+ // Main guard — self-execute when run directly (e.g. node .clancy/clancy-autopilot.js)
142
+ if (process.argv[1] &&
143
+ fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
144
+ main().catch((error) => {
145
+ const message = error instanceof Error ? error.message : String(error);
146
+ console.error(message);
147
+ });
148
+ }
149
+ //# sourceMappingURL=entrypoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../../src/runner/autopilot/entrypoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=esbuild.runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esbuild.runtime.d.ts","sourceRoot":"","sources":["../../src/runner/esbuild.runtime.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { mkdirSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { build } from 'esbuild';
5
+ const THIS_DIR = dirname(fileURLToPath(import.meta.url));
6
+ const DIST = join(THIS_DIR, '..', '..', 'dist');
7
+ const DIST_BUNDLE = join(DIST, 'bundle');
8
+ const BUNDLES = [
9
+ {
10
+ entryPoint: join(DIST, 'runner', 'implement', 'entrypoint.js'),
11
+ outfile: join(DIST_BUNDLE, 'clancy-implement.js'),
12
+ },
13
+ {
14
+ entryPoint: join(DIST, 'runner', 'autopilot', 'entrypoint.js'),
15
+ outfile: join(DIST_BUNDLE, 'clancy-autopilot.js'),
16
+ },
17
+ ];
18
+ /**
19
+ * esbuild plugin that stubs zod's locale barrel import.
20
+ *
21
+ * Zod v4 re-exports all ~50 locale modules from `zod/v4/core/index.js`
22
+ * via `export * as locales from "../locales/index.js"`. These are never
23
+ * used at runtime (Clancy uses zod/mini with default English messages).
24
+ *
25
+ * The plugin intercepts any resolve to a `locales/index.js` originating
26
+ * from within the zod package and replaces it with an empty export,
27
+ * saving ~1.2 MB from the final bundle.
28
+ */
29
+ const stubZodLocales = {
30
+ name: 'stub-zod-locales',
31
+ setup(b) {
32
+ b.onResolve({ filter: /locales\/index\.js$/ }, (args) => {
33
+ const isFromZod = args.resolveDir.includes('/zod/');
34
+ return isFromZod
35
+ ? { path: 'zod-locales-stub', namespace: 'zod-stub' }
36
+ : undefined;
37
+ });
38
+ b.onLoad({ filter: /.*/, namespace: 'zod-stub' }, () => ({
39
+ contents: 'export default {};',
40
+ loader: 'js',
41
+ }));
42
+ },
43
+ };
44
+ const SHARED_OPTIONS = {
45
+ bundle: true,
46
+ platform: 'node',
47
+ format: 'esm',
48
+ target: 'node22',
49
+ minify: true,
50
+ treeShaking: true,
51
+ plugins: [stubZodLocales],
52
+ };
53
+ mkdirSync(DIST_BUNDLE, { recursive: true });
54
+ await Promise.all(BUNDLES.map(({ entryPoint, outfile }) => build({ ...SHARED_OPTIONS, entryPoints: [entryPoint], outfile })));
55
+ //# sourceMappingURL=esbuild.runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esbuild.runtime.js","sourceRoot":"","sources":["../../src/runner/esbuild.runtime.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACzD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAChD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAEzC,MAAM,OAAO,GAAG;IACd;QACE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;QAC9D,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC;KAClD;IACD;QACE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;QAC9D,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC;KAClD;CACO,CAAC;AAEX;;;;;;;;;;GAUG;AACH,MAAM,cAAc,GAAW;IAC7B,IAAI,EAAE,kBAAkB;IACxB,KAAK,CAAC,CAAC;QACL,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YACtD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpD,OAAO,SAAS;gBACd,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE;gBACrD,CAAC,CAAC,SAAS,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YACvD,QAAQ,EAAE,oBAAoB;YAC9B,MAAM,EAAE,IAAI;SACb,CAAC,CAAC,CAAC;IACN,CAAC;CACF,CAAC;AAEF,MAAM,cAAc,GAAG;IACrB,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,MAAe;IACzB,MAAM,EAAE,KAAc;IACtB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,IAAI;IACZ,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,CAAC,cAAc,CAAC;CAC1B,CAAC;AAEF,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAE5C,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,CACtC,KAAK,CAAC,EAAE,GAAG,cAAc,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CACjE,CACF,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Implement runtime entry point — wire real Node.js I/O into runImplement.
3
+ *
4
+ * This file is the entry point for the `clancy-implement.js` bundle.
5
+ * It constructs all dependency injection adapters from real Node.js APIs
6
+ * (fs, child_process, fetch) and calls runImplement with the full opts.
7
+ *
8
+ * Built by esbuild into a self-contained ESM bundle with zero npm deps.
9
+ */
10
+ import type { CostFs, EnvFileSystem, ExecGit, LockFs, ProgressFs, QualityFs } from '@chief-clancy/core';
11
+ import type { SpawnSyncReturns } from 'node:child_process';
12
+ type GitSpawnFn = (command: string, args: readonly string[], options: {
13
+ readonly cwd: string;
14
+ readonly encoding: 'utf8';
15
+ }) => SpawnSyncReturns<string>;
16
+ /**
17
+ * Build an ExecGit adapter from a spawn function.
18
+ *
19
+ * Wraps `spawnSync('git', args)` with error handling on non-zero exit.
20
+ *
21
+ * @param cwd - Working directory for git commands.
22
+ * @param spawn - Spawn function (injected for testability).
23
+ * @returns An ExecGit function that throws on failure.
24
+ */
25
+ export declare function makeExecGit(cwd: string, spawn?: GitSpawnFn): ExecGit;
26
+ /** Build a LockFs adapter from real node:fs functions. */
27
+ export declare function makeLockFs(): LockFs;
28
+ /** Build a ProgressFs adapter from real node:fs functions. */
29
+ export declare function makeProgressFs(): ProgressFs;
30
+ /** Build a CostFs adapter from real node:fs functions. */
31
+ export declare function makeCostFs(): CostFs;
32
+ /** Build a QualityFs adapter from real node:fs functions. */
33
+ export declare function makeQualityFs(): QualityFs;
34
+ /** Build an EnvFileSystem adapter from real node:fs functions. */
35
+ export declare function makeEnvFs(): EnvFileSystem;
36
+ export {};
37
+ //# sourceMappingURL=entrypoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../../src/runner/implement/entrypoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,OAAO,EACP,MAAM,EACN,UAAU,EACV,SAAS,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAoB3D,KAAK,UAAU,GAAG,CAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KACzD,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAI9B;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,UAAsB,GAC5B,OAAO,CAiBT;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,IAAI,MAAM,CAOnC;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,IAAI,UAAU,CAM3C;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,IAAI,SAAS,CAOzC;AAED,kEAAkE;AAClE,wBAAgB,SAAS,IAAI,aAAa,CAIzC"}
@@ -0,0 +1,98 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { appendFileSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { runPipeline } from '@chief-clancy/core';
6
+ import { runImplement } from './implement.js';
7
+ // ─── Adapter factories ──────────────────────────────────────────────────────
8
+ /**
9
+ * Build an ExecGit adapter from a spawn function.
10
+ *
11
+ * Wraps `spawnSync('git', args)` with error handling on non-zero exit.
12
+ *
13
+ * @param cwd - Working directory for git commands.
14
+ * @param spawn - Spawn function (injected for testability).
15
+ * @returns An ExecGit function that throws on failure.
16
+ */
17
+ export function makeExecGit(cwd, spawn = spawnSync) {
18
+ return (args) => {
19
+ const result = spawn('git', [...args], { cwd, encoding: 'utf8' });
20
+ if (result.status !== 0) {
21
+ const cmd = args[0] ?? 'unknown';
22
+ const code = result.status ?? 'null';
23
+ const detail = result.stderr?.trim();
24
+ const message = detail
25
+ ? `git ${cmd} failed (exit ${code}): ${detail}`
26
+ : `git ${cmd} failed (exit ${code})`;
27
+ throw new Error(message);
28
+ }
29
+ return result.stdout.trim();
30
+ };
31
+ }
32
+ /** Build a LockFs adapter from real node:fs functions. */
33
+ export function makeLockFs() {
34
+ return {
35
+ readFile: (path) => readFileSync(path, 'utf8'),
36
+ writeFile: (path, content) => writeFileSync(path, content, 'utf8'),
37
+ deleteFile: (path) => unlinkSync(path),
38
+ mkdir: (path) => mkdirSync(path, { recursive: true }),
39
+ };
40
+ }
41
+ /** Build a ProgressFs adapter from real node:fs functions. */
42
+ export function makeProgressFs() {
43
+ return {
44
+ readFile: (path) => readFileSync(path, 'utf8'),
45
+ appendFile: (path, content) => appendFileSync(path, content, 'utf8'),
46
+ mkdir: (path) => mkdirSync(path, { recursive: true }),
47
+ };
48
+ }
49
+ /** Build a CostFs adapter from real node:fs functions. */
50
+ export function makeCostFs() {
51
+ return {
52
+ appendFile: (path, content) => appendFileSync(path, content, 'utf8'),
53
+ mkdir: (path) => mkdirSync(path, { recursive: true }),
54
+ };
55
+ }
56
+ /** Build a QualityFs adapter from real node:fs functions. */
57
+ export function makeQualityFs() {
58
+ return {
59
+ readFile: (path) => readFileSync(path, 'utf8'),
60
+ writeFile: (path, content) => writeFileSync(path, content, 'utf8'),
61
+ rename: (from, to) => renameSync(from, to),
62
+ mkdir: (path) => mkdirSync(path, { recursive: true }),
63
+ };
64
+ }
65
+ /** Build an EnvFileSystem adapter from real node:fs functions. */
66
+ export function makeEnvFs() {
67
+ return {
68
+ readFile: (path) => readFileSync(path, 'utf8'),
69
+ };
70
+ }
71
+ // ─── Main ───────────────────────────────────────────────────────────────────
72
+ async function main() {
73
+ const projectRoot = process.cwd();
74
+ await runImplement({
75
+ argv: process.argv,
76
+ projectRoot,
77
+ isAfk: false,
78
+ exec: makeExecGit(projectRoot),
79
+ lockFs: makeLockFs(),
80
+ progressFs: makeProgressFs(),
81
+ costFs: makeCostFs(),
82
+ envFs: makeEnvFs(),
83
+ qualityFs: makeQualityFs(),
84
+ spawn: (cmd, args, opts) => spawnSync(cmd, [...args], { ...opts, stdio: [...opts.stdio] }),
85
+ fetch: globalThis.fetch.bind(globalThis),
86
+ runPipeline,
87
+ console,
88
+ });
89
+ }
90
+ // Main guard — self-execute when run directly (e.g. node .clancy/clancy-implement.js)
91
+ if (process.argv[1] &&
92
+ fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
93
+ main().catch((error) => {
94
+ const message = error instanceof Error ? error.message : String(error);
95
+ console.error(message);
96
+ });
97
+ }
98
+ //# sourceMappingURL=entrypoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../../src/runner/implement/entrypoint.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chief-clancy/terminal",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Installer, slash commands, hooks, AFK runner, agents, Claude CLI bridge",
5
5
  "author": "Alex Clapperton",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "esbuild": "^0.27.4"
44
44
  },
45
45
  "scripts": {
46
- "build": "rm -rf dist tsconfig.build.tsbuildinfo && tsc --project tsconfig.build.json && tsc-alias --project tsconfig.build.json && node dist/hooks/esbuild.hooks.js",
46
+ "build": "rm -rf dist tsconfig.build.tsbuildinfo && tsc --project tsconfig.build.json && tsc-alias --project tsconfig.build.json && node dist/hooks/esbuild.hooks.js && node dist/runner/esbuild.runtime.js",
47
47
  "test": "vitest run",
48
48
  "test:e2e": "vitest run --config vitest.config.e2e.ts",
49
49
  "lint": "eslint .",