@senlabsai/aigon-pro 0.1.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.
Files changed (3) hide show
  1. package/README.md +20 -0
  2. package/dist/index.js +54 -0
  3. package/package.json +27 -0
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @senlabsai/aigon-pro
2
+
3
+ > **Private beta** — access by invitation only
4
+
5
+ Aigon Pro is the analytics and AI coaching layer for Aigon: insights engine, dashboard analytics, and AI-driven performance coaching.
6
+
7
+ ## Installation
8
+
9
+ See **[docs/pro-installation.md](docs/pro-installation.md)** for full setup instructions.
10
+
11
+ In short:
12
+
13
+ 1. Get your GitHub account added to the beta (email `john@aigon.build` with your GitHub username)
14
+ 2. Create a GitHub PAT with `read:packages` scope
15
+ 3. Add `@senlabsai:registry=https://npm.pkg.github.com` to your `.npmrc`
16
+ 4. `npm install @senlabsai/aigon-pro`
17
+
18
+ ## Beta access
19
+
20
+ Want in? See [Want access?](docs/pro-installation.md#want-access) in the installation guide.
package/dist/index.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";var to=Object.create;var Jt=Object.defineProperty;var no=Object.getOwnPropertyDescriptor;var ro=Object.getOwnPropertyNames;var oo=Object.getPrototypeOf,so=Object.prototype.hasOwnProperty;var T=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var io=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ro(t))!so.call(e,o)&&o!==n&&Jt(e,o,{get:()=>t[o],enumerable:!(r=no(t,o))||r.enumerable});return e};var co=(e,t,n)=>(n=e!=null?to(oo(e)):{},io(t||!e||!e.__esModule?Jt(n,"default",{value:e,enumerable:!0}):n,e));var en=T((Ki,Xt)=>{"use strict";var L=require("fs"),z=require("path"),Ht=z.join(".aigon","insights-cache.json"),ao="claude-3-5-sonnet-latest",Yt=.1;function me(e){if(e==null||e==="")return null;let t=Number(e);return Number.isFinite(t)?t:null}function lo(e){let t=String(e||"").trim();return t?t==="true"?!0:t==="false"?!1:t==="null"||t==="~"?null:/^-?\d+(\.\d+)?$/.test(t)?Number(t):t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t:""}function uo(e){let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);if(!t)return{};let n={};return t[1].split(/\r?\n/).forEach(r=>{let o=r.trim();if(!o||o.startsWith("#"))return;let s=r.indexOf(":");if(s===-1)return;let i=r.slice(0,s).trim(),c=r.slice(s+1).trim();i&&(n[i]=lo(c))}),n}function fo(e,t){if(t&&t.completedAt){let n=Date.parse(t.completedAt);if(!Number.isNaN(n))return n}try{return L.statSync(e).mtime.getTime()}catch{return 0}}function go(e){if(!e||!L.existsSync(e))return{};try{return uo(L.readFileSync(e,"utf8"))}catch{return{}}}function po({logsDir:e,featureId:t,winnerAgent:n}){if(!L.existsSync(e))return null;let r=L.readdirSync(e).filter(o=>o.startsWith(`feature-${t}-`)&&o.endsWith("-log.md")).sort();if(r.length===0)return null;if(n){let o=r.find(s=>s.includes(`-${n}-`));if(o)return z.join(e,o)}return z.join(e,r[0])}function ho(e,t){let n=z.join(e,".aigon","state",`feature-${t}.json`);if(!L.existsSync(n))return null;try{return JSON.parse(L.readFileSync(n,"utf8")).winner||null}catch{return null}}function Gt(e=process.cwd()){let t=z.join(e,"docs","specs","features","05-done"),n=z.join(e,"docs","specs","features","logs");return L.existsSync(t)?L.readdirSync(t).filter(s=>/^feature-\d+-.+\.md$/.test(s)).sort().map(s=>{let i=s.match(/^feature-(\d+)-(.+)\.md$/);if(!i)return null;let c=i[1],l=i[2],a=ho(e,c),u=po({logsDir:n,featureId:c,winnerAgent:a}),p=go(u),f=fo(z.join(t,s),p),h=p.rework_thrashing===!0,d=p.rework_fix_cascade===!0,g=p.rework_scope_creep===!0;return{featureId:c,name:l,completedAtMs:f,costUsd:me(p.cost_usd),tokensPerLineChanged:me(p.tokens_per_line_changed),totalTokens:me(p.total_tokens),linesChanged:me(p.lines_changed),autonomyLabel:p.autonomy_label?String(p.autonomy_label):null,reworkThrashing:h,reworkFixCascade:d,reworkScopeCreep:g,hasRework:h||d||g}}).filter(Boolean).sort((s,i)=>s.completedAtMs-i.completedAtMs):[]}function Wt(e){if(!e||e.length<3)return null;let t=Math.floor(e.length/2),n=e.slice(0,t),r=e.slice(t);if(n.length===0||r.length===0)return null;let o=n.reduce((c,l)=>c+l,0)/n.length,s=r.reduce((c,l)=>c+l,0)/r.length;if(o===0)return null;let i=(s-o)/o*100;return{direction:i>5?"up":i<-5?"down":"flat",deltaPct:i,olderAvg:o,recentAvg:s}}function Vt(e){let t=Math.round(e);return t>0?`+${t}%`:`${t}%`}function mo(e){let t=e.filter(i=>i.costUsd!==null),n=e.filter(i=>i.totalTokens!==null),r=t.length>0?t.reduce((i,c)=>i+c.costUsd,0)/t.length:null,o=n.length>0?n.reduce((i,c)=>i+c.totalTokens,0)/n.length:null,s=[];return e.forEach(i=>{r&&i.costUsd!==null&&i.costUsd>=r*3&&s.push({featureId:i.featureId,name:i.name,metric:"cost",value:i.costUsd,baseline:r}),o&&i.totalTokens!==null&&i.totalTokens>=o*3&&s.push({featureId:i.featureId,name:i.name,metric:"tokens",value:i.totalTokens,baseline:o})}),{outliers:s,avgCost:r,avgTokens:o}}function zt(e){let t=e.length;if(t<3)return{generatedAt:new Date().toISOString(),insufficientData:!0,observations:[],summary:`Not enough data for insights yet (${t}/3 completed features).`,aggregates:{totalFeatures:t}};let n=e.slice(-5),r=n.map(d=>d.costUsd).filter(d=>d!==null),o=Wt(r),s=n.map(d=>d.tokensPerLineChanged).filter(d=>d!==null),i=Wt(s),c=e.filter(d=>d.reworkThrashing===!0||d.reworkFixCascade===!0||d.reworkScopeCreep===!0||d.reworkThrashing===!1||d.reworkFixCascade===!1||d.reworkScopeCreep===!1),l=c.length>0?c.filter(d=>d.hasRework).length/c.length:null,a={fullAutonomy:0,thrashing:0,other:0};e.forEach(d=>{let g=(d.autonomyLabel||"").toLowerCase();g&&(g.includes("full autonomy")?a.fullAutonomy+=1:g.includes("thrashing")?a.thrashing+=1:a.other+=1)});let{outliers:u,avgCost:p,avgTokens:f}=mo(e),h=[];return h.push({id:"cost-trend",title:"Cost trend (last 5 features)",severity:o?o.direction==="up"?"warn":"good":"info",observation:o?`Average cost moved ${Vt(o.deltaPct)} (${o.olderAvg.toFixed(3)} -> ${o.recentAvg.toFixed(3)} USD).`:"Not enough cost telemetry to establish a trend.",action:o?o.direction==="up"?"Review prompt size and model selection on recent costly features.":"Keep current prompting approach; cost trend is stable or improving.":"Ensure cost telemetry is captured on feature-close."}),h.push({id:"token-efficiency-trend",title:"Token efficiency trend (tokens per line changed)",severity:i?i.direction==="up"?"warn":"good":"info",observation:i?`Efficiency moved ${Vt(i.deltaPct)} (${i.olderAvg.toFixed(1)} -> ${i.recentAvg.toFixed(1)} tokens/line).`:"Not enough tokens_per_line_changed data to establish a trend.",action:i?i.direction==="up"?"Investigate high-token edits: break work into smaller scoped features.":"Efficiency is improving; preserve current implementation cadence.":"Capture total_tokens and lines_changed for each completed feature."}),h.push({id:"rework-frequency",title:"Rework frequency",severity:l===null?"info":l>=.35?"warn":"good",observation:l===null?"No rework flags found in recent feature logs.":`${Math.round(l*100)}% of features triggered rework flags.`,action:l===null?"Enable git signal capture during feature-close to unlock rework insights.":l>=.35?"Raise acceptance-criteria specificity before implementation begins.":"Current rework rate is healthy; keep spec quality consistent."}),h.push({id:"autonomy-distribution",title:"Autonomy distribution",severity:a.thrashing>a.fullAutonomy?"warn":"good",observation:`Full Autonomy: ${a.fullAutonomy}, Thrashing: ${a.thrashing}, Other: ${a.other}.`,action:a.thrashing>a.fullAutonomy?"When thrashing spikes, reduce batch size and validate after each criterion.":"Autonomy profile is healthy; consider expanding autonomous loops where safe."}),h.push({id:"outlier-detection",title:"Cost/token outliers (3x baseline)",severity:u.length>0?"warn":"good",observation:u.length===0?"No 3x cost or token outliers detected.":u.map(d=>`#${d.featureId} ${d.name} (${d.metric}: ${d.metric==="cost"?`$${d.value.toFixed(3)}`:Math.round(d.value)})`).join(" | "),action:u.length===0?"Keep monitoring for sudden spikes as volume grows.":"Review outlier specs/logs to identify prompt bloat, scope creep, or retries."}),{generatedAt:new Date().toISOString(),insufficientData:!1,observations:h,summary:"Rule-based insights generated successfully.",aggregates:{totalFeatures:t,reworkRate:l,autonomyCounts:a,avgCost:p,avgTokens:f}}}function Kt(e={}){let n=[e.tier,e.license&&e.license.tier,e.aade&&e.aade.tier].find(Boolean);return String(n||"free").toLowerCase()}async function Qt({report:e,projectConfig:t={},apiKey:n=process.env.ANTHROPIC_API_KEY}){if(!n)return{ok:!1,error:"ANTHROPIC_API_KEY is not set. Set it to enable --coach."};let r=String(t.insights&&t.insights.coachModel||ao),o={model:r,max_tokens:450,temperature:.2,system:["You are a developer workflow coach.","Given aggregated AI development metrics, return 3-5 concrete recommendations.","Focus on actionable, specific, low-ambiguity guidance.","Each recommendation must begin with a verb."].join(" "),messages:[{role:"user",content:[{type:"text",text:`Generate coaching recommendations from this AADE summary:
2
+ ${JSON.stringify(e,null,2)}`}]}]},s=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"content-type":"application/json","anthropic-version":"2023-06-01","x-api-key":n},body:JSON.stringify(o)});if(!s.ok){let a=await s.text();return{ok:!1,error:`Claude API request failed (${s.status}): ${a.slice(0,240)}`}}let i=await s.json(),c=Array.isArray(i.content)?i.content.filter(a=>a&&a.type==="text").map(a=>a.text).join(`
3
+ `).trim():"",l=c.split(/\r?\n/).map(a=>a.replace(/^\s*[-*\d.)]+\s*/,"").trim()).filter(Boolean).slice(0,5);return{ok:!0,model:r,recommendations:l,rawText:c}}function rt(e=process.cwd()){return z.join(e,Ht)}function yo(e=process.cwd()){let t=rt(e);if(!L.existsSync(t))return null;try{return JSON.parse(L.readFileSync(t,"utf8"))}catch{return null}}function Zt(e,t=process.cwd()){let n=rt(t);L.mkdirSync(z.dirname(n),{recursive:!0}),L.writeFileSync(n,`${JSON.stringify(e,null,2)}
4
+ `)}async function So({repoPath:e=process.cwd(),includeCoaching:t=!1,loadProjectConfig:n}={}){let r=n?n():{},o=Kt(r),s=Gt(e),i=zt(s),c={generatedAt:new Date().toISOString(),source:"aigon-insights",tier:o,report:i,coaching:null};return t&&(o!=="pro"?c.coaching={ok:!1,gated:!0,error:'AI coaching requires tier "pro" in .aigon/config.json.'}:c.coaching=await Qt({report:i,projectConfig:r})),Zt(c,e),c}function wo(e={}){let t=me(e.insights&&e.insights.costCapUsd);return t!==null&&t>0?t:Yt}function ko(e,{includeCoaching:t=!1}={}){if(!e||!e.report)return"No insights available.";let n=[];if(n.push("AADE Insights"),n.push(""),n.push(`Generated: ${e.generatedAt||new Date().toISOString()}`),n.push(`Tier: ${e.tier||"free"}`),n.push(""),e.report.insufficientData)return n.push(e.report.summary),n.join(`
5
+ `);if((e.report.observations||[]).forEach((r,o)=>{let s=(r.severity||"info").toUpperCase();n.push(`${o+1}. [${s}] ${r.title}`),n.push(` ${r.observation}`),n.push(` Action: ${r.action}`)}),t){n.push(""),n.push("AI Coaching");let r=e.coaching||{};r.gated?n.push(`- ${r.error}`):r.ok?Array.isArray(r.recommendations)&&r.recommendations.length>0?r.recommendations.slice(0,5).forEach((o,s)=>{n.push(`${s+1}. ${o}`)}):n.push("- No coaching recommendations returned."):n.push(`- ${r.error||"Coaching unavailable."}`)}return n.join(`
6
+ `)}Xt.exports={CACHE_RELATIVE_PATH:Ht,DEFAULT_COST_CAP_USD:Yt,collectAadeFeatures:Gt,buildDeterministicInsights:zt,resolveTier:Kt,generateCoaching:Qt,getCachePath:rt,readInsightsCache:yo,writeInsightsCache:Zt,generateAndCacheInsights:So,getCostCap:wo,formatInsightsForCli:ko}});var on=T((Qi,rn)=>{"use strict";var te=require("fs"),Z=require("path"),ce=[{id:"implement",seed:"brewboard",featureId:"07",label:"Implementation"},{id:"review",seed:"brewboard-review",featureId:"08",label:"Review"}];function ot(e){return Z.join(e,".aigon","benchmarks")}function st(e){let t=ot(e);return te.existsSync(t)?te.readdirSync(t).filter(n=>n.endsWith(".json")&&n!=="baseline.json"&&!n.startsWith("all-")).map(n=>Z.join(t,n)):[]}function it(e){let t=ot(e);return te.existsSync(t)?te.readdirSync(t).filter(n=>n.endsWith(".json")&&n.startsWith("all-")).map(n=>Z.join(t,n)):[]}function bo(e){return st(e).length>0||it(e).length>0}function Ao(e){let t=Z.basename(e);for(let n of ce)if(t.startsWith("all-"+n.seed+"-")||t==="all-"+n.seed+".json")return n.id;return null}function tn(e){try{return JSON.parse(te.readFileSync(e,"utf8"))}catch{return null}}function nn(e){if(!e||typeof e!="object")return null;let t=String(e.seed||""),n=String(e.featureId||"");for(let r of ce)if(t===r.seed&&n===r.featureId)return r.id;return null}function vo(e,t){let n=e&&e.timestamp;if(n){let r=new Date(n).getTime();if(!Number.isNaN(r))return r}try{return te.statSync(t).mtimeMs}catch{return 0}}function ye(e,t){return`${String(e||"")}\0${t==null?"":String(t)}`}function $o(e){if(!e||typeof e!="object")return null;let t=Number(e.inputTokens||0),n=Number(e.cachedInputTokens||0),r=Number(e.freshInputTokens!=null?e.freshInputTokens:Math.max(0,t-n)),o=Number(e.outputTokens||0),s=Number(e.thinkingTokens||0),i=Number(e.totalTokens||0),c=Number(e.billableTokens!=null?e.billableTokens:t+o+s),l=Number(e.sessions||0),a=Number(e.costUsd||0),u=e.model!=null?String(e.model):null;return!(t>0||n>0||o>0||s>0||i>0||c>0||l>0||a>0)&&!u?null:{inputTokens:t,cachedInputTokens:n,freshInputTokens:r,outputTokens:o,thinkingTokens:s,totalTokens:i,billableTokens:c,sessions:l,costUsd:Math.round(a*1e4)/1e4,model:u}}function jo(e){if(!e||typeof e!="object")return null;let t=e.score!=null?Number(e.score):null;return t==null||Number.isNaN(t)?null:{kind:e.kind||"implementation",rubricId:e.rubricId||null,rubricVersion:e.rubricVersion||null,score:Math.round(t*100)/100,summary:e.summary||"",judge:e.judge||null,assessedAt:e.assessedAt||null}}function Ro(){try{let e=require("@senlabsai/aigon/lib/perf-bench");if(e&&typeof e.collectAllPairs=="function")return e.collectAllPairs([])}catch{}return[]}function Fo(e){let t=Z.resolve(e),n=st(t),r=new Map;for(let f of ce)r.set(f.id,new Map);for(let f of n){let h=tn(f),d=nn(h);if(!d||h.agent==null)continue;let g=String(h.agent||""),w=h.model==null?"":String(h.model),m=ye(g,w===""?null:w),y=vo(h,f),k=Z.relative(t,f).replace(/\\/g,"/"),v=r.get(d),E=v.get(m);(!E||y>E.tk)&&v.set(m,{record:h,tk:y,rel:k})}let o=new Map,s=it(t);for(let f of s){let h=Ao(f);if(!h)continue;let d=tn(f);if(!d||!Array.isArray(d.pairs))continue;let g=(()=>{try{return te.statSync(f).mtimeMs}catch{return 0}})(),w=Z.relative(t,f).replace(/\\/g,"/"),m=(()=>{let y=Z.basename(f).match(/(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d+Z)/);if(!y)return null;let k=y[1].replace(/-(\d{2})-(\d{2})-(\d+)Z$/,":$1:$2.$3Z"),v=Date.parse(k);return Number.isNaN(v)?null:new Date(v).toISOString()})();for(let y of d.pairs){let k=String(y.agentId||""),v=y.modelValue==null?"":String(y.modelValue),E=ye(k,v===""?null:v);y.modelLabel&&o.set(E,String(y.modelLabel));let j=r.get(h);j.has(E)||j.set(E,{record:{agent:k,model:v||null,totalMs:y.totalMs!=null?y.totalMs:null,ok:y.ok!==!1,error:y.error||null,timestamp:m,aigonVersion:d.aigonVersion||null},tk:g,rel:w})}}let i=Ro(),c=new Set;for(let f of i)c.add(ye(f.agentId,f.modelValue));for(let f of r.values())for(let h of f.keys())c.add(h);let l=new Map,a=0;for(let f of i)l.set(ye(f.agentId,f.modelValue),a++);let u=Array.from(c).sort((f,h)=>{let d=l.has(f)?l.get(f):1e9,g=l.has(h)?l.get(h):1e9;if(d!==g)return d-g;let[w,m]=f.split("\0"),[y,k]=h.split("\0");return w!==y?w.localeCompare(y):String(m).localeCompare(String(k))}),p=[];for(let f of u){let h=f.indexOf("\0"),d=f.slice(0,h),g=f.slice(h+1),w=g===""?null:g,m=i.find(j=>j.agentId===d&&String(j.modelValue||"")===String(w||"")),y=m?m.modelLabel:o.get(f)||w||"default",k=r.get("implement").get(f),v=r.get("review").get(f);!m&&k&&!w&&(y=k.record.model!=null?String(k.record.model):"default"),!m&&!k&&v&&!w&&(y=v.record.model!=null?String(v.record.model):"default");let E={implement:null,review:null};for(let j of ce){let O=r.get(j.id).get(f);if(!O)continue;let I=O.record;E[j.id]={timestamp:I.timestamp||null,totalMs:I.totalMs!=null?I.totalMs:null,phases:Array.isArray(I.phases)?I.phases:null,ok:I.ok!==!1,error:I.error||null,tokenUsage:$o(I.tokenUsage),quality:jo(I.quality),sourceFileRelative:O.rel,aigonVersion:I.aigonVersion||null,effort:I.effort!=null?I.effort:null}}p.push({agentId:d,modelValue:w,modelLabel:y,cells:E})}return{kinds:ce.map(({id:f,seed:h,featureId:d,label:g})=>({id:f,seed:h,featureId:d,label:g})),rows:p}}rn.exports={getBenchmarksDir:ot,listBenchmarkJsonFiles:st,listAggregateJsonFiles:it,repoHasBenchmarks:bo,buildLatestMatrix:Fo,matchKind:nn,BENCHMARK_KINDS:ce,_pairKey:ye}});var ct=T((Zi,sn)=>{"use strict";sn.exports=require("@senlabsai/aigon/lib/config")});var fn=T((Xi,un)=>{"use strict";var P=require("fs"),C=require("path"),an=require("crypto"),Eo=/(heartbeat|\.lock$|\.tmp$|\.temp$|\.pid$)/i;function _e(e){let t=[];if(!P.existsSync(e))return t;let n=[""];for(;n.length>0;){let r=n.pop(),o=C.join(e,r);P.readdirSync(o,{withFileTypes:!0}).forEach(i=>{let c=r?C.join(r,i.name):i.name;i.isDirectory()?n.push(c):i.isFile()&&t.push(c)})}return t.sort()}function ne(e){P.mkdirSync(C.dirname(e),{recursive:!0})}function Te(e){try{return JSON.parse(P.readFileSync(e,"utf8"))}catch{return null}}function at(e,t){ne(e),P.writeFileSync(e,`${JSON.stringify(t,null,2)}
7
+ `,"utf8")}function cn(e){let t=P.readFileSync(e);return an.createHash("sha1").update(t).digest("hex")}function Po(e,t){let n=new Set,r=[];return[...e,...t].forEach(o=>{let s=JSON.stringify(o);n.has(s)||(n.add(s),r.push(o))}),r}function lt(e,t){if(Array.isArray(e)&&Array.isArray(t))return Po(e,t);if(e&&t&&typeof e=="object"&&typeof t=="object"&&!Array.isArray(e)&&!Array.isArray(t)){let n={...e};return Object.keys(t).forEach(r=>{Object.prototype.hasOwnProperty.call(n,r)?n[r]=lt(n[r],t[r]):n[r]=t[r]}),n}return e!==void 0?e:t}function Co(e,t){let n=P.existsSync(e)?P.readFileSync(e,"utf8").split(`
8
+ `).filter(Boolean):[],r=P.existsSync(t)?P.readFileSync(t,"utf8").split(`
9
+ `).filter(Boolean):[],o=new Set,s=[];[...n,...r].forEach(i=>{let c=i.trim();if(!c)return;let l=an.createHash("sha1").update(c).digest("hex");o.has(l)||(o.add(l),s.push(c))}),ne(e),P.writeFileSync(e,`${s.join(`
10
+ `)}${s.length>0?`
11
+ `:""}`,"utf8")}function ln(e,t){let n=l=>P.existsSync(l)?P.readFileSync(l,"utf8").split(`
12
+ `).filter(Boolean):[],r=n(e),o=n(t),s=new Set,i=[];[...r,...o].forEach(l=>{let a=l.trim();if(!a||s.has(a))return;s.add(a);let u=null;try{u=JSON.parse(a).t||null}catch{}i.push({line:a,t:u})}),i.sort((l,a)=>l.t===null&&a.t===null?0:l.t===null?1:a.t===null||l.t<a.t?-1:l.t>a.t?1:0),ne(e);let c=i.map(l=>l.line);P.writeFileSync(e,`${c.join(`
13
+ `)}${c.length>0?`
14
+ `:""}`,"utf8")}function Io(e,t,n){_e(t).forEach(o=>{let s=C.join(t,o),i=C.join(e,o);if(o.endsWith(".jsonl")){ln(i,s),n.telemetryFilesAdded+=1;return}if(!P.existsSync(i)){ne(i),P.copyFileSync(s,i),n.telemetryFilesAdded+=1;return}if(cn(i)===cn(s))return;let c=C.extname(i),a=`${c?i.slice(0,-c.length):i}.imported-${Date.now()}${c}`;ne(a),P.copyFileSync(s,a),n.telemetryFilesConflictCopied+=1})}function xo(e,t,n){_e(t).forEach(s=>{let i=C.join(t,s),c=C.join(e,s),l=C.basename(s);if(l!=="lock"){if(l==="events.jsonl"){Co(c,i),n.workflowEventLogsMerged+=1;return}l==="snapshot.json"||l==="stats.json"||P.existsSync(c)||(ne(c),P.copyFileSync(i,c),n.workflowFilesAdded+=1)}}),_e(e).forEach(s=>{let i=C.basename(s);(i==="snapshot.json"||i==="stats.json")&&(P.rmSync(C.join(e,s),{force:!0}),n.derivedFilesCleared+=1)})}function _o(e,t,n){_e(t).forEach(o=>{let s=C.join(t,o),i=C.join(e,o),c=C.basename(o);if(Eo.test(c))return;if(!P.existsSync(i)){ne(i),P.copyFileSync(s,i),n.stateFilesAdded+=1;return}if(C.extname(c).toLowerCase()!==".json")return;let l=Te(i),a=Te(s);if(!l||!a)return;let u=lt(l,a);at(i,u),n.stateFilesMerged+=1})}function To(e,t,n){let r=Te(t);if(!r)return;if(!P.existsSync(e)){at(e,r),n.configMerged+=1;return}let o=Te(e)||{},s=lt(o,r);at(e,s),n.configMerged+=1}function Do(e,t){let n=C.join(e,".aigon","cache");P.existsSync(n)&&(P.rmSync(n,{recursive:!0,force:!0}),t.cacheDirsCleared+=1)}function Oo({bundleRoot:e,repoPathById:t}){let n=C.join(e,"repos"),r={reposMerged:0,reposSkipped:[],telemetryFilesAdded:0,telemetryFilesConflictCopied:0,workflowEventLogsMerged:0,workflowFilesAdded:0,stateFilesAdded:0,stateFilesMerged:0,configMerged:0,derivedFilesCleared:0,cacheDirsCleared:0};return P.existsSync(n)&&P.readdirSync(n).forEach(o=>{let s=C.join(n,o,".aigon");if(!P.existsSync(s))return;let i=t[o];if(!i||!P.existsSync(i)){r.reposSkipped.push(o);return}let c=C.join(i,".aigon");P.mkdirSync(c,{recursive:!0}),Io(C.join(c,"telemetry"),C.join(s,"telemetry"),r),xo(C.join(c,"workflows"),C.join(s,"workflows"),r),_o(C.join(c,"state"),C.join(s,"state"),r),To(C.join(c,"config.json"),C.join(s,"config.json"),r),Do(i,r),r.reposMerged+=1}),r}un.exports={mergeBundleIntoRepos:Oo,mergeJsonlByTimestamp:ln}});var vn=T((ec,An)=>{"use strict";var R=require("fs"),S=require("path"),Me=require("os"),No=require("crypto"),{execFileSync:qe}=require("child_process"),{loadGlobalConfig:Mo,saveGlobalConfig:pn,DEFAULT_GLOBAL_CONFIG:qo,GLOBAL_CONFIG_PATH:Bo}=ct(),{mergeBundleIntoRepos:Lo}=fn(),Y=1,D=require("@senlabsai/aigon/package.json").version,ut=/(heartbeat|\.lock$|\.tmp$|\.temp$|\.pid$)/i;function K(){return new Date().toISOString()}function Se(){return Me.hostname()||"unknown-host"}function W(e){R.mkdirSync(e,{recursive:!0})}function ae(e,t=null){if(!R.existsSync(e))return t;try{return JSON.parse(R.readFileSync(e,"utf8"))}catch{return t}}function we(e,t){W(S.dirname(e)),R.writeFileSync(e,`${JSON.stringify(t,null,2)}
15
+ `,"utf8")}function Uo(e){return e.split(S.sep).join("/")}function hn(e){if(!e)return null;let t=String(e).trim();if(t=t.replace(/\.git$/i,""),t=t.replace(/^https?:\/\//i,""),t=t.replace(/^ssh:\/\//i,""),/^[^@]+@[^:]+:.+$/.test(t)){let n=t.indexOf("@");t=t.slice(n+1).replace(":","/")}return/^[^@/]+@/.test(t)&&(t=t.slice(t.indexOf("@")+1)),t.replace(/\/+$/,"").toLowerCase()}function mn(e){return String(e||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo"}function X(e,t,n={}){let r=qe("git",["-C",e,...t],{encoding:"utf8",stdio:["ignore","pipe","pipe"],...n});return typeof r=="string"?r.trim():""}function G(e,t){try{return{ok:!0,output:X(e,t)}}catch(n){return{ok:!1,output:(n&&n.stderr?String(n.stderr):String(n.message||"")).trim()}}}function Jo(e){return JSON.parse(JSON.stringify(e))}function Be(){let e=Mo();return!e||Object.keys(e).length===0?Jo(qo):e}function ft(e){return e&&typeof e.sync=="object"&&e.sync?e.sync:null}function ke(e){let t=Be();t.sync=e,pn(t)}function Wo(e){let t=mn(hn(e)||S.basename(e||"sync-repo"));return S.join(Me.homedir(),".aigon","sync",t)}function Vo(e){let t=G(e,["remote","get-url","origin"]);return t.ok?t.output:null}function Ho(e){let t=Vo(e),n=hn(t);if(n)return{id:mn(n),originUrl:t};let r=S.resolve(e);return{id:`local-${No.createHash("sha1").update(r).digest("hex").slice(0,12)}`,originUrl:null}}function Ne(e){let t=[];if(!R.existsSync(e))return t;let n=[""];for(;n.length>0;){let r=n.pop(),o=S.join(e,r);R.readdirSync(o,{withFileTypes:!0}).forEach(i=>{let c=r?S.join(r,i.name):i.name;i.isDirectory()?n.push(c):i.isFile()&&t.push(c)})}return t.sort()}function Yo(e){let t=S.join(e,".aigon");if(!R.existsSync(t))return[];let n=[],r=[t];for(;r.length>0;){let o=r.pop();R.readdirSync(o,{withFileTypes:!0}).forEach(i=>{let c=S.join(o,i.name);if(i.isDirectory())r.push(c);else if(i.isFile()){let l=Uo(S.relative(t,c));(l.startsWith("locks/")||l.endsWith("/lock")||l==="lock")&&n.push(c)}})}return n}function Le(e){let t=[];if(Object.values(e||{}).forEach(n=>{!n||!n.path||!R.existsSync(n.path)||t.push(...Yo(n.path))}),t.length>0)throw new Error(`Sync preflight failed: active lock files detected.
16
+ ${t.map(n=>` - ${n}`).join(`
17
+ `)}`)}function be(){let e=Be(),t=ft(e);if(!t||!t.repoPath||!t.repoUrl)throw new Error(`Sync is not initialized. Run: aigon sync init <git-url>
18
+ Global config: ${Bo}`);if(!R.existsSync(S.join(t.repoPath,".git")))throw new Error(`Sync repo is missing or invalid: ${t.repoPath}. Re-run: aigon sync init ${t.repoUrl}`);return t.registeredRepos=t.registeredRepos||{},t}function Oe(e,t,n){if(!R.existsSync(e))return;Ne(e).forEach(o=>{if(n&&!n(o))return;let s=S.join(e,o),i=S.join(t,o);W(S.dirname(i)),R.copyFileSync(s,i)})}function yn(e){R.rmSync(e,{recursive:!0,force:!0}),R.mkdirSync(e,{recursive:!0})}function Sn(e,t){let n=S.join(e,".aigon");yn(t),Oe(S.join(n,"workflows"),S.join(t,"workflows"),o=>{let s=S.basename(o);return s!=="lock"&&s!=="snapshot.json"&&s!=="stats.json"}),Oe(S.join(n,"telemetry"),S.join(t,"telemetry")),Oe(S.join(n,"state"),S.join(t,"state"),o=>!ut.test(S.basename(o)));let r=S.join(n,"config.json");R.existsSync(r)&&(W(t),R.copyFileSync(r,S.join(t,"config.json")))}function Go(e){let t=S.join(e,"workflows");Ne(t).forEach(n=>{let r=S.basename(n);(r==="snapshot.json"||r==="stats.json")&&R.rmSync(S.join(t,n),{force:!0})})}function zo(e){R.rmSync(S.join(e,".aigon","cache"),{recursive:!0,force:!0})}function Ko(e,t){let n=S.join(e,".aigon");W(n),["workflows","telemetry","state"].forEach(o=>{let s=S.join(t,o),i=S.join(n,o);R.existsSync(s)&&(yn(i),Oe(s,i))});let r=ae(S.join(t,"config.json"),null);if(r){let o=ae(S.join(n,"config.json"),{});we(S.join(n,"config.json"),{...o,...r})}Go(n),zo(e)}function dt(e){return ae(S.join(e,"metadata","manifest.json"),null)}function gt(e,t){we(S.join(e,"metadata","manifest.json"),t)}function pt(e){return ae(S.join(e,"metadata","bootstrap.json"),null)}function ht(e,t){we(S.join(e,"metadata","bootstrap.json"),t)}function Qo(e){let{repoPath:t,repoUrl:n}=e;if(W(t),!R.existsSync(S.join(t,".git")))try{X(S.dirname(t),["clone",n,t])}catch{X(t,["init"]),X(t,["remote","add","origin",n])}W(S.join(t,"repos")),W(S.join(t,"metadata")),R.existsSync(S.join(t,"README.md"))||R.writeFileSync(S.join(t,"README.md"),["# Aigon Sync Repo","","This repository stores portable `.aigon/` state for registered repos.","Generated by `aigon sync`.",""].join(`
19
+ `),"utf8");let r=dt(t)||{syncSchemaVersion:Y,writtenByAigonVersion:D,minReadableAigonVersion:D,repos:{},machines:{}};gt(t,r);let o=pt(t)||{syncSchemaVersion:Y,bootstrapped:!1,minReadableAigonVersion:D};ht(t,o)}function wn(e){let t=G(e,["rev-parse","--abbrev-ref","HEAD"]);return t.ok&&t.output?t.output:"main"}function De(e,t){let n=G(e,["config","--get",t]);return n.ok&&n.output?n.output:null}function dn(e){try{let t=qe("git",["config","--global","--get",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});return String(t||"").trim()||null}catch{return null}}function Zo(e){let t=De(e,"user.name"),n=De(e,"user.email");t&&n||(t=t||De(process.cwd(),"user.name")||dn("user.name"),n=n||De(process.cwd(),"user.email")||dn("user.email"),t||(t="Aigon Sync"),n||(n="sync@aigon.local"),G(e,["config","user.name",t]),G(e,["config","user.email",n]))}function Xo(e){X(e,["fetch","origin"]);let t=G(e,["rev-parse","--abbrev-ref","--symbolic-full-name","@{u}"]);if(!t.ok||!t.output){let i=wn(e);G(e,["branch","--set-upstream-to",`origin/${i}`,i]);return}let n=X(e,["rev-list","--left-right","--count",`HEAD...${t.output}`]),[r,o]=n.split(/\s+/);if(Number(o||0)>0)throw new Error("Push refused: sync repo is behind remote (non-fast-forward). Run `aigon sync pull` first.")}function gn(e){let n=String(e||"").trim().replace(/^v/i,"").split("-")[0].split(".").map(r=>Number(r||0));for(;n.length<3;)n.push(0);return n.slice(0,3)}function es(e,t){let n=gn(e),r=gn(t);for(let o=0;o<3;o++){if(n[o]>r[o])return 1;if(n[o]<r[o])return-1}return 0}function kn(e){let t=pt(e);if(!t||!t.minReadableAigonVersion)return;let n=t.minReadableAigonVersion;if(es(D,n)<0)throw new Error(`This repo requires aigon >= ${n} but local is ${D}. Upgrade first.`)}function mt(e,t){let n=Se(),r=t||{syncSchemaVersion:Y,writtenByAigonVersion:D,minReadableAigonVersion:D,repos:{},machines:{}};return r.syncSchemaVersion=Y,r.writtenByAigonVersion=D,r.minReadableAigonVersion=D,r.repos=r.repos||{},r.machines=r.machines||{},Object.entries(e.registeredRepos||{}).forEach(([o,s])=>{r.repos[o]={displayName:s.displayName,originUrl:s.originUrl||null,registeredAt:s.registeredAt}}),r.machines[n]={...r.machines[n]||{},lastPushAt:e.lastPushAt||null,lastPullAt:e.lastPullAt||null,lastExportAt:e.lastExportAt||null,lastBootstrapMergeAt:e.lastBootstrapMergeAt||null},r}function ts(e){let t=S.join(e.repoPath,"repos");W(t),Object.entries(e.registeredRepos||{}).forEach(([n,r])=>{if(!r.path||!R.existsSync(r.path))return;let o=S.join(t,n,".aigon");Sn(r.path,o)})}function ns(e,t){Le(e.registeredRepos||{});let n=R.mkdtempSync(S.join(Me.tmpdir(),"aigon-sync-export-")),r=S.join(n,"bundle");W(r);let o=S.join(r,"repos");W(o),Object.entries(e.registeredRepos||{}).forEach(([c,l])=>{!l.path||!R.existsSync(l.path)||Sn(l.path,S.join(o,c,".aigon"))});let s=mt(e,null);we(S.join(r,"metadata","manifest.json"),s),we(S.join(r,"metadata","bootstrap.json"),{syncSchemaVersion:Y,bootstrapped:!!e.bootstrapCompleted,minReadableAigonVersion:e.minReadableAigonVersion||D,writtenByAigonVersion:D,exportedAt:K(),exportedByHost:Se()});let i=t?S.resolve(String(t)):S.resolve(process.cwd(),`aigon-sync-export-${K().replace(/[:.]/g,"-")}.tgz`);return W(S.dirname(i)),qe("tar",["-czf",i,"-C",r,"."],{stdio:"pipe"}),R.rmSync(n,{recursive:!0,force:!0}),e.lastExportAt=K(),ke(e),i}function rs(e,t){let n=e.repoPath;Xo(n),Zo(n),X(n,["add","repos","metadata","README.md"]);let r=G(n,["diff","--cached","--name-only"]);if(!r.ok||!r.output)return{committed:!1};X(n,["commit","-m",t]);let o=wn(n),s=G(n,["push","origin",o]);if(!s.ok)throw/non-fast-forward|fetch first|rejected/.test(s.output)?new Error("Push refused: non-fast-forward update detected. Run `aigon sync pull` and retry."):new Error(`Failed to push sync repo: ${s.output}`);return{committed:!0}}function bn(){let e=be();Le(e.registeredRepos||{}),kn(e.repoPath),ts(e),e.lastPushAt=K(),e.minReadableAigonVersion=D;let t=mt(e,dt(e.repoPath));gt(e.repoPath,t);let n=pt(e.repoPath)||{syncSchemaVersion:Y,bootstrapped:!1};return n.syncSchemaVersion=Y,n.writtenByAigonVersion=D,n.minReadableAigonVersion||(n.minReadableAigonVersion=D),ht(e.repoPath,n),ke(e),{committed:rs(e,`chore(sync): push portable state (${Se()})`).committed,pushedAt:e.lastPushAt}}function os(){let e=be();Le(e.registeredRepos||{});let t=G(e.repoPath,["pull","--ff-only"]);if(!t.ok)throw/Not possible to fast-forward|non-fast-forward|divergent/.test(t.output)?new Error("Pull refused: non-fast-forward history detected. Resolve sync repo divergence manually."):new Error(`Failed to pull sync repo: ${t.output}`);return kn(e.repoPath),Object.entries(e.registeredRepos||{}).forEach(([n,r])=>{if(!r.path||!R.existsSync(r.path))return;let o=S.join(e.repoPath,"repos",n,".aigon");R.existsSync(o)&&Ko(r.path,o)}),e.lastPullAt=K(),ke(e),{pulledAt:e.lastPullAt}}function ss(e){if(!e)throw new Error("Usage: aigon sync init <git-url>");let t=Be(),n=ft(t)||{};return n.repoUrl=String(e).trim(),n.repoPath=n.repoPath||Wo(n.repoUrl),n.initializedAt=n.initializedAt||K(),n.registeredRepos=n.registeredRepos||{},n.syncSchemaVersion=Y,n.minReadableAigonVersion=n.minReadableAigonVersion||D,Qo(n),t.sync=n,pn(t),n}function is(e){let t=be(),n=S.resolve(e||process.cwd());if(!R.existsSync(S.join(n,".git")))throw new Error(`Not a git repo: ${n}`);let{id:r,originUrl:o}=Ho(n),s=t.registeredRepos[r]||{};return t.registeredRepos[r]={id:r,displayName:S.basename(n),path:n,originUrl:o,registeredAt:s.registeredAt||K(),updatedAt:K()},ke(t),t.registeredRepos[r]}function cs(){let e=Be(),t=ft(e);if(!t||!t.repoPath||!t.repoUrl)return{initialized:!1,bootstrapCompleted:!1,registeredRepos:[],pendingChanges:!1};let n=Object.values(t.registeredRepos||{}),r=n.some(o=>{if(!o.path||!R.existsSync(o.path))return!1;let s=S.join(o.path,".aigon"),i=S.join(t.repoPath,"repos",o.id,".aigon"),c=Ne(s).filter(a=>a.startsWith("workflows/")||a.startsWith("telemetry/")||a.startsWith("state/")||a==="config.json").filter(a=>S.basename(a)!=="lock").filter(a=>!ut.test(S.basename(a))),l=Ne(i).filter(a=>a.startsWith("workflows/")||a.startsWith("telemetry/")||a.startsWith("state/")||a==="config.json").filter(a=>S.basename(a)!=="lock").filter(a=>!ut.test(S.basename(a)));if(c.length!==l.length)return!0;for(let a=0;a<c.length;a++){if(c[a]!==l[a])return!0;let u=S.join(s,c[a]),p=S.join(i,l[a]);if(!R.existsSync(p))return!0;let f=R.readFileSync(u),h=R.readFileSync(p);if(Buffer.compare(f,h)!==0)return!0}return!1});return{initialized:!0,repoPath:t.repoPath,repoUrl:t.repoUrl,bootstrapCompleted:!!t.bootstrapCompleted,lastPushAt:t.lastPushAt||null,lastPullAt:t.lastPullAt||null,lastExportAt:t.lastExportAt||null,lastBootstrapMergeAt:t.lastBootstrapMergeAt||null,minReadableAigonVersion:t.minReadableAigonVersion||null,pendingChanges:r,registeredRepos:n}}function as(e,{shouldPush:t=!1}={}){let n=be();Le(n.registeredRepos||{});let r=S.resolve(String(e||""));if(!e||!R.existsSync(r))throw new Error(`Bundle file not found: ${e||"(missing)"}`);let o=R.mkdtempSync(S.join(Me.tmpdir(),"aigon-sync-import-"));try{qe("tar",["-xzf",r,"-C",o],{stdio:"pipe"})}catch(s){throw R.rmSync(o,{recursive:!0,force:!0}),new Error(`Failed to extract bundle: ${s.message}`)}try{let s=ae(S.join(o,"metadata","manifest.json"),{}),i=ae(S.join(o,"metadata","bootstrap.json"),{}),c={};Object.entries(n.registeredRepos||{}).forEach(([f,h])=>{c[f]=h.path});let l=Lo({bundleRoot:o,repoPathById:c});n.bootstrapCompleted=!0,n.lastBootstrapMergeAt=K(),n.minReadableAigonVersion=D,ke(n);let a={syncSchemaVersion:Y,bootstrapped:!0,bootstrappedAt:n.lastBootstrapMergeAt,bootstrappedByHost:Se(),minReadableAigonVersion:D,writtenByAigonVersion:D,sources:[{kind:"import-bundle",host:i.exportedByHost||"unknown",writtenByAigonVersion:i.writtenByAigonVersion||null},{kind:"local-state",host:Se(),writtenByAigonVersion:D}]};ht(n.repoPath,a);let u=mt(n,dt(n.repoPath)||s);gt(n.repoPath,u);let p=null;return t&&(p=bn()),{summary:l,pushed:!!p}}finally{R.rmSync(o,{recursive:!0,force:!0})}}function ls(e){if(!e.initialized){console.log("Sync: not initialized"),console.log("Run: aigon sync init <git-url>");return}console.log("Sync: initialized"),console.log(` Repo: ${e.repoPath}`),console.log(` URL: ${e.repoUrl}`),console.log(` Bootstrap: ${e.bootstrapCompleted?"completed":"not completed"}`),console.log(` Last push: ${e.lastPushAt||"never"}`),console.log(` Last pull: ${e.lastPullAt||"never"}`),console.log(` Last export: ${e.lastExportAt||"never"}`),console.log(` Last bootstrap merge: ${e.lastBootstrapMergeAt||"never"}`),console.log(` Min readable version: ${e.minReadableAigonVersion||"n/a"}`),console.log(` Pending local changes: ${e.pendingChanges?"yes":"no"}`),console.log(` Registered repos (${e.registeredRepos.length}):`),e.registeredRepos.length===0?console.log(" (none)"):e.registeredRepos.forEach(t=>{console.log(` - ${t.id}: ${t.path}`)})}function us(){console.log("Usage: aigon sync <command> [options]"),console.log(""),console.log("Commands:"),console.log(" init <git-url> Initialize sync repo and save sync config"),console.log(" register [repo-path] Register a local git repo for sync"),console.log(" export [--output <file>] Export portable state bundle for registered repos"),console.log(" bootstrap-merge <bundle> [--push] Merge imported bundle with local state (one-time)"),console.log(" push Copy portable state to sync repo and push"),console.log(" pull Pull sync repo and restore portable state"),console.log(" status Show sync status and pending changes")}async function fs(e=[]){let t=e[0],n=e.slice(1);if(!t||t==="help"||t==="--help"||t==="-h"){us();return}if(t==="init"){let r=n[0],o=ss(r);console.log("\u2705 Sync initialized"),console.log(` Repo URL: ${o.repoUrl}`),console.log(` Local repo: ${o.repoPath}`);return}if(t==="register"){let r=is(n[0]);console.log(`\u2705 Registered repo: ${r.id}`),console.log(` Path: ${r.path}`);return}if(t==="export"){let r=null;for(let i=0;i<n.length;i++){if(n[i]==="--output"&&n[i+1]){r=n[i+1];break}if(n[i].startsWith("--output=")){r=n[i].slice(9);break}}let o=be(),s=ns(o,r);console.log(`\u2705 Exported bundle: ${s}`);return}if(t==="bootstrap-merge"){let r=n.find(i=>!i.startsWith("--")),o=n.includes("--push"),s=as(r,{shouldPush:o});console.log("\u2705 Bootstrap merge complete"),console.log(` Repos merged: ${s.summary.reposMerged}`),s.summary.reposSkipped.length>0&&console.log(` Repos skipped (not registered locally): ${s.summary.reposSkipped.join(", ")}`),o&&console.log(" Baseline pushed to sync repo");return}if(t==="push"){let r=bn();r.committed?console.log(`\u2705 Sync push complete (${r.pushedAt})`):console.log("\u2705 Sync push complete (no changes to commit)");return}if(t==="pull"){let r=os();console.log(`\u2705 Sync pull complete (${r.pulledAt})`);return}if(t==="status"){ls(cs());return}throw new Error(`Unknown sync command: ${t}
20
+ Run: aigon sync --help`)}An.exports={SYNC_SCHEMA_VERSION:Y,handleSyncCommand:fs}});var yt=T((tc,Rn)=>{"use strict";var q=require("fs"),Ae=require("path"),{spawnSync:ds}=require("child_process");function gs(){return new Date().toISOString()}function ps(e){if(!q.existsSync(e))return{};try{return JSON.parse(q.readFileSync(e,"utf8"))}catch{return{}}}function hs(e,t){q.mkdirSync(Ae.dirname(e),{recursive:!0}),q.writeFileSync(e,JSON.stringify(t,null,2)+`
21
+ `,"utf8")}function ms(e,t){return q.existsSync(e)?!1:(q.mkdirSync(Ae.dirname(e),{recursive:!0}),q.writeFileSync(e,t,"utf8"),!0)}function ys(e){return q.existsSync(e)?q.readFileSync(e,"utf8").split(`
22
+ `).map(t=>t.trim()).filter(t=>t&&!t.startsWith("#")):[]}function $n(e){let t=e.replace(/\\/g,"/");t.endsWith("/")&&(t=t.slice(0,-1));let r=t.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*");return new RegExp(`^${r}(/|$)`)}function Ss(e){let t=e.map($n);return function(r){let o=r.replace(/\\/g,"/");for(let s of t){if(s.test(o))return!0;let i=o.split("/");for(let c=0;c<i.length;c++)if(s.test(i.slice(c).join("/")))return!0}return!1}}function jn(e,t=""){let n=[],r=Ae.join(e,t);if(!q.existsSync(r))return n;let o=q.readdirSync(r,{withFileTypes:!0});for(let s of o){let i=t?`${t}/${s.name}`:s.name;s.isDirectory()?n.push(...jn(e,i)):s.isFile()&&n.push(i)}return n}function N(e,t,{input:n,allowFail:r=!1}={}){let o=ds("git",t,{cwd:e,encoding:"utf8",input:n,stdio:["pipe","pipe","pipe"]});if(!r&&(o.error||o.status!==0)){let s=(o.stderr||"").trim(),i=o.error?o.error.message:`git ${t.join(" ")} failed (${o.status}): ${s}`,c=new Error(i);throw c.stderr=s,c.code=o.status,c}return{ok:!o.error&&o.status===0,stdout:(o.stdout||"").trim(),stderr:(o.stderr||"").trim(),status:o.status}}function ws(e,t){if(q.mkdirSync(e,{recursive:!0}),q.existsSync(Ae.join(e,".git"))||(N(e,["init","--quiet"]),N(e,["config","user.email","aigon-sync@local"]),N(e,["config","user.name","aigon-sync"])),t){let n=N(e,["remote","get-url","origin"],{allowFail:!0});n.ok?n.stdout!==t&&N(e,["remote","set-url","origin",t]):N(e,["remote","add","origin",t])}return e}function ks(e,t){return N(e,["fetch","origin",t],{allowFail:!0}).ok}function bs(e,t,{hadRemote:n,clearWorkingTree:r=!0}){let o=N(e,["rev-parse","--verify",t],{allowFail:!0}).ok,s=N(e,["rev-parse","--verify",`origin/${t}`],{allowFail:!0});if(n&&s.ok)o?(N(e,["checkout","--quiet",t]),N(e,["reset","--hard",`origin/${t}`])):N(e,["checkout","--quiet","-B",t,`origin/${t}`]);else if(o)N(e,["checkout","--quiet",t]);else{N(e,["checkout","--quiet","--orphan",t]);let i=N(e,["rm","-rf","--cached","."],{allowFail:!0})}if(r)for(let i of q.readdirSync(e))i!==".git"&&q.rmSync(Ae.join(e,i),{recursive:!0,force:!0})}Rn.exports={nowIso:gs,loadJson:ps,saveJson:hs,ensureSyncIgnoreAt:ms,readSyncIgnorePatterns:ys,patternToRegex:$n,makeSyncIgnoreMatcher:Ss,listFilesUnder:jn,git:N,ensureHelperRepoAt:ws,fetchBranch:ks,checkoutBranch:bs}});var Yn=T((nc,Hn)=>{"use strict";var A=require("fs"),Ue=require("os"),b=require("path"),As=require("zlib"),{spawnSync:bt}=require("child_process"),F=yt(),_="main",vs=".vault",$s="backup-meta.json",xn=new Set(["sessions","locks","cache","server",".sync",".vault"]),js=new Set(["budget-cache.json","insights-cache.json","recurring-state.json","config-hash",".syncignore"]),Rs=["repos","serverPort","sync"],ve=new Set(["daily","hourly","weekly","off"]),St="daily";function ee(){return b.join(Ue.homedir(),".aigon")}function je(){return b.join(ee(),vs)}function re(){return b.join(je(),"repo")}function At(){return b.join(je(),$s)}function _n(){return b.join(ee(),"backup.log")}function oe(){let e=b.join(ee(),"config.json");return F.loadJson(e)}function wt(e){F.saveJson(b.join(ee(),"config.json"),e)}function vt(){let e=oe();return e.backup&&typeof e.backup=="object"?e.backup:{}}function Tn(e){let t=oe();return t.backup=Object.assign({},t.backup||{},e),wt(t),t.backup}function We(){let e=vt();return e.remote?String(e.remote).trim():null}function Re(){let e=vt(),t=String(e.schedule||St).toLowerCase();return ve.has(t)?t:St}function le(){return F.loadJson(At())}function Je(e){F.saveJson(At(),e)}function Dn(){let e=We();if(!e){let t=new Error("Backup is not configured. Run: aigon backup configure");throw t.code="ENOBACKUP",t}return e}function On(){let e=oe();return Array.isArray(e.repos)?e.repos.map(t=>String(t)):[]}function Fs(e){return b.basename(b.resolve(e))}function Es(e){let t=b.resolve(e);return/\/(Library\/Mobile Documents|iCloud Drive|Dropbox|Google Drive|OneDrive)(\/|$)/i.test(t)}function Nn(e){return bt(process.platform==="win32"?"where":"which",[e],{encoding:"utf8"}).status===0}function Mn(){return bt("gh",["auth","status"],{encoding:"utf8",stdio:"pipe"}).status===0}var kt={compressAfterDays:90,dropAfterDays:365},Fn=1440*60*1e3;function qn(){let e=vt(),t=e.telemetryRetention&&typeof e.telemetryRetention=="object"?e.telemetryRetention:{};return{compressAfterDays:t.compressAfterDays!==void 0?t.compressAfterDays:kt.compressAfterDays,dropAfterDays:t.dropAfterDays!==void 0?t.dropAfterDays:kt.dropAfterDays}}function En(e,t){if(t){let n=Date.parse(t);if(!Number.isNaN(n))return Date.now()-n}try{return Date.now()-A.statSync(e).mtimeMs}catch{return 0}}function Pn(e){let t=A.readFileSync(e),n=As.gzipSync(t);A.writeFileSync(e+".gz",n),A.unlinkSync(e)}function Bn(e,t){let{compressAfterDays:n,dropAfterDays:r}=t||qn(),o=b.join(e,".aigon","telemetry");if(!A.existsSync(o))return;let s=n!==null&&n!==0?n*Fn:null,i=r!==null&&r!==0?r*Fn:null;for(let l of A.readdirSync(o,{withFileTypes:!0})){if(!l.isFile()||!l.name.endsWith(".json"))continue;let a=b.join(o,l.name),u=null;try{let f=JSON.parse(A.readFileSync(a,"utf8"));u=f&&f.endAt?f.endAt:null}catch{}let p=En(a,u);if(i!==null&&p>=i)try{A.unlinkSync(a)}catch{}else if(s!==null&&p>=s)try{Pn(a)}catch{}}let c=b.join(o,"signal-health");if(A.existsSync(c))for(let l of A.readdirSync(c,{withFileTypes:!0})){if(!l.isFile()||!/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(l.name))continue;let a=b.join(c,l.name),u=l.name.slice(0,10),p=En(a,u+"T23:59:59Z");if(i!==null&&p>=i)try{A.unlinkSync(a)}catch{}else if(s!==null&&p>=s)try{Pn(a)}catch{}}}function Ps(e,t){let n=b.join(e,".aigon");if(!A.existsSync(n))return 0;let r=0,o=A.readdirSync(n,{withFileTypes:!0});for(let s of o){if(s.isDirectory()&&xn.has(s.name)||s.isFile()&&js.has(s.name)||s.isFile()&&/^backup\.log/.test(s.name)||s.isFile()&&/\.log$/.test(s.name))continue;let i=b.join(n,s.name),c=b.join(t,s.name);s.isFile()?(A.mkdirSync(b.dirname(c),{recursive:!0}),A.copyFileSync(i,c),r++):s.isDirectory()&&(r+=$e(i,c))}return r}function $e(e,t){let n=0;if(!A.existsSync(e))return 0;A.mkdirSync(t,{recursive:!0});for(let r of A.readdirSync(e,{withFileTypes:!0})){let o=b.join(e,r.name),s=b.join(t,r.name);r.isDirectory()?n+=$e(o,s):r.isFile()&&(A.copyFileSync(o,s),n++)}return n}function Cs(e){try{A.rmSync(e,{recursive:!0,force:!0})}catch{}}function $t(e,t={}){let n=e?String(e).trim():null;if(!n)throw new Error("Usage: aigon backup configure <git-url>");return Es(ee())&&console.warn("\u26A0\uFE0F ~/.aigon is inside an iCloud/Dropbox path \u2014 git + cloud sync corrupts repos. Move ~/.aigon out first."),Tn({remote:n,schedule:Re()}),A.mkdirSync(je(),{recursive:!0}),F.ensureHelperRepoAt(re(),n),{remote:n}}function Ln(e="aigon-vault"){if(!Nn("gh")){let o=new Error("gh CLI is not installed. Install it from https://cli.github.com or pass a git URL directly.");throw o.code="ENOGH",o}if(!Mn()){let o=new Error("gh is not authenticated. Run: gh auth login");throw o.code="ENOGHAUTH",o}let t=bt("gh",["repo","create",e,"--private","--description","aigon backup vault"],{encoding:"utf8"});if(t.status!==0){let o=(t.stderr||"").trim();throw new Error(`gh repo create failed: ${o||"unknown error"}`)}let n=(t.stdout||"").trim(),r=n.match(/https:\/\/github\.com\/[^\s]+/);if(!r)throw new Error(`gh repo create did not return a URL. Output: ${n}`);return r[0]+".git"}function jt(){let e=Dn();A.mkdirSync(je(),{recursive:!0});let t=F.ensureHelperRepoAt(re(),e);if(F.fetchBranch(t,_)){if(F.git(t,["rev-parse","--verify",_],{allowFail:!0}).ok){let y=F.git(t,["rev-list",`origin/${_}..${_}`],{allowFail:!0}),k=F.git(t,["rev-list",`${_}..origin/${_}`],{allowFail:!0}),v=y.ok&&y.stdout?y.stdout.split(`
23
+ `).length:0,E=k.ok&&k.stdout?k.stdout.split(`
24
+ `).length:0;if(v>0&&E>0){let j=new Error(`Remote has diverged from local. Pull first to integrate remote changes,
25
+ then retry: aigon backup pull && aigon backup push`);throw j.code="EBACKUPCONFLICT",j}}F.checkoutBranch(t,_,{hadRemote:!0})}else F.checkoutBranch(t,_,{hadRemote:!1});for(let m of A.readdirSync(t))m!==".git"&&Cs(b.join(t,m));let r=On(),o=0,s=[];for(let m of r){if(!A.existsSync(m))continue;Bn(m);let y=Fs(m),k=b.join(t,"projects",y),v=Ps(m,k);v>0&&(s.push({name:y,path:m,files:v}),o+=v)}let i=b.join(t,"settings");A.mkdirSync(i,{recursive:!0});let c=oe(),l=Object.assign({},c);for(let m of Rs)delete l[m];A.writeFileSync(b.join(i,"config.json"),JSON.stringify(l,null,2)+`
26
+ `,"utf8"),o++;let a=b.join(ee(),"workflow-definitions"),u=b.join(i,"workflow-definitions");A.existsSync(a)&&(o+=$e(a,u)),F.git(t,["add","-A"]);let p=F.git(t,["status","--porcelain"]),f=F.git(t,["rev-parse","--verify","HEAD"],{allowFail:!0}).ok;if(!p.stdout&&f){let m=le();return m.lastPushAt=F.nowIso(),m.lastPushFiles=o,m.lastPushNoChanges=!0,m.projectCount=s.length,Je(m),{committed:!1,pushed:!1,fileCount:o,projects:s}}let h=`aigon backup \u2014 ${F.nowIso()}`;p.stdout?F.git(t,["commit","--quiet","-m",h]):F.git(t,["commit","--quiet","--allow-empty","-m",h]);let d=F.git(t,["push","origin",`${_}:${_}`],{allowFail:!0});if(!d.ok){if(/non-fast-forward|rejected/i.test(d.stderr)){let m=new Error("Push rejected \u2014 remote has diverged. Run 'aigon backup pull' first, resolve any conflicts, then retry.");throw m.code="EBACKUPCONFLICT",m}throw new Error(`Backup push failed: ${d.stderr||"unknown error"}`)}let g=F.git(t,["rev-parse",_],{allowFail:!0}),w=le();return w.lastPushAt=F.nowIso(),w.lastPushMessage=h,w.lastPushFiles=o,w.lastPushNoChanges=!1,w.projectCount=s.length,g.ok&&g.stdout&&(w.lastSha=g.stdout),Je(w),{committed:!0,pushed:!0,fileCount:o,projects:s,message:h}}var Is=[b.join(Ue.homedir(),"src"),b.join(Ue.homedir(),"code"),b.join(Ue.homedir(),"Developer"),process.cwd()];function xs(e){for(let t of Is){if(!A.existsSync(t))continue;let n=b.join(t,e);if(A.existsSync(n)&&A.existsSync(b.join(n,".git")))return n}return null}function Un(){let e=Dn();A.mkdirSync(je(),{recursive:!0});let t=F.ensureHelperRepoAt(re(),e);if(!F.fetchBranch(t,_)){let f=le();return f.lastPullAt=F.nowIso(),f.lastPullEmpty=!0,Je(f),{applied:!1,reason:"remote-empty"}}if(F.git(t,["rev-parse","--verify",_],{allowFail:!0}).ok){let f=F.git(t,["rev-list",`origin/${_}..${_}`],{allowFail:!0}),h=F.git(t,["rev-list",`${_}..origin/${_}`],{allowFail:!0}),d=f.ok&&f.stdout?f.stdout.split(`
27
+ `).length:0,g=h.ok&&h.stdout?h.stdout.split(`
28
+ `).length:0;if(d>0&&g>0){let w=new Error(`Vault branch has diverged: ${d} local-only and ${g} remote-only commits.
29
+ Resolve manually:
30
+ cd ${re()} && git pull --rebase origin ${_}`);throw w.code="EBACKUPCONFLICT",w}}F.checkoutBranch(t,_,{hadRemote:!0,clearWorkingTree:!1});let o=b.join(t,"settings","config.json");if(A.existsSync(o)){let f={};try{f=JSON.parse(A.readFileSync(o,"utf8"))}catch{f={}}let h=oe(),d=Object.assign({},f,{repos:h.repos||[],serverPort:h.serverPort});h.sync&&(d.sync=h.sync),d.serverPort===void 0&&delete d.serverPort,wt(d)}let s=b.join(t,"settings","workflow-definitions"),i=b.join(ee(),"workflow-definitions");A.existsSync(s)&&$e(s,i);let c=b.join(t,"projects"),l=[],a=[];if(A.existsSync(c))for(let f of A.readdirSync(c,{withFileTypes:!0})){if(!f.isDirectory())continue;let h=f.name,d=xs(h);if(!d){a.push(h);continue}let g=b.join(c,h),w=b.join(d,".aigon");for(let m of A.readdirSync(g,{withFileTypes:!0})){let y=b.join(g,m.name),k=b.join(w,m.name);m.isDirectory()?(A.mkdirSync(k,{recursive:!0}),$e(y,k)):m.isFile()&&(A.mkdirSync(b.dirname(k),{recursive:!0}),A.copyFileSync(y,k))}try{if(!On().map(y=>b.resolve(y)).includes(b.resolve(d))){let y=oe();y.repos=(y.repos||[]).concat([d]),wt(y)}}catch{}l.push({name:h,path:d})}let u=F.git(t,["rev-parse",_],{allowFail:!0}),p=le();return p.lastPullAt=F.nowIso(),p.lastPullEmpty=!1,u.ok&&u.stdout&&(p.lastSha=u.stdout),Je(p),{applied:!0,restored:l,notFound:a}}function Jn(){let e=We(),t=le(),n=Re(),r=oe(),o=t.projectCount||0;if(!o&&A.existsSync(b.join(re(),"projects")))try{o=A.readdirSync(b.join(re(),"projects"),{withFileTypes:!0}).filter(s=>s.isDirectory()).length}catch{o=0}return{configured:!!e,remote:e||null,lastPushAt:t.lastPushAt||null,lastPullAt:t.lastPullAt||null,schedule:n,scheduleActive:!!e&&n!=="off",projectCount:o,registeredRepos:Array.isArray(r.repos)?r.repos.length:0}}function Wn(e){let t=String(e||"").toLowerCase();if(!ve.has(t))throw new Error(`Invalid schedule: ${e}. Valid: ${[...ve].join(", ")}`);return Tn({schedule:t}),t}var Cn={hourly:3600*1e3,daily:1440*60*1e3,weekly:10080*60*1e3};function Vn(){if(!We())return!1;let t=Re();if(t==="off")return!1;let n=le();if(!n.lastPushAt)return!0;let r=Date.parse(n.lastPushAt);if(Number.isNaN(r))return!0;let o=Cn[t]||Cn.daily;return Date.now()-r>=o}function In(e){try{A.mkdirSync(ee(),{recursive:!0}),A.appendFileSync(_n(),`[${F.nowIso()}] ${e}
31
+ `,"utf8")}catch{}}function _s(){if(!Vn())return{ran:!1,reason:"not-due"};try{let e=jt();return In(`scheduled-push ok files=${e.fileCount} projects=${(e.projects||[]).length}`),{ran:!0,ok:!0,result:e}}catch(e){return In(`scheduled-push failed: ${e.message}`),{ran:!0,ok:!1,error:e.message,code:e.code}}}function Ts(){console.log("Usage: aigon backup <command> [options]"),console.log(""),console.log("Commands:"),console.log(" configure [<git-url>] Configure the vault remote (interactive without arg)"),console.log(" push Pull, then push project state + settings to the vault"),console.log(" pull Fetch + restore settings and project state from the vault"),console.log(" status Show remote, last push/pull, schedule, project count"),console.log(" schedule <daily|hourly|weekly|off> Set scheduled push cadence (default: daily)")}async function Ds(){let e;try{e=require("@clack/prompts")}catch{e=null}let t=process.stdin.isTTY&&process.stdout.isTTY;if(!e||!t)throw new Error("Interactive configure requires a TTY. Pass a git URL: aigon backup configure <git-url>");e.intro("\u{1F512} Aigon Vault setup");let n=null;if(Nn("gh")&&Mn()){let r=await e.confirm({message:"Create a new private GitHub repo for the vault? (gh detected)",initialValue:!0});if(e.isCancel(r))return e.cancel("Cancelled."),null;if(r){let o=await e.text({message:"Repo name",placeholder:"aigon-vault",defaultValue:"aigon-vault"});if(e.isCancel(o))return e.cancel("Cancelled."),null;let s=String(o||"aigon-vault").trim()||"aigon-vault",i=e.spinner();i.start(`Creating ${s} on GitHub\u2026`);try{n=Ln(s),i.stop(`\u2705 Created ${n}`)}catch(c){i.stop(`\u274C ${c.message}`),n=null}}}if(!n){let r=await e.text({message:"Git URL for the vault repo",placeholder:"git@github.com:you/aigon-vault.git"});if(e.isCancel(r)||!r)return e.cancel("Cancelled."),null;n=String(r).trim()}return $t(n),e.outro(`\u2705 Vault configured: ${n}`),n}async function Os(e=[]){let t=e[0],n=e.slice(1);if(!t||t==="help"||t==="--help"||t==="-h"){Ts();return}if(t==="configure"){if(n[0]){let o=$t(n[0]);console.log("\u2705 Vault configured"),console.log(` Remote: ${o.remote}`);return}await Ds()||(process.exitCode=1);return}if(t==="push"){let r=jt();r.committed?(console.log(`\u2705 Backup push: ${r.fileCount} files, ${(r.projects||[]).length} projects`),console.log(` ${r.message}`)):console.log("\u2705 Backup push: no changes to commit");return}if(t==="pull"){let r=Un();if(!r.applied){console.log("\u2705 Backup pull: vault is empty (nothing to restore yet)");return}console.log(`\u2705 Backup pull: ${r.restored.length} project(s) restored`);for(let o of r.restored)console.log(` \u2713 ${o.name} \u2192 ${o.path}`);if(r.notFound.length){console.log(""),console.log(`\u26A0\uFE0F ${r.notFound.length} project(s) not found locally:`);for(let o of r.notFound)console.log(` \u2022 ${o} \u2014 clone it, then run: aigon server add <path>`)}return}if(t==="status"){let r=Jn();if(!r.configured){console.log("Backup: not configured"),console.log("Run: aigon backup configure");return}console.log("Backup: configured"),console.log(` Remote: ${r.remote}`),console.log(` Last push: ${r.lastPushAt||"never"}`),console.log(` Last pull: ${r.lastPullAt||"never"}`),console.log(` Schedule: ${r.schedule}${r.scheduleActive?"":" (inactive)"}`),console.log(` Projects in vault: ${r.projectCount}`);return}if(t==="schedule"){if(!n[0]){console.log(`Backup schedule: ${Re()}`),console.log(`Valid: ${[...ve].join(", ")}`);return}let r=Wn(n[0]);console.log(`\u2705 Backup schedule: ${r}`);return}throw new Error(`Unknown backup command: ${t}
32
+ Run: aigon backup --help`)}Hn.exports={VAULT_BRANCH:_,DEFAULT_SCHEDULE:St,VALID_SCHEDULES:ve,PROJECT_EXCLUDES:xn,DEFAULT_RETENTION:kt,handleBackupCommand:Os,configure:$t,createVaultOnGitHub:Ln,push:jt,pull:Un,status:Jn,setSchedule:Wn,getSchedule:Re,getRemote:We,isScheduledPushDue:Vn,runScheduledPushIfDue:_s,applyTelemetryRetention:Bn,getTelemetryRetentionConfig:qn,helperRepoPath:re,metaPath:At,logPath:_n}});var zn=T((rc,Gn)=>{"use strict";Gn.exports=require("@senlabsai/aigon/lib/cli-parse")});var Qn=T((oc,Kn)=>{"use strict";Kn.exports=require("@senlabsai/aigon/lib/spec-crud")});var Xn=T((sc,Zn)=>{"use strict";Zn.exports=require("@senlabsai/aigon/lib/workflow-core/engine")});var sr=T((ic,or)=>{"use strict";var U=require("fs"),B=require("path"),{execFileSync:Ve}=require("child_process"),{parseFrontMatter:Ft}=zn(),er=Qn(),Ns=["01-inbox","02-backlog","03-in-progress","04-in-evaluation"],Ms=["01-inbox","02-backlog","03-in-progress","04-in-evaluation","05-done","06-paused"];function qs(e){return{root:B.join(e,"docs","specs","features"),folders:Ms,prefix:"feature"}}function Et(e){let t=e?new Date(e):new Date,n=new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate())),r=n.getUTCDay()||7;n.setUTCDate(n.getUTCDate()+4-r);let o=new Date(Date.UTC(n.getUTCFullYear(),0,1)),s=Math.ceil(((n-o)/864e5+1)/7);return`${n.getUTCFullYear()}-W${String(s).padStart(2,"0")}`}function Pt(e){let t=e?new Date(e):new Date,n=t.getUTCFullYear(),r=Math.floor(t.getUTCMonth()/3)+1;return`${n}-Q${r}`}function tr(e){let t=e?new Date(e):new Date,n=t.getUTCFullYear(),r=String(t.getUTCMonth()+1).padStart(2,"0"),o=String(t.getUTCDate()).padStart(2,"0");return`${n}-${r}-${o}`}function Ct(e){let t=e?new Date(e):new Date,n=t.getUTCFullYear(),r=String(t.getUTCMonth()+1).padStart(2,"0");return`${n}-${r}`}function Bs(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function He(e,t={}){let n=e;return t.isoWeek!==void 0&&(n=n.replace(/\{\{YYYY-WW\}\}/g,t.isoWeek)),t.isoQuarter!==void 0&&(n=n.replace(/\{\{YYYY-Q\}\}/g,t.isoQuarter)),t.isoMonth!==void 0&&(n=n.replace(/\{\{YYYY-MM\}\}/g,t.isoMonth)),t.isoDate!==void 0&&(n=n.replace(/\{\{YYYY-MM-DD\}\}/g,t.isoDate)),n}function Ls(e,t,n){return He(e,{isoWeek:t,isoMonth:n})}function It(e){if(!U.existsSync(e))return[];let t=[],n=new Set,r=U.readdirSync(e).filter(o=>o.endsWith(".md")).sort();for(let o of r){let s=B.join(e,o),i;try{i=U.readFileSync(s,"utf8")}catch(p){console.warn(`\u26A0\uFE0F [recurring] Could not read ${o}: ${p.message}`);continue}let{data:c}=Ft(i);if(!c.schedule){console.warn(`\u26A0\uFE0F [recurring] ${o}: missing 'schedule' frontmatter, skipping`);continue}if(c.schedule!=="weekly"&&c.schedule!=="quarterly"&&c.schedule!=="monthly"){console.warn(`\u26A0\uFE0F [recurring] ${o}: unsupported schedule '${c.schedule}', skipping`);continue}if(!c.name_pattern){console.warn(`\u26A0\uFE0F [recurring] ${o}: missing 'name_pattern' frontmatter, skipping`);continue}if(!c.recurring_slug){console.warn(`\u26A0\uFE0F [recurring] ${o}: missing 'recurring_slug' frontmatter, skipping`);continue}if(n.has(c.recurring_slug)){console.warn(`\u26A0\uFE0F [recurring] ${o}: duplicate recurring_slug '${c.recurring_slug}', skipping`);continue}let l=c.name_pattern.match(/\{\{[^}]+\}\}/g)||[],a={weekly:["{{YYYY-WW}}"],quarterly:["{{YYYY-Q}}"],monthly:["{{YYYY-MM}}"]}[c.schedule],u=l.filter(p=>!a.includes(p));if(u.length>0){console.warn(`\u26A0\uFE0F [recurring] ${o}: unsupported name_pattern placeholders for schedule=${c.schedule}: ${u.join(", ")}, skipping`);continue}if(l.length===0){console.warn(`\u26A0\uFE0F [recurring] ${o}: name_pattern has no supported placeholders, skipping`);continue}n.add(c.recurring_slug),t.push({file:o,filePath:s,schedule:c.schedule,namePattern:c.name_pattern,recurringSlug:c.recurring_slug,rawContent:i})}return t}function nr(e,t){let n=B.join(e,"docs","specs","features");for(let r of Ns){let o=B.join(n,r);if(U.existsSync(o)){for(let s of U.readdirSync(o))if(s.endsWith(".md"))try{let i=U.readFileSync(B.join(o,s),"utf8"),{data:c}=Ft(i);if(c.recurring_slug===t)return!0}catch{}}}return!1}function rr(e){let t=B.join(e,".aigon","recurring-state.json");try{return JSON.parse(U.readFileSync(t,"utf8"))}catch{return{}}}function Us(e,t){let n=B.join(e,".aigon","recurring-state.json"),r=B.dirname(n);U.existsSync(r)||U.mkdirSync(r,{recursive:!0}),U.writeFileSync(n,JSON.stringify(t,null,2)+`
33
+ `)}function Js(e,t,n,r){let o=qs(e),s=Bs(n),i=`feature-${s}.md`,c=B.join(o.root,"01-inbox"),l=B.join(c,i),{data:a,body:u}=Ft(t.rawContent),p=new Set(["schedule","name_pattern"]),f=Object.entries(a||{}).filter(([O])=>!p.has(O)),h=["---"];for(let[O,I]of f)h.push(`${O}: ${typeof I=="string"?I:JSON.stringify(I)}`);t.schedule==="weekly"?h.push(`recurring_week: ${r.isoWeek}`):t.schedule==="monthly"?h.push(`recurring_month: ${r.isoMonth}`):h.push(`recurring_quarter: ${r.isoQuarter}`),h.push(`recurring_template: ${t.file}`),h.push("---");let d=h.join(`
34
+ `),g=(u||"").replace(/^# .+$/m,`# ${n}`);/^# /m.test(g)||(g=`# ${n}
35
+
36
+ ${g.trim()}`),g=He(g,r);let w=`${d}
37
+
38
+ ${g.trim()}
39
+ `;U.existsSync(c)||U.mkdirSync(c,{recursive:!0}),U.writeFileSync(l,w);let m=Xn();m.ensureEntityBootstrappedSync(e,"feature",s,"inbox",l,{});let y=er.getNextId(o),k=String(y).padStart(2,"0"),v=`feature-${k}-${s}.md`,E=B.join(o.root,"02-backlog",v);m.migrateEntityWorkflowIdSync(e,"feature",s,k,E,"backlog");let j={file:i,folder:"01-inbox",fullPath:l};return er.moveFile(j,"02-backlog",v,{actor:"recurring/feature-prioritise"}),Ve("git",["add","docs/specs/features/"],{cwd:e,stdio:"inherit"}),Ve("git",["commit","-m",`chore: recurring feature ${k} - ${n}`],{cwd:e,stdio:"inherit"}),{id:k,name:n}}var Rt=!1;function Ws(e){if(Rt)return console.log("[recurring] Check already in progress, skipping concurrent trigger"),{skipped:!0};Rt=!0;try{return Hs(e)}catch(t){return console.error(`[recurring] Unexpected error: ${t.message}`),{error:t.message}}finally{Rt=!1}}function Vs(e){try{let t=Ve("git",["rev-parse","--git-common-dir"],{cwd:e,stdio:"pipe"}).toString().trim(),n=Ve("git",["rev-parse","--git-dir"],{cwd:e,stdio:"pipe"}).toString().trim();return B.resolve(e,t)!==B.resolve(e,n)}catch{return!1}}function Hs(e){if(Vs(e))return console.log("[recurring] Skipping: running inside a feature worktree. Recurring tasks run from the main repo only."),{skipped:!0,reason:"worktree"};let t=B.join(e,"docs","specs","recurring"),n=Et(),r=Pt(),o=Ct(),s=tr(),i={isoWeek:n,isoQuarter:r,isoMonth:o,isoDate:s},c=It(t),l=rr(e),a={week:n,quarter:r,month:o,found:c.length,due:0,created:0,skipped:[]};console.log(`[recurring] Week ${n} quarter ${r} month ${o}: ${c.length} template(s) found`);for(let u of c){if(nr(e,u.recurringSlug)){console.log(`[recurring] ${u.recurringSlug}: open instance exists, skipping`),a.skipped.push({slug:u.recurringSlug,reason:"open instance exists"});continue}let p,f;if(u.schedule==="weekly"?(p=n,f=l[u.recurringSlug]?.lastWeek):u.schedule==="monthly"?(p=o,f=l[u.recurringSlug]?.lastMonth):(p=r,f=l[u.recurringSlug]?.lastQuarter),f===p){let d=u.schedule==="weekly"?"already created this week":u.schedule==="monthly"?"already created this month":"already created this quarter";console.log(`[recurring] ${u.recurringSlug}: ${d}, skipping`),a.skipped.push({slug:u.recurringSlug,reason:d});continue}a.due++;let h=He(u.namePattern,i);try{let d=Js(e,u,h,i),g={createdAt:new Date().toISOString()};u.schedule==="weekly"?l[u.recurringSlug]={...l[u.recurringSlug],lastWeek:n,...g}:u.schedule==="monthly"?l[u.recurringSlug]={...l[u.recurringSlug],lastMonth:o,...g}:l[u.recurringSlug]={...l[u.recurringSlug],lastQuarter:r,...g},a.created++,console.log(`[recurring] Created and prioritised: ${d.name} (ID: ${d.id})`)}catch(d){console.error(`[recurring] Failed to create ${u.recurringSlug}: ${d.message}`),a.skipped.push({slug:u.recurringSlug,reason:`error: ${d.message}`})}}try{Us(e,l)}catch(u){console.warn(`[recurring] Could not write state: ${u.message}`)}return console.log(`[recurring] Done: ${a.created} created, ${a.skipped.length} skipped`),a}function Ys(e){let t=B.join(e,"docs","specs","recurring"),n=Et(),r=Pt(),o=Ct(),s=It(t),i=rr(e);return s.map(c=>{let l=nr(e,c.recurringSlug),a,u;c.schedule==="weekly"?(a=n,u=i[c.recurringSlug]?.lastWeek):c.schedule==="monthly"?(a=o,u=i[c.recurringSlug]?.lastMonth):(a=r,u=i[c.recurringSlug]?.lastQuarter);let p=u===a,f=!l&&!p;return{recurringSlug:c.recurringSlug,schedule:c.schedule,namePattern:c.namePattern,lastWeek:i[c.recurringSlug]?i[c.recurringSlug].lastWeek:null,lastQuarter:i[c.recurringSlug]?i[c.recurringSlug].lastQuarter:null,lastMonth:i[c.recurringSlug]?i[c.recurringSlug].lastMonth:null,currentWeek:n,currentQuarter:r,currentMonth:o,isDue:f,reason:l?"open instance exists":p?c.schedule==="weekly"?"already created this week":c.schedule==="monthly"?"already created this month":"already created this quarter":null}})}or.exports={checkRecurringFeatures:Ws,listRecurringStatus:Ys,getISOWeek:Et,getISOQuarter:Pt,getISOMonth:Ct,getISODateUTC:tr,scanTemplates:It,renderPattern:Ls,renderTemplateString:He}});var cr=T((cc,ir)=>{"use strict";ir.exports=require("@senlabsai/aigon/lib/agent-registry")});var lr=T((ac,ar)=>{"use strict";ar.exports=require("@senlabsai/aigon/lib/feature-spec-resolver")});var fr=T((lc,ur)=>{"use strict";ur.exports=require("@senlabsai/aigon/lib/workflow-snapshot-adapter")});var gr=T((uc,dr)=>{"use strict";dr.exports=require("@senlabsai/aigon/lib/feature-autonomous-payload")});var mr=T((fc,hr)=>{"use strict";var pr=[{name:"minute",min:0,max:59},{name:"hour",min:0,max:23},{name:"dom",min:1,max:31},{name:"month",min:1,max:12},{name:"dow",min:0,max:7}];function Gs(e,t){let n=new Set,r=String(e).split(",");for(let o of r){let[s,i]=o.split("/"),c=i!=null?parseInt(i,10):1;if(!Number.isFinite(c)||c<1)throw new Error(`invalid step in field "${t.name}": ${o}`);let l,a;if(s==="*")l=t.min,a=t.max;else if(s.includes("-")){let[u,p]=s.split("-").map(f=>parseInt(f,10));if(!Number.isFinite(u)||!Number.isFinite(p))throw new Error(`invalid range in field "${t.name}": ${o}`);l=u,a=p}else{let u=parseInt(s,10);if(!Number.isFinite(u))throw new Error(`invalid value in field "${t.name}": ${o}`);l=u,a=u}if(l<t.min||a>t.max||l>a)throw new Error(`out-of-range value in field "${t.name}": ${o} (allowed ${t.min}-${t.max})`);for(let u=l;u<=a;u+=c)n.add(u)}if(n.size===0)throw new Error(`empty field "${t.name}"`);return n}function zs(e){let t=String(e||"").trim();if(!t)throw new Error("cron expression is empty");let n=t.split(/\s+/);if(n.length!==5)throw new Error(`cron must have 5 fields (got ${n.length}): "${t}"`);let r={};for(let o=0;o<5;o++)r[pr[o].name]=Gs(n[o],pr[o]);return r.dow.has(7)&&(r.dow.delete(7),r.dow.add(0)),r._raw=t,r._domRestricted=n[2]!=="*",r._dowRestricted=n[4]!=="*",r}function Ks(e,t){let n=new Date(t);n.setUTCSeconds(0,0),n=new Date(n.getTime()+6e4);let r=366*24*60*4;for(let o=0;o<r;o++){let s=n.getUTCMinutes(),i=n.getUTCHours(),c=n.getUTCDate(),l=n.getUTCMonth()+1,a=n.getUTCDay();if(e.minute.has(s)&&e.hour.has(i)&&e.month.has(l)){let u=e.dom.has(c),p=e.dow.has(a);if(e._domRestricted&&e._dowRestricted?u||p:u&&p)return n.getTime()}n=new Date(n.getTime()+6e4)}throw new Error(`cron "${e._raw}" produced no firing time within 4 years`)}hr.exports={parseCron:zs,nextTime:Ks}});var Dr=T((dc,Tr)=>{"use strict";var V=require("fs"),Q=require("path"),fe=require("crypto"),{spawnSync:Qs}=require("child_process"),xt=cr(),yr=lr(),Sr=fr(),{validateFeatureAutonomousPayload:Zs,buildFeatureAutonomousCliArgv:Xs}=gr(),{readConductorReposFromGlobalConfig:vr}=ct(),_t=mr(),Tt=/^[a-z0-9][a-z0-9-]{0,59}$/,de="agent_prompt",Ye=1,$r=45*1e3,wr=4e3;function Dt(e){return Q.join(e,".aigon","state","scheduled-kickoffs.json")}function ei(e){return Q.join(e,".aigon","state","scheduled-kickoffs.json.lock")}var ti=3e4;function ni(e){let t=Date.now()+e;for(;Date.now()<t;);}function kr(e){try{let t=V.statSync(e);if(Date.now()-t.mtimeMs>ti)return V.rmSync(e,{force:!0}),!0}catch{}return!1}function Ee(e,t){let n=ei(e);V.mkdirSync(Q.dirname(n),{recursive:!0}),kr(n);let r=Date.now()+8e3,o;for(;Date.now()<r;)try{o=V.openSync(n,"wx");break}catch(s){if(s.code!=="EEXIST")throw s;if(kr(n))continue;ni(5)}if(!o)throw new Error("scheduled-kickoffs: lock timeout");try{return t()}finally{try{V.closeSync(o)}catch{}try{V.rmSync(n,{force:!0})}catch{}}}function ri(e,t){let n=Q.dirname(e);V.mkdirSync(n,{recursive:!0});let r=`${e}.tmp.${process.pid}`;V.writeFileSync(r,JSON.stringify(t,null,2)),V.renameSync(r,e)}function Pe(e){let t=Dt(e);if(!V.existsSync(t))return{version:Ye,jobs:[]};try{let n=JSON.parse(V.readFileSync(t,"utf8")),r=Array.isArray(n.jobs)?n.jobs:[];return{version:Ye,jobs:r}}catch{return{version:Ye,jobs:[]}}}function ze(e,t){ri(Dt(e),t)}function oi(){return typeof fe.randomUUID=="function"?fe.randomUUID():`${Date.now()}-${fe.randomBytes(8).toString("hex")}`}function se(e){return Q.resolve(String(e||"").trim())}function Ce(e){let t=String(e||"").trim();if(!t)return{ok:!1,error:"runAt is required"};if(!/T/i.test(t))return{ok:!1,error:"runAt must be an ISO 8601 datetime (include T and timezone)"};if(!(/z$/i.test(t)||/[+-]\d{2}:\d{2}/.test(t)||/[+-]\d{2}:\d{2}:\d{2}/.test(t)||/[+-]\d{4}\s*$/.test(t)))return{ok:!1,error:"runAt must include a timezone (e.g. ...Z or ...-07:00 or ...+0530)"};let r=Date.parse(t);return Number.isNaN(r)?{ok:!1,error:"runAt is not a valid ISO 8601 datetime"}:{ok:!0,ms:r,iso:t}}function jr(e,t){let n=Array.isArray(e.agents)?e.agents.map(c=>String(c||"").trim()).filter(Boolean):[],r=!!e.background,o=!!e.foreground;if(r&&o)return{ok:!1,error:"Use either background or foreground, not both"};let s=new Set(t.getAllAgentIds()),i=n.filter(c=>!s.has(c));return i.length>0?{ok:!1,error:`Unknown agent(s): ${i.join(", ")}`}:{ok:!0,normalized:{agents:n,background:r,foreground:o}}}function Rr(e,t){let n=["research-start",e];return n.push(...t.agents),t.background&&n.push("--background"),t.foreground&&n.push("--foreground"),n}function si(){return typeof fe.randomUUID=="function"?fe.randomUUID().replace(/-/g,"").slice(0,8):fe.randomBytes(4).toString("hex")}function Fr(e,t){let n=String(e&&e.agentId||"").trim();if(!n)return{ok:!1,error:"agentId is required"};if(!new Set(t.getAllAgentIds()).has(n))return{ok:!1,error:`Unknown agent: ${n}`};let o=String(e&&e.prompt||"").trim();if(!o)return{ok:!1,error:"prompt is required"};let s=String(e&&e.label||"").trim();if(s){if(!Tt.test(s))return{ok:!1,error:"label must match [a-z0-9-]+ (start with alphanumeric, max 60 chars)"}}else s=`prompt-${si()}`;let i=null,c=e&&e.cron!=null?String(e.cron).trim():"";if(c){try{_t.parseCron(c)}catch(l){return{ok:!1,error:`invalid cron expression: ${l.message}`}}i=c}return{ok:!0,normalized:{agentId:n,prompt:o,label:s,cron:i}}}function Er(e,t){return["agent-launch","--agent",t.agentId,"--repo",e,"--prompt",t.prompt,"--label",t.label]}function Ge(e,t,n){let r=String(n).trim();if(t===de)return!r||!Tt.test(r)?{ok:!1,error:"label must match [a-z0-9-]+ (start with alphanumeric, max 60 chars)"}:{ok:!0};if(t==="feature_autonomous")return yr.listVisibleFeatureSpecs(e,r).some(c=>c.stage==="backlog"||c.stage==="in-progress")?Sr.readFeatureSnapshotSync(e,r)?{ok:!0}:{ok:!1,error:`Feature ${r} has no workflow snapshot \u2014 run aigon doctor --fix`}:{ok:!1,error:`Feature ${r} not found in backlog or in-progress for this repo`};if(t==="research_start"){let o=yr.resolveResearchSpec(e,r);if(!o||!o.path)return{ok:!1,error:`Research ${r} not found in this repo`};let s=o.stage||"";return s!=="backlog"&&s!=="in-progress"?{ok:!1,error:`Research ${r} must be in backlog or in-progress (found stage: ${s||"unknown"})`}:s==="in-progress"&&!Sr.readWorkflowSnapshotSync(e,"research",r)?{ok:!1,error:`Research ${r} is in-progress but has no workflow snapshot \u2014 run aigon doctor --fix`}:{ok:!0}}return{ok:!1,error:`Unknown kind: ${t}`}}function ii(e){let t=vr().map(o=>Q.resolve(String(o))),n=Q.resolve(process.cwd()),r=e?Q.resolve(String(e).trim()):"";return r?t.length>0&&!t.includes(r)?{ok:!1,error:"repoPath is not registered with dashboard"}:{ok:!0,repoPath:r}:t.length===1?{ok:!0,repoPath:t[0]}:t.length>1?t.includes(n)?{ok:!0,repoPath:n}:{ok:!1,error:"repoPath is required when multiple repos are registered"}:{ok:!0,repoPath:n}}function Pr(e,t){let n=se(e),r=Ce(t.runAt);if(!r.ok)return r;let o=String(t.kind||"").trim(),s=String(t.entityId||"").trim(),i;if(o==="feature_autonomous"){if(!s||!/^\d+$/.test(s))return{ok:!1,error:"entityId must be numeric"};let l=Ge(n,o,s);if(!l.ok)return l;let a=Zs({featureId:s,...t.payload},xt);if(!a.ok)return a;i=a.normalized}else if(o==="research_start"){if(!s||!/^\d+$/.test(s))return{ok:!1,error:"entityId must be numeric"};let l=Ge(n,o,s);if(!l.ok)return l;let a=jr(t.payload||{},xt);if(!a.ok)return a;i=a.normalized}else if(o===de){let l=Fr(t.payload||{},xt);if(!l.ok)return l;i=l.normalized,s=i.label;let a=Ge(n,o,s);if(!a.ok)return a}else return{ok:!1,error:"kind must be feature_autonomous, research_start, or agent_prompt"};let c={jobId:oi(),runAt:r.iso,kind:o,entityId:s,repoPath:n,payload:i,createdAt:new Date().toISOString(),status:"pending"};return Ee(n,()=>{let l=Pe(n);return l.jobs.push(c),ze(n,l),{ok:!0,job:c}})}function Cr(e,{includeAll:t=!1}={}){let n=se(e);return Ee(n,()=>{let{jobs:r}=Pe(n),o=t?r.slice():r.filter(s=>s.status==="pending");return o.sort((s,i)=>String(s.runAt).localeCompare(String(i.runAt))),o})}function ci(e,t){let n=String(t||"").trim();if(!n)return{ok:!1,error:"jobId is required"};let r=se(e);return Ee(r,()=>{let o=Pe(r),s=o.jobs.find(i=>i.jobId===n);return s?s.status==="fired"?{ok:!1,error:"Job already fired"}:s.status==="cancelled"?{ok:!0,job:s,noop:!0}:s.status==="failed"?{ok:!1,error:"Job already failed"}:s.status==="firing"?{ok:!1,error:"Job is currently being executed"}:(s.status="cancelled",s.cancelledAt=new Date().toISOString(),ze(r,o),{ok:!0,job:s}):{ok:!1,error:`No job with id ${n}`}})}function Ir(e){if(e.kind==="feature_autonomous")return Xs(e.payload);if(e.kind==="research_start")return Rr(e.entityId,e.payload);if(e.kind===de)return Er(e.repoPath,e.payload);throw new Error(`Unsupported job kind: ${e.kind}`)}function br(e){let t=String(e||"").trim();return t.length<=wr?t:`${t.slice(0,wr)}\u2026`}function ai(e,t,n){let{cliEntryPath:r,spawnSyncImpl:o,env:s}=n,i=o||Qs,c=Ir(t),l=i(process.execPath,[r,...c],{cwd:t.repoPath,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:s||{...process.env,GIT_TERMINAL_PROMPT:"0",AIGON_INVOKED_BY_DASHBOARD:"1"}});if(l.error)return{ok:!1,error:br(l.error.message)};let a=typeof l.status=="number"?l.status:1;return a!==0?{ok:!1,error:br(l.stderr||"")||`exit code ${a}`}:{ok:!0}}function xr(e,t){let n=t.now?t.now():Date.now(),r=t.cliEntryPath||Q.join(__dirname,"..","aigon-cli.js"),o=Ee(e,()=>{let i=Pe(e),c=[];for(let l of i.jobs){if(l.status!=="pending")continue;let a=Ce(l.runAt);a.ok&&a.ms<=n&&(l.status="firing",c.push(l))}return c.length&&ze(e,i),c}),s=t.log||(()=>{});for(let i of o){let c=ai(i.repoPath,i,{...t,cliEntryPath:r});if(Ee(i.repoPath,()=>{let l=Pe(i.repoPath),a=l.jobs.find(u=>u.jobId===i.jobId);!a||a.status!=="firing"||(c.ok?(a.status="fired",a.firedAt=new Date().toISOString()):(a.status="failed",a.error=c.error),ze(i.repoPath,l))}),c.ok&&i.kind===de&&i.payload&&i.payload.cron)try{let l=Ce(i.runAt),a=l.ok?l.ms:n,u=_t.parseCron(i.payload.cron),p=_t.nextTime(u,a),f=new Date(p).toISOString(),h=Pr(i.repoPath,{kind:de,entityId:i.entityId,runAt:f,payload:{...i.payload}});h.ok||s(`[scheduled-kickoff] cron re-enqueue failed for ${i.jobId}: ${h.error}`)}catch(l){s(`[scheduled-kickoff] cron re-enqueue error for ${i.jobId}: ${l&&l.message}`)}}return o.length}function li(e){let t=typeof e=="function"?e():null;if(!Array.isArray(t)||t.length===0){let n=vr();t=Array.isArray(n)&&n.length>0?n.map(se):[se(process.cwd())]}return t}function _r(e={}){let t=li(e.getRepoRoots),n=0;for(let r of t)try{n+=xr(r,e)}catch(o){(e.log||console.log)(`[scheduled-kickoff] ${r}: ${o&&o.message}`)}return n}var ue=null,Fe=null;function Ar(e){let t=String(e||"").trim(),n=new Set([t]);return/^\d+$/.test(t)&&n.add(String(parseInt(t,10))),[...n]}function ui(e){let t=se(e),n=[];try{n=Cr(t,{includeAll:!1})}catch{n=[]}let r=new Map,o=new Map;function s(c,l,a,u){let p=Ce(a);if(p.ok)for(let f of Ar(l)){let h=c.get(f);(!h||p.ms<h.ms)&&c.set(f,{runAt:a,ms:p.ms,kind:u})}}for(let c of n)c.status==="pending"&&(c.kind==="feature_autonomous"?s(r,c.entityId,c.runAt,c.kind):c.kind==="research_start"&&s(o,c.entityId,c.runAt,c.kind));function i(c,l){let a=null;for(let u of Ar(l)){let p=c.get(u);p&&(!a||p.ms<a.ms)&&(a=p)}return a?{runAt:a.runAt,kind:a.kind}:null}return{lookupFeature:c=>i(r,c),lookupResearch:c=>i(o,c)}}function fi(e={}){let t=e.intervalMs||$r,n=e.log||(()=>{});async function r(){return Fe||(Fe=Promise.resolve().then(()=>_r(e)).catch(o=>{n(`[scheduled-kickoff] tick: ${o&&o.message}`)}).finally(()=>{Fe=null}),Fe)}return r(),ue=setInterval(()=>{r()},t),typeof ue.unref=="function"&&ue.unref(),{stop(){ue&&clearInterval(ue),ue=null},tick:r}}Tr.exports={STORE_VERSION:Ye,DEFAULT_POLL_MS:$r,AGENT_PROMPT_KIND:de,LABEL_RE:Tt,getStorePath:Dt,parseRunAt:Ce,validateResearchStartPayload:jr,buildResearchStartArgv:Rr,validateAgentPromptPayload:Fr,buildAgentPromptArgv:Er,assertEntitySchedulable:Ge,resolveRepoForScheduleCli:ii,addJob:Pr,listJobs:Cr,cancelJob:ci,buildSpawnArgvForJob:Ir,processRepoDueJobs:xr,processAllReposDueJobs:_r,startScheduledKickoffPoller:fi,normalizeRepoPath:se,buildPendingScheduleIndex:ui}});var Wr=T((gc,Jr)=>{"use strict";var J=require("fs"),di=require("os"),M=require("path"),$=yt(),x="aigon-profile",gi=".sync",pi="repo",hi="sync-meta.json",mi=".syncignore",yi="config.json",Ot=["config.json","workflow-definitions"],Si=["# Defaults written by aigon profile sync \u2014 paths under ~/.aigon excluded from sync.","# Each line is a glob relative to ~/.aigon/. Lines starting with # are comments.","logs/","backups/","*.log","*.log.*","ports.json","action-logs.jsonl","conductor.pid","radar.log","dashboard.log*",".sync/","worktrees/","instances/","tmp/","sync/",""].join(`
40
+ `);function pe(){return M.join(di.homedir(),".aigon")}function Nt(){return M.join(pe(),yi)}function Or(){return M.join(pe(),gi)}function ge(){return M.join(Or(),pi)}function Mt(){return M.join(Or(),hi)}function qt(){return M.join(pe(),mi)}function Nr(){return $.loadJson(Nt())}function wi(e){$.saveJson(Nt(),e)}function Ie(){return $.loadJson(Mt())}function Ke(e){$.saveJson(Mt(),e)}function Qe(){let e=Nr();return e.sync&&e.sync.profileRemote?String(e.sync.profileRemote).trim():null}function Ze(){return $.ensureSyncIgnoreAt(qt(),Si)}function ki(){return $.readSyncIgnorePatterns(qt())}function Mr(){let e=Qe();if(!e){let t=new Error("Profile sync is not configured. Run: aigon profile configure <git-remote-url>");throw t.code="ENOPROFILECONFIG",t}return e}function bi(e){let t=[];for(let n of Ot){let r=M.join(e,n);if(!J.existsSync(r))continue;let o=J.statSync(r);if(o.isFile())t.push(n);else if(o.isDirectory())for(let s of $.listFilesUnder(e,n))t.push(s)}return t}function Ai(e){let t=pe();if(!J.existsSync(t))return 0;let n=$.makeSyncIgnoreMatcher(ki()),r=bi(t),o=0;for(let s of r){if(n(s))continue;let i=M.join(t,s),c=M.join(e,s);J.mkdirSync(M.dirname(c),{recursive:!0}),J.copyFileSync(i,c),o++}return o}function qr(e){if(!e)throw new Error("Usage: aigon profile configure <git-remote-url>");let t=Nr();t.sync=Object.assign({},t.sync||{},{profileRemote:e}),wi(t);let n=Ze();return $.ensureHelperRepoAt(ge(),e),{remote:e,syncignoreCreated:n}}function Br(){let e=Mr();Ze();let t=$.ensureHelperRepoAt(ge(),e),n=$.fetchBranch(t,x),r=Ie();if(n){let u=$.git(t,["rev-parse",`origin/${x}`],{allowFail:!0});if(u.ok&&u.stdout){let p=r.lastSyncedRemoteSha;if(p&&p!==u.stdout){let f=new Error(`Profile sync remote has new commits (was ${p.slice(0,8)}, now ${u.stdout.slice(0,8)}).
41
+ Run 'aigon profile pull' to integrate them, then retry 'aigon profile push'.`);throw f.code="EPROFILECONFLICT",f}if(!p){let f=new Error(`Remote already has ${x} commits. Run 'aigon profile pull' before the first push on this machine.`);throw f.code="EPROFILECONFLICT",f}}}$.checkoutBranch(t,x,{hadRemote:n});let o=Ai(t);$.git(t,["add","-A"]);let s=$.git(t,["status","--porcelain"]),i=$.git(t,["rev-parse","--verify","HEAD"],{allowFail:!0}).ok;if(!s.stdout&&i)return r.lastPushAt=$.nowIso(),r.lastPushFiles=o,r.lastPushNoChanges=!0,Ke(r),{committed:!1,pushed:!1,fileCount:o};let c=`aigon-profile-sync: ${$.nowIso()}`;s.stdout?$.git(t,["commit","--quiet","-m",c]):$.git(t,["commit","--quiet","--allow-empty","-m",c]);let l=$.git(t,["push","origin",`${x}:${x}`],{allowFail:!0});if(!l.ok){if(/non-fast-forward|rejected/i.test(l.stderr)){let u=new Error(`Push rejected \u2014 remote ${x} has diverged. Run 'aigon profile pull' first, resolve any conflicts, then retry.`);throw u.code="EPROFILECONFLICT",u}throw new Error(`Profile sync push failed: ${l.stderr||"unknown error"}`)}let a=$.git(t,["rev-parse",x],{allowFail:!0});return r.lastPushAt=$.nowIso(),r.lastPushMessage=c,r.lastPushFiles=o,r.lastPushNoChanges=!1,a.ok&&a.stdout&&(r.lastSyncedRemoteSha=a.stdout),Ke(r),{committed:!0,pushed:!0,fileCount:o,message:c}}function Lr(){let e=Mr();Ze();let t=$.ensureHelperRepoAt(ge(),e);if(!$.fetchBranch(t,x)){let l=Ie();return l.lastPullAt=$.nowIso(),l.lastPullEmpty=!0,Ke(l),{applied:!1,reason:"remote-empty"}}if($.git(t,["rev-parse","--verify",x],{allowFail:!0}).ok){let l=$.git(t,["rev-list",`origin/${x}..${x}`],{allowFail:!0}),a=$.git(t,["rev-list",`${x}..origin/${x}`],{allowFail:!0}),u=l.ok&&l.stdout?l.stdout.split(`
42
+ `).length:0,p=a.ok&&a.stdout?a.stdout.split(`
43
+ `).length:0;if(u>0&&p>0){let f=new Error(`Profile sync branch has diverged: ${u} local-only and ${p} remote-only commits.
44
+ Resolve manually:
45
+ cd ${ge()} && git pull --rebase origin ${x}
46
+ Then retry: aigon profile push`);throw f.code="EPROFILECONFLICT",f}}$.checkoutBranch(t,x,{hadRemote:!0,clearWorkingTree:!1});let o=pe();J.mkdirSync(o,{recursive:!0});let s=0;for(let l of Ot){let a=M.join(t,l);if(!J.existsSync(a))continue;let u=J.statSync(a);if(u.isFile()){let p=M.join(o,l);J.mkdirSync(M.dirname(p),{recursive:!0}),J.copyFileSync(a,p),s++}else if(u.isDirectory())for(let p of $.listFilesUnder(t,l)){let f=M.join(t,p),h=M.join(o,p);J.mkdirSync(M.dirname(h),{recursive:!0}),J.copyFileSync(f,h),s++}}let i=Ie();i.lastPullAt=$.nowIso(),i.lastPullFiles=s,i.lastPullEmpty=!1;let c=$.git(t,["rev-parse",x],{allowFail:!0});return c.ok&&c.stdout&&(i.lastSyncedRemoteSha=c.stdout),Ke(i),{applied:!0,fileCount:s}}function Ur(){let e=Qe(),t=Ie(),n={configured:!!e,remote:e||null,lastPushAt:t.lastPushAt||null,lastPullAt:t.lastPullAt||null,localOnlyCommits:0,remoteOnlyCommits:0,diverged:!1,helperReady:!1};if(!e)return n;try{let r=$.ensureHelperRepoAt(ge(),e);n.helperReady=!0;let o=$.fetchBranch(r,x),s=$.git(r,["rev-parse","--verify",x],{allowFail:!0}).ok;if(o&&s){let i=$.git(r,["rev-list",`origin/${x}..${x}`],{allowFail:!0}),c=$.git(r,["rev-list",`${x}..origin/${x}`],{allowFail:!0});n.localOnlyCommits=i.ok&&i.stdout?i.stdout.split(`
47
+ `).length:0,n.remoteOnlyCommits=c.ok&&c.stdout?c.stdout.split(`
48
+ `).length:0,n.diverged=n.localOnlyCommits>0&&n.remoteOnlyCommits>0}else if(o&&!s){let i=$.git(r,["rev-list","--count",`origin/${x}`],{allowFail:!0});n.remoteOnlyCommits=i.ok&&parseInt(i.stdout,10)||0}else if(!o&&s){let i=$.git(r,["rev-list","--count",x],{allowFail:!0});n.localOnlyCommits=i.ok&&parseInt(i.stdout,10)||0}}catch{n.helperReady=!1}return n}function vi(){let e=Qe(),t=Ie();return{configured:!!e,remote:e||null,lastPushAt:t.lastPushAt||null,lastPullAt:t.lastPullAt||null}}function $i(){console.log("Usage: aigon profile <command> [options]"),console.log(""),console.log("Profile (project type) commands:"),console.log(" show Display current project profile and settings"),console.log(" set <type> Set project profile (web, api, ios, android, library, generic)"),console.log(" detect Show what auto-detection would choose"),console.log(""),console.log("Profile sync commands (sync ~/.aigon between machines):"),console.log(" configure <git-url> Configure remote and create ~/.aigon/.syncignore"),console.log(" push Commit ~/.aigon/ profile and push to aigon-profile branch"),console.log(" pull Fetch + fast-forward merge aigon-profile from configured remote"),console.log(" status Show last push/pull timestamps and divergence")}async function ji(e=[]){let t=e[0],n=e.slice(1);if(t==="configure"){let r=qr(n[0]);console.log("\u2705 Profile sync configured"),console.log(` Remote: ${r.remote}`),r.syncignoreCreated&&console.log(" Created: ~/.aigon/.syncignore (defaults)");return}if(t==="push"){let r=Br();r.committed?(console.log(`\u2705 Profile sync push: ${r.fileCount} files committed`),console.log(` ${r.message}`)):console.log("\u2705 Profile sync push: no changes to commit");return}if(t==="pull"){let r=Lr();r.applied?console.log(`\u2705 Profile sync pull: ${r.fileCount} files restored`):console.log("\u2705 Profile sync pull: remote has no aigon-profile branch yet");return}if(t==="status"){let r=Ur();if(!r.configured){console.log("Profile sync: not configured"),console.log("Run: aigon profile configure <git-remote-url>");return}console.log("Profile sync: configured"),console.log(` Remote: ${r.remote}`),console.log(` Last push: ${r.lastPushAt||"never"}`),console.log(` Last pull: ${r.lastPullAt||"never"}`),console.log(` Local-only commits: ${r.localOnlyCommits}`),console.log(` Remote-only commits: ${r.remoteOnlyCommits}`),r.diverged&&console.log(" \u26A0\uFE0F Branches have diverged \u2014 pull or rebase before pushing.");return}throw new Error(`Unknown profile sync command: ${t}
49
+ Run: aigon profile --help`)}Jr.exports={PROFILE_BRANCH:x,PROFILE_INCLUDES:Ot,handleProfileSyncCommand:ji,configure:qr,push:Br,pull:Lr,status:Ur,statusLocal:vi,getProfileRemote:Qe,ensureProfileSyncIgnore:Ze,profileRoot:pe,profileConfigPath:Nt,helperRepoPath:ge,metaPath:Mt,syncIgnorePath:qt,printUsage:$i}});var Kr=T((pc,zr)=>{"use strict";var Ri=require("fs"),Xe=require("path"),Fi=require("os"),{chooseNextAgent:et,getAgentRuntimeId:xe,getLastReachableCommit:Vr,resolveFailoverConfig:Hr,clearTokenExhaustedFlag:Yr}=require("@senlabsai/aigon/lib/agent-exhaustion-detect"),Ei=require("@senlabsai/aigon/lib/workflow-core"),{readAgentStatusRecordAt:Pi}=require("@senlabsai/aigon/lib/agent-status"),{resolveAgentPromptBody:Ci}=require("@senlabsai/aigon/lib/agent-prompt-resolver"),{buildAgentCommand:Ii,buildTmuxSessionName:xi,createDetachedTmuxSession:_i,runTmux:Ti}=require("@senlabsai/aigon/lib/worktree"),{resolveFeatureWorktreePath:Di}=require("@senlabsai/aigon/lib/dashboard-status-helpers"),{getAgentCliConfig:Oi}=require("@senlabsai/aigon/lib/config"),Ni=require("@senlabsai/aigon/lib/workflow-snapshot-adapter");function Gr(e,t){let n=["","## Failover Handoff",`- Previous slot: ${t.slotAgentId}`,`- Previous implementation agent: ${t.previousAgentId||t.slotAgentId}`,`- Replacement agent: ${t.replacementAgentId}`,`- Last reachable commit: ${t.lastCommit||"none"}`,"- Continue from the current branch and worktree state.","- Do not reset the branch, discard work, or re-plan the feature from scratch."].join(`
50
+ `);return`${e.trimEnd()}
51
+ ${n}
52
+ `}function Mi(e,t,n){let r=Pi(e,t,n,{prefixes:["feature"]});return r&&r.data&&r.data.worktreePath?r.data.worktreePath:Di(Xe.join(Fi.homedir(),".aigon","worktrees",Xe.basename(e)),t,n,e)}async function Bt(e,t,n,r,o,s){let i=n.agents&&n.agents[r];if(!i)return!1;let c=Mi(e,t,r);if(!c||!Ri.existsSync(c))return!1;let l=Vr(c),a=Xe.basename(c).match(/^feature-\d+-[a-z0-9]+-(.+)$/),u=a?a[1]:null,p=Ci({agentId:o,verb:"do",featureId:t,cliConfig:Oi(o,e)}),f=Gr(p,{slotAgentId:r,previousAgentId:xe(i,r),replacementAgentId:o,lastCommit:l}),h=xi(t,r,{repo:Xe.basename(e),role:"do",desc:u});try{Ti(["kill-session","-t",h],{stdio:"ignore"})}catch{}let d=Ii({agent:o,slotAgentId:r,featureId:t,path:c,desc:u,repoPath:e,snapshot:n,promptOverride:f});return _i(h,c,d,{repoPath:e,entityType:"f",entityId:t,agent:r,role:"do",worktreePath:c}),await Ei.recordAgentFailoverSwitch(e,t,{agentId:r,previousAgentId:xe(i,r),replacementAgentId:o,source:s,lastCommit:l}),Yr(e,t,r,o,c),!0}async function qi({repoPath:e,entityId:t,agentId:n,signal:r,snapshot:o,failoverConfig:s}){let i=et(s.chain,r.currentAgentId,[r.currentAgentId]);i&&await Bt(e,t,o,n,i,r.source)}function Bi(e,t,n,r,o,s){if(t!=="feature"||!Array.isArray(o))return Array.isArray(s)?s:[];let i=Array.isArray(s)?s.slice():[],c=new Set(i.filter(l=>l.action==="switch-agent").map(l=>l.agentId));for(let l of o){if(!l||!l.id)continue;let a=l.id;if(c.has(a))continue;let u=r&&r.agents?r.agents[a]:null;if(!u||!u.tokenExhausted)continue;let p=Hr(e,r),f=xe(u,a),h=et(p.chain,f,[f]),d=!h,g=h?`Failover now \u2192 ${h}`:"Failover now";i.push({command:`aigon feature-failover ${n} ${a}`,label:g,reason:d?"No agents left in failover chain":`Switch ${a} to ${h}`,action:"switch-agent",kind:"switch-agent",agentId:a,mode:null,category:"agent-control",type:"action",to:null,priority:"normal",requiresInput:null,scope:null,metadata:{nextAgentId:h||null,chainExhausted:d,flagAction:"switch-agent"},clientOnly:!1}),c.add(a)}return i}function Li(e){let{resolveRequestedRepoPath:t,sendJson:n}=e;return function(o,s,i){return i.readJsonBody().catch(()=>(n(s,400,{error:"Invalid JSON body"}),null)).then(async c=>{if(!c)return;let l=String(c.featureId||"").trim(),a=String(c.agentId||"").trim();if(!l||!a){n(s,400,{error:"featureId and agentId are required"});return}let u=t(String(c.repoPath||"").trim());if(!u.ok){n(s,u.status||400,{error:u.error||"Invalid repoPath"});return}let p=u.repoPath;try{let f=Ni.readFeatureSnapshotSync(p,l),h=f&&f.agents?f.agents[a]:null;if(!f||!h){n(s,404,{error:`Agent ${a} not found on feature ${l}`});return}if(!h.tokenExhausted){n(s,409,{error:"Switch is only allowed after token exhaustion is recorded for this agent slot"});return}let d=Hr(p,f),g=xe(h,a),w=et(d.chain,g,[g]);if(!w){n(s,409,{error:`No failover candidate available for ${a} (chain exhausted)`});return}if(!await Bt(p,l,f,a,w,"manual")){n(s,500,{error:"Switch failed \u2014 worktree not found or inaccessible"});return}n(s,200,{ok:!0,message:`Switched ${a} \u2192 ${w}`,replacementAgentId:w})}catch(f){n(s,500,{error:f.message})}})}}zr.exports={buildFailoverPrompt:Gr,clearTokenExhaustedFlag:Yr,switchFeatureAgent:Bt,handleExhaustion:qi,appendFailoverDashboardActions:Bi,createFailoverRouteHandler:Li,chooseNextAgent:et,getAgentRuntimeId:xe,getLastReachableCommit:Vr}});var Ui=require("fs"),Ji=require("os"),H=require("path"),tt=en(),nt=on(),Wi=vn(),he=Yn(),Qr=sr(),ie=Dr(),Zr=Wr(),Lt=Kr(),Vi=he,Xr=Buffer.from("YWlnb24tcHJvLWJldGEtMjAyNg==","base64").toString();function eo(){try{return JSON.parse(Ui.readFileSync(H.join(Ji.homedir(),".aigon","config.json"),"utf8")).proKey||null}catch{return null}}var Hi=eo()===Xr;function Yi(){return Hi}function Gi(e){let t=eo();if(!t){process.stderr.write(`Aigon Pro: no key found. Run: aigon pro activate <your-key>
53
+ `);return}if(t!==Xr){process.stderr.write(`Aigon Pro: invalid key. Run: aigon pro activate <your-key>
54
+ `);return}let n=e.helpers||{},{loadProjectConfig:r,resolveRequestedRepoPath:o,sendJson:s,readConductorReposFromGlobalConfig:i}=n,c=typeof n.log=="function"?n.log:()=>{},l=typeof n.emitNotification=="function"?n.emitNotification:()=>{};typeof n.registerExhaustionHandler=="function"&&n.registerExhaustionHandler(Lt.handleExhaustion),typeof n.registerFailoverActionAppender=="function"&&n.registerFailoverActionAppender(Lt.appendFailoverDashboardActions),e.registerRoute("POST","/api/feature-failover",Lt.createFailoverRouteHandler(n)),e.registerRoute("GET","/api/insights",(d,g,w)=>{let m=String(w.url.searchParams.get("repoPath")||"").trim(),y=o(m);if(!y.ok)return s(g,y.status||400,{error:y.error||"Invalid repoPath"});let k=y.repoPath,v=tt.readInsightsCache(k);return v?s(g,200,v):tt.generateAndCacheInsights({repoPath:k,includeCoaching:!1,loadProjectConfig:r}).then(E=>s(g,200,E)).catch(E=>s(g,500,{error:E.message}))}),e.registerRoute("POST","/api/insights/refresh",(d,g,w)=>w.readJsonBody().catch(()=>(s(g,400,{error:"Invalid JSON body"}),null)).then(m=>{if(!m)return;let y=o(m.repoPath);return y.ok?tt.generateAndCacheInsights({repoPath:y.repoPath,includeCoaching:!1,loadProjectConfig:r}).then(k=>s(g,200,k)).catch(k=>s(g,500,{error:k.message})):s(g,y.status||400,{error:y.error||"Invalid repoPath"})})),e.registerRoute("GET","/api/benchmarks/latest",(d,g,w)=>{let m=String(w.url.searchParams.get("repoPath")||"").trim(),y=o(m);if(!y.ok)return s(g,y.status||400,{error:y.error||"Invalid repoPath"});try{let k=y.repoPath,v=k,E=!1;if(!nt.repoHasBenchmarks(k)){let O=(typeof i=="function"?i():[]).map(I=>H.resolve(String(I)));for(let I of O)if(I!==k&&nt.repoHasBenchmarks(I)){v=I,E=!0;break}}let j=nt.buildLatestMatrix(v);return j.sourceRepo=v,j.requestedRepo=k,j.sourceRepoFellBack=E,s(g,200,j)}catch(k){return s(g,500,{error:k.message})}}),e.registerRoute("GET","/api/profile/status",(d,g)=>{try{s(g,200,Zr.statusLocal())}catch(w){s(g,500,{error:w.message})}}),e.registerRoute("GET","/api/settings-sync/status",(d,g)=>{try{s(g,200,he.status())}catch(w){s(g,500,{error:w.message})}}),e.registerRoute("GET","/api/backup/status",(d,g)=>{try{s(g,200,he.status())}catch(w){s(g,500,{error:w.message})}}),e.registerRoute("POST","/api/backup/schedule",(d,g,w)=>w.readJsonBody().then(m=>{let y=String(m&&m.cadence||"").toLowerCase();try{let k=he.setSchedule(y);s(g,200,{ok:!0,schedule:k})}catch(k){s(g,400,{error:k.message})}}).catch(m=>s(g,400,{error:m.message}))),e.registerRoute("GET","/api/sync/status",(d,g,w)=>{try{let m=require("fs"),y=String(w.url.searchParams.get("repoPath")||process.cwd()),k=H.join(y,".aigon","config.json"),v=H.join(y,".aigon",".sync","sync-meta.json"),E={};try{E=JSON.parse(m.readFileSync(k,"utf8"))}catch{}let j={};try{j=JSON.parse(m.readFileSync(v,"utf8"))}catch{}let O=E.sync&&E.sync.remote?String(E.sync.remote).trim():null;s(g,200,{configured:!!O,remote:O||null,lastPushAt:j.lastPushAt||null,lastPullAt:j.lastPullAt||null})}catch(m){s(g,500,{error:m.message})}});let a=require("os");e.registerRoute("GET","/api/schedule/jobs",(d,g,w)=>{try{let m=String(w.url.searchParams.get("repoPath")||w.url.searchParams.get("path")||"").trim(),y=w.url.searchParams.get("all")==="1"||w.url.searchParams.get("all")==="true",k=i().map(j=>H.resolve(String(j))),v=(()=>{if(m){let j=H.resolve(m.startsWith("~")?m.replace(/^~/,a.homedir()):m);return k.length>0&&!k.includes(j)?(s(g,403,{error:"repoPath is not registered with dashboard"}),null):[j]}return k.length>0?k:[H.resolve(process.cwd())]})();if(!v)return;let E=[];for(let j of v){let O=ie.listJobs(j,{includeAll:y});for(let I of O){let Ut=a.homedir();E.push({...I,repoPath:j,displayPath:j.startsWith(Ut)?"~"+j.slice(Ut.length):j})}}E.sort((j,O)=>String(j.runAt).localeCompare(String(O.runAt))),s(g,200,{jobs:E})}catch(m){s(g,500,{error:m.message})}}),e.registerRoute("POST","/api/schedule/add",(d,g,w)=>w.readJsonBody().then(m=>{try{let y=ie.resolveRepoForScheduleCli(m.repoPath!=null?String(m.repoPath):"");if(!y.ok){s(g,400,{error:y.error});return}let k=String(m.kind||"").trim(),v=String(m.entityId||"").trim(),E=String(m.runAt||"").trim(),j=ie.addJob(y.repoPath,{kind:k,entityId:v,runAt:E,payload:m.payload||{}});if(!j.ok){s(g,400,{error:j.error});return}s(g,200,{ok:!0,job:j.job})}catch(y){s(g,500,{error:y.message})}}).catch(()=>s(g,400,{error:"Invalid JSON body"}))),e.registerRoute("POST","/api/schedule/cancel",(d,g,w)=>w.readJsonBody().then(m=>{try{let y=ie.resolveRepoForScheduleCli(m.repoPath!=null?String(m.repoPath):"");if(!y.ok){s(g,400,{error:y.error});return}let k=String(m.jobId||"").trim(),v=ie.cancelJob(y.repoPath,k);if(!v.ok){s(g,400,{error:v.error});return}s(g,200,{ok:!0,job:v.job,noop:!!v.noop})}catch(y){s(g,500,{error:y.message})}}).catch(()=>s(g,400,{error:"Invalid JSON body"})));let u=String(n.defaultRepoPath||process.cwd()),p=String(n.cliEntryPath||require.resolve("@senlabsai/aigon/aigon-cli.js")),f=()=>{let d=i().map(g=>H.resolve(String(g)));d.length===0&&d.push(u);for(let g of d)try{Qr.checkRecurringFeatures(g)}catch(w){c(`[recurring] Check failed for ${g}: ${w&&w.message}`)}};f(),setInterval(f,1440*60*1e3).unref();try{ie.startScheduledKickoffPoller({log:c,getRepoRoots:()=>i().map(d=>H.resolve(String(d))),cliEntryPath:p})}catch(d){c(`Scheduled kickoff poller failed to start: ${d&&d.message}`)}let h=()=>{let d=he.runScheduledPushIfDue();if(d.ran)if(d.ok)c(`[backup] scheduled push ok (${d.result&&d.result.fileCount||0} files)`);else{c(`[backup] scheduled push failed: ${d.error}`);try{l("backup-failed",`Backup push failed: ${d.error}`,{code:d.code})}catch{}}};h(),setInterval(h,3600*1e3).unref()}module.exports={insights:tt,benchmarkArtifacts:nt,sync:Wi,vault:Vi,backup:he,recurring:Qr,scheduledKickoff:ie,profile:Zr,dashboardDir:H.join(__dirname,"dashboard"),commandsDir:H.join(__dirname,"commands"),register:Gi,isActivated:Yi};
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@senlabsai/aigon-pro",
3
+ "version": "0.1.0",
4
+ "description": "Aigon Pro — autonomous pipelines, agent failover, scheduled features, Insights analytics, and Aigon Sync",
5
+ "main": "dist/index.js",
6
+ "scripts": {
7
+ "build": "node scripts/build.js",
8
+ "prepublishOnly": "npm run build",
9
+ "test": "node tests/insights.test.js && node tests/benchmark-artifacts.test.js && node tests/backup.test.js"
10
+ },
11
+ "keywords": [
12
+ "aigon",
13
+ "aade",
14
+ "insights"
15
+ ],
16
+ "license": "UNLICENSED",
17
+ "publishConfig": {
18
+ "registry": "https://registry.npmjs.org",
19
+ "access": "public"
20
+ },
21
+ "files": [
22
+ "dist/index.js"
23
+ ],
24
+ "devDependencies": {
25
+ "esbuild": "^0.28.0"
26
+ }
27
+ }