@oxgeneral/orch 1.0.11 → 1.0.14

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.
@@ -0,0 +1,6 @@
1
+ export { Orchestrator } from './chunk-C6II4C6Y.js';
2
+ import './chunk-XUZZJCKG.js';
3
+ import './chunk-RHFRHCN5.js';
4
+ import './chunk-NLQAJ7TW.js';
5
+ //# sourceMappingURL=orchestrator-NC2NCJBC.js.map
6
+ //# sourceMappingURL=orchestrator-NC2NCJBC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"orchestrator-47LRXS6X.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"orchestrator-NC2NCJBC.js"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import {d as d$2,e as e$2,c as c$1}from'./chunk-LY3X2UHQ.js';import {e,c,b,d as d$1,g,f}from'./chunk-KR7VDF23.js';import {a}from'./chunk-CHRW4CLD.js';import {a as a$1}from'./chunk-P4JTJBWO.js';import {d,l,h,e as e$1,n}from'./chunk-IKNBPOQL.js';import {dirname}from'path';import A from'fs/promises';import {execFile}from'child_process';function et(l,t){if(!l?.length||!t?.length)return false;for(let e of l)for(let s of t)if(pt(e,s))return true;return false}function j(l){let t=l.split("*")[0],e=!t.endsWith("/"),s=e?dirname(t):"";return {raw:l,base:t,isFile:e,dir:s}}var x=class{entries;constructor(t){this.entries=[];for(let e of t)if(e?.length)for(let s of e)this.entries.push(j(s));}overlapsAny(t){if(!t?.length||this.entries.length===0)return false;for(let e of t){let s=j(e);for(let a of this.entries)if(ht(s,a))return true}return false}add(t){if(t?.length)for(let e of t)this.entries.push(j(e));}get size(){return this.entries.length}};function ht(l,t){return l.raw===t.raw||l.base.startsWith(t.base)||t.base.startsWith(l.base)?true:l.isFile&&t.isFile?l.dir===t.dir&&l.dir!==".":false}function pt(l,t){if(l===t)return true;let e=l.split("*")[0],s=t.split("*")[0];if(e.startsWith(s)||s.startsWith(e))return true;if(!e.endsWith("/")&&!s.endsWith("/")){let a=dirname(e),r=dirname(s);return a===r&&a!=="."}return false}var st=Promise.resolve();async function F(l){let t,e=new Promise(a=>{t=a;}),s=st;st=e,await s;try{return await gt(l)}finally{t();}}var ft=6e4;async function gt(l){let t=await it(l);if(t!==null){if(vt(t)&&!await mt(l))return {acquired:false,pid:t};await A.unlink(l).catch(()=>{});}try{let e=await A.open(l,"wx");return await e.writeFile(String(process.pid),"utf-8"),await e.close(),{acquired:!0,pid:process.pid}}catch(e){if(e.code==="EEXIST")return {acquired:false,pid:await it(l)??void 0};throw e}}async function G(l){await A.unlink(l).catch(()=>{});}async function at(l){let t=Date.now()/1e3;await A.utimes(l,t,t).catch(()=>{});}async function it(l){try{let t=await A.readFile(l,"utf-8"),e=parseInt(t.trim(),10);return isNaN(e)?null:e}catch{return null}}async function mt(l){try{let t=await A.stat(l);return Date.now()-t.mtimeMs>ft}catch{return true}}function vt(l){try{return process.kill(l,0),!0}catch(t){return t.code==="EPERM"}}var C=class{constructor(t){this.inner=t;}cache=new Map;async list(t){let e=t?`${t.status??""}:${t.goalId??""}`:"__all__";if(this.cache.has(e))return this.cache.get(e);let s=await this.inner.list(t);return this.cache.set(e,s),s}async get(t){return this.inner.get(t)}async save(t){await this.inner.save(t),this.cache.clear();}async delete(t){await this.inner.delete(t),this.cache.clear();}invalidate(){this.cache.clear();}},O=class{constructor(t){this.inner=t;}listCache=null;nameCache=new Map;async list(){if(this.listCache)return this.listCache;let t=await this.inner.list();return this.listCache=t,t}async get(t){return this.inner.get(t)}async getByName(t){if(this.nameCache.has(t))return this.nameCache.get(t)??null;let e=await this.inner.getByName(t);return this.nameCache.set(t,e),e}async save(t){await this.inner.save(t),this.listCache=null,this.nameCache.clear();}async delete(t){await this.inner.delete(t),this.listCache=null,this.nameCache.clear();}invalidate(){this.listCache=null,this.nameCache.clear();}},B=class{constructor(t){this.inner=t;}cache=new Map;async list(t){let e=t?.status??"__all__";if(this.cache.has(e))return this.cache.get(e);let s=await this.inner.list(t);return this.cache.set(e,s),s}async get(t){return this.inner.get(t)}async save(t){await this.inner.save(t),this.cache.clear();}async delete(t){await this.inner.delete(t),this.cache.clear();}invalidate(){this.cache.clear();}};var wt={test_pass:{cmd:"npm",args:["test"]},typecheck:{cmd:"npx",args:["tsc","--noEmit"]},lint:{cmd:"npm",args:["run","lint"]}},rt=["typecheck","lint","test_pass"],R=class{cwd;timeoutMs;failFast;constructor(t){this.cwd=t.cwd,this.timeoutMs=t.timeout_ms??12e4,this.failFast=t.fail_fast??true;}async runAll(t){let e=yt(t),s=[];for(let a of e){let r=await this.runCriterion(a);if(s.push(r),this.failFast&&!r.passed)break}return s}static allPassed(t){return t.length>0&&t.every(e=>e.passed)}static formatReport(t){return t.map(s=>{let a=s.passed?"\u2713":"\u2717",r=s.output;return `${a} ${s.criterion}: ${s.passed?"PASSED":"FAILED"}
3
+ ${r}`}).join(`
4
+
5
+ `)}runCriterion(t){let{cmd:e,args:s}=wt[t];return new Promise(a=>{execFile(e,s,{cwd:this.cwd,timeout:this.timeoutMs,maxBuffer:1024*1024},(r,d,n)=>{let o=(d+`
6
+ `+n).trim();a({criterion:t,passed:!r,output:o.slice(0,2e3)});});})}};function yt(l){return [...l].sort((t,e)=>{let s=rt.indexOf(t),a=rt.indexOf(e);return (s===-1?1/0:s)-(a===-1?1/0:a)})}var kt=8192,_t=4096,nt=class l$1{constructor(t){this.deps=t;this.cachedTaskStore=new C(t.taskStore),this.cachedAgentStore=new O(t.agentStore),this.cachedGoalStore=t.goalStore?new B(t.goalStore):null;}intervalId=null;shuttingDown=false;state=null;abortControllers=new Map;cachedTaskStore;cachedAgentStore;cachedGoalStore;saveStateTimer=null;saveStateDirty=false;lockAcquired=false;consecutiveTickFailures=0;maxConsecutiveTickFailures=5;maxRetryQueueSize=100;signalHandlers=[];immediateDispatchTimer=null;taskCreatedUnsub=null;tickInProgress=false;stoppedResolvers=[];skipAutonomousSeeding=false;lastAutoSeedAt=new Map;static AUTO_SEED_COOLDOWN_MS=3e4;stateMutex=Promise.resolve();get isOwner(){return this.lockAcquired}withStateLock(t){let e,s=new Promise(r=>{e=r;}),a=this.stateMutex;return this.stateMutex=s,a.then(async()=>{try{return await t()}finally{e();}})}async runTask(t){if(this.lockAcquired){await this.freshDispatch(()=>this.dispatchTask(t));return}await this.withTemporaryLock(()=>this.freshDispatch(()=>this.dispatchTask(t)));}async runAll(){if(this.lockAcquired){await this.freshDispatch(()=>this.dispatchAll());return}await this.withTemporaryLock(()=>this.freshDispatch(()=>this.dispatchAll()));}async freshDispatch(t){await this.withStateLock(async()=>{this.cachedTaskStore.invalidate(),this.cachedAgentStore.invalidate(),await this.loadState(),await t(),await this.saveState();});}async withTemporaryLock(t){let e=await F(this.deps.lockPath);if(!e.acquired)throw new d(e.pid);this.lockAcquired=true;try{await t();}finally{this.lockAcquired=false,await G(this.deps.lockPath);}}async startWatch(t){this.skipAutonomousSeeding=t?.skipAutonomousSeeding??false;let e=await F(this.deps.lockPath);if(!e.acquired)throw new d(e.pid);this.lockAcquired=true,await this.loadState(),await this.cleanupStaleRunningEntries(),this.state.pid=process.pid,this.state.started_at=new Date().toISOString(),await this.saveState(),this.registerSignalHandlers(),this.taskCreatedUnsub=this.deps.eventBus.on("task:created",()=>{this.scheduleImmediateDispatch();}),await this.tick(),this.intervalId=setInterval(()=>this.tick().then(()=>{this.consecutiveTickFailures=0;},s=>{this.consecutiveTickFailures++;let a=s instanceof Error?s.message:String(s);this.deps.eventBus.emit({type:"orchestrator:error",error:a,context:"tick",fatal:this.consecutiveTickFailures>=this.maxConsecutiveTickFailures}),this.consecutiveTickFailures>=this.maxConsecutiveTickFailures&&(this.deps.eventBus.emit({type:"orchestrator:shutdown",reason:`${this.consecutiveTickFailures} consecutive tick failures`}),this.stop().catch(r=>{this.deps.eventBus.emit({type:"orchestrator:error",error:r instanceof Error?r.message:String(r),context:"stop after consecutive tick failures",fatal:false});}));}),this.deps.config.scheduling.poll_interval_ms);}waitForStop(){return this.shuttingDown?Promise.resolve():new Promise(t=>{this.stoppedResolvers.push(t);})}registerSignalHandlers(){let t=e=>{this.deps.eventBus.emit({type:"orchestrator:shutdown",reason:`Received ${e}`}),this.stop().catch(s=>{this.deps.eventBus.emit({type:"orchestrator:error",error:s instanceof Error?s.message:String(s),context:`stop after ${e} signal`,fatal:false});});};for(let e of ["SIGINT","SIGTERM"]){let s=()=>t(e);this.signalHandlers.push([e,s]),process.on(e,s);}}removeSignalHandlers(){for(let[t,e]of this.signalHandlers)process.removeListener(t,e);this.signalHandlers=[];}async stop(){if(!this.shuttingDown){this.shuttingDown=true,this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),this.taskCreatedUnsub&&(this.taskCreatedUnsub(),this.taskCreatedUnsub=null),this.immediateDispatchTimer&&(clearTimeout(this.immediateDispatchTimer),this.immediateDispatchTimer=null),await this.flushStateLazy(),await this.withStateLock(async()=>{if(this.state){for(let[t,e$1]of Object.entries(this.state.running)){this.abortControllers.get(t)?.abort(),this.abortControllers.delete(t),await this.deps.processManager.killWithGrace(e$1.pid),await this.deps.runService.finish(e$1.run_id,"cancelled");let s=await this.deps.taskStore.get(t);s&&await this.deps.taskService.updateStatus(t,e(s)),await this.deps.agentService.setStatus(e$1.agent_id,"idle");}this.state.running={},this.state.claimed=new Set,this.state.pid=void 0,this.state.started_at=void 0,await this.saveState();}}),this.lockAcquired&&(await G(this.deps.lockPath),this.lockAcquired=false),this.removeSignalHandlers();for(let t of this.stoppedResolvers)t();this.stoppedResolvers=[];}}async cancelTask(t){if(!this.lockAcquired)return this.withTemporaryLock(()=>this.cancelTask(t));await this.withStateLock(async()=>{await this.loadState();let e=this.state,s=e.running[t];s&&(this.abortControllers.get(t)?.abort(),this.abortControllers.delete(t),await this.deps.processManager.killWithGrace(s.pid,3e3).catch(a=>{this.deps.eventBus.emit({type:"orchestrator:error",error:a instanceof Error?a.message:String(a),context:`cancelTask kill process ${s.pid} for task ${t}`,fatal:false});}),await this.deps.runService.finish(s.run_id,"cancelled").catch(a=>{this.deps.eventBus.emit({type:"orchestrator:error",error:a instanceof Error?a.message:String(a),context:`cancelTask finish run ${s.run_id}`,fatal:false});}),await this.deps.agentService.setStatus(s.agent_id,"idle").catch(a=>{this.deps.eventBus.emit({type:"orchestrator:error",error:a instanceof Error?a.message:String(a),context:`cancelTask setStatus idle for agent ${s.agent_id}`,fatal:false});}),delete e.running[t],await this.saveState()),e.retry_queue=e.retry_queue.filter(a=>a.task_id!==t);try{await this.deps.taskService.cancel(t);}catch{try{await this.deps.taskService.updateStatus(t,"cancelled");}catch{}}await this.saveState();});}async forceStopAgent(t){if(!this.lockAcquired)return this.withTemporaryLock(()=>this.forceStopAgent(t));await this.withStateLock(async()=>{await this.loadState();let e=this.state;for(let[s,a]of Object.entries(e.running))if(a.agent_id===t){this.abortControllers.get(s)?.abort(),this.abortControllers.delete(s),await this.deps.processManager.killWithGrace(a.pid,3e3),await this.deps.runService.finish(a.run_id,"cancelled");try{await this.deps.taskService.updateStatus(s,"failed");}catch{}delete e.running[s];}await this.deps.agentService.setStatus(t,"idle"),await this.saveState();});}async tick(){if(!this.shuttingDown){this.tickInProgress=true;try{await this.withStateLock(async()=>{if(this.shuttingDown)return;this.cachedTaskStore.invalidate(),this.cachedAgentStore.invalidate(),this.cachedGoalStore?.invalidate(),await this.loadState(),await this.reconcile(),this.skipAutonomousSeeding||await this.seedAutonomousTasks(),await this.dispatchAll();let t=await this.cachedTaskStore.list(),e=Object.keys(this.state.running).length,s=t.filter(a=>c(a.status)).length;this.deps.eventBus.emit({type:"orchestrator:tick",running:e,queued:s});}),await at(this.deps.lockPath);}finally{this.tickInProgress=false;}}}scheduleImmediateDispatch(t=0){this.shuttingDown||this.immediateDispatchTimer||(this.immediateDispatchTimer=setTimeout(()=>{if(this.immediateDispatchTimer=null,!this.shuttingDown){if(this.tickInProgress){t<10&&this.scheduleImmediateDispatch(t+1);return}this.immediateDispatch().catch(e=>{this.deps.eventBus.emit({type:"orchestrator:error",error:e instanceof Error?e.message:String(e),context:"immediate dispatch on task:created",fatal:false});});}},500));}async immediateDispatch(){this.shuttingDown||await this.freshDispatch(()=>this.shuttingDown?Promise.resolve():this.dispatchAll());}async reconcile(){let t=this.state,e=Date.now(),s=Object.entries(t.running),a=await Promise.all(s.map(([i])=>this.deps.taskStore.get(i)));for(let i=0;i<s.length;i++){let[h,c]=s[i],m=a[i];if(!m||b(m.status)){this.abortControllers.delete(h),delete t.running[h],await this.deps.agentService.setStatus(c.agent_id,"idle").catch(p=>{this.deps.eventBus.emit({type:"orchestrator:error",error:p instanceof Error?p.message:String(p),context:`reconcile setStatus idle for stale agent ${c.agent_id} (task ${h})`,fatal:false});});continue}if(!this.deps.processManager.isAlive(c.pid)){try{await this._handleRunFailure(h,c,"Process crashed unexpectedly");}catch{delete t.running[h],await this.deps.agentService.setStatus(c.agent_id,"idle").catch(p=>{this.deps.eventBus.emit({type:"orchestrator:error",error:p instanceof Error?p.message:String(p),context:`reconcile crash fallback setStatus idle for agent ${c.agent_id} (task ${h})`,fatal:false});});}continue}let y=new Date(c.last_event_at).getTime(),v=this.deps.config.defaults.agent.stall_timeout_ms;if(e-y>v){this.deps.eventBus.emit({type:"orchestrator:stall_detected",runId:c.run_id}),this.abortControllers.get(h)?.abort(),await this.deps.processManager.killWithGrace(c.pid,5e3);try{await this._handleRunFailure(h,c,"Agent stalled (no events)");}catch{delete t.running[h],await this.deps.agentService.setStatus(c.agent_id,"idle").catch(p=>{this.deps.eventBus.emit({type:"orchestrator:error",error:p instanceof Error?p.message:String(p),context:`reconcile stall fallback setStatus idle for agent ${c.agent_id} (task ${h})`,fatal:false});});}}}let r=new Set(Object.values(t.running).map(i=>i.agent_id)),[d,n]=await Promise.all([this.cachedAgentStore.list(),this.cachedTaskStore.list()]),o=d.filter(i=>i.status==="running"&&!r.has(i.id));o.length>0&&await Promise.all(o.map(i=>this.deps.agentService.setStatus(i.id,"idle")));let g=n.filter(i=>i.status==="in_progress"&&!t.running[i.id]);g.length>0&&await Promise.all(g.map(async i=>{try{await this.deps.taskService.updateStatus(i.id,"failed");}catch{i.status="failed",i.updated_at=new Date().toISOString(),await this.deps.taskStore.save(i).catch(h=>{this.deps.eventBus.emit({type:"orchestrator:error",error:h instanceof Error?h.message:String(h),context:`force-write orphaned task ${i.id}`,fatal:false});});}this.deps.eventBus.emit({type:"task:orphaned",taskId:i.id});}));let u=[];t.retry_queue=t.retry_queue.filter(i=>e>=new Date(i.due_at).getTime()?(u.push(i.task_id),false):true);for(let i of u)await this.dispatchTask(i);await this.saveState();}async seedAutonomousTasks(){let e=(await this.cachedAgentStore.list()).filter(n=>n.autonomous&&n.status==="idle");if(e.length===0)return;let s=await this.cachedTaskStore.list(),a$1=this.cachedGoalStore?await this.cachedGoalStore.list({status:"active"}):[],r=false,d=new Set;for(let n of e){if(s.some(m=>m.assignee===n.id&&!b(m.status)))continue;let g=this.lastAutoSeedAt.get(n.id)??0;if(Date.now()-g<l$1.AUTO_SEED_COOLDOWN_MS)continue;let u=a$1.find(m=>m.assignee===n.id&&!d.has(m.id))??a$1.find(m=>!m.assignee&&!d.has(m.id));u&&d.add(u.id);let i=n.role??"general assistant",h=u?`[auto] ${n.name}: ${u.title.slice(0,60)}`:`[auto] ${n.name}: ${i.slice(0,60)}`,c=u?`## GOAL (highest priority)
7
+
8
+ ${u.description||u.title}
9
+
10
+ ---
11
+ Agent role: ${i}`:`Autonomous work cycle. Agent role: ${i}`;try{await this.deps.taskService.create({title:h,description:c,assignee:n.id,labels:[a],priority:3,goalId:u?.id}),this.lastAutoSeedAt.set(n.id,Date.now()),r=!0;}catch(m){this.deps.eventBus.emit({type:"orchestrator:error",error:m instanceof Error?m.message:String(m),context:`autonomous task for agent ${n.id}`,fatal:false});}}r&&this.cachedTaskStore.invalidate();}async dispatchAll(){let t=this.state,e$1=this.deps.config.scheduling.max_concurrent_agents,s=Object.keys(t.running).length,a=e$1-s;if(a<=0)return;let r=await this.cachedTaskStore.list(),d=new Map(r.map(i=>[i.id,i])),n=r.filter(i=>c(i.status)&&!d$1(i,d)&&!t.running[i.id]&&!t.claimed.has(i.id)).sort((i,h)=>{let c=(i.priority??3)-(h.priority??3);if(c!==0)return c;let m=(i.goalId?0:1)-(h.goalId?0:1);if(m!==0)return m;let y=h.updated_at??"",v=i.updated_at??"";return y<v?-1:y>v?1:0}).slice(0,a),o=new Set,g$1=r.filter(i=>i.status==="in_progress"&&i.scope?.length),u=new x(g$1.map(i=>i.scope));for(let i of n)if(i.scope?.length)if(u.overlapsAny(i.scope)){let h=g$1.find(c=>et(i.scope,c.scope));this.deps.eventBus.emit({type:"task:scope_overlap",taskId:i.id,overlappingTaskId:h?.id??i.id,patterns:i.scope}),o.add(i.id);}else u.add(i.scope);for(let i of n)if(!o.has(i.id))try{await this.dispatchTask(i.id);}catch(h){if(h instanceof l)try{let c=await this.deps.taskStore.get(i.id);if(c&&!b(c.status)){let m={...c,attempts:(c.attempts??0)+1,updated_at:new Date().toISOString()},y=e(m),v={...m,status:y};if(await this.deps.taskStore.save(v),y==="failed"){let p=r.map(f=>f.id===v.id?v:f);this.cachedTaskStore.invalidate(),await this.cascadeFailDependents(v.id,p,`dependency ${v.id} failed: ${h.message}`);}else {let p=g(v.attempts-1,this.deps.config.scheduling.retry_base_delay_ms,this.deps.config.scheduling.retry_max_delay_ms);this.enqueueRetry(t,v.id,v.attempts,p,h.message),await this.saveState();}}}catch{}this.deps.eventBus.emit({type:"orchestrator:error",error:h instanceof Error?h.message:String(h),context:`dispatch task ${i.id}`,fatal:false});}}enqueueRetry(t,e,s,a,r){t.retry_queue.some(d=>d.task_id===e)||(t.retry_queue.length>=this.maxRetryQueueSize&&t.retry_queue.shift(),t.retry_queue.push({task_id:e,attempt:s,due_at:new Date(Date.now()+a).toISOString(),error:r}));}async cascadeFailDependents(t,e,s){let a=new Map;for(let g of e)for(let u of g.depends_on){let i=a.get(u);i||(i=[],a.set(u,i)),i.push(g);}let r=[t],d=0,n=new Set,o=false;for(;d<r.length;){let g=r[d++];if(n.has(g))continue;n.add(g);let u=a.get(g);if(!u)continue;let i=[];for(let c of u)b(c.status)||n.has(c.id)||(i.push({task:c,previousStatus:c.status}),r.push(c.id));if(i.length===0)continue;let h=new Date().toISOString();await Promise.all(i.map(({task:c})=>this.deps.taskStore.save({...c,status:"failed",updated_at:h})));for(let{task:c,previousStatus:m}of i)this.deps.eventBus.emit({type:"task:status_changed",taskId:c.id,from:m,to:"failed"}),this.deps.eventBus.emit({type:"task:cascade_failed",taskId:c.id,failedDependencyId:t,reason:s});o=true;}o&&this.cachedTaskStore.invalidate();}async dispatchTask(t){let e=this.state;if(e.running[t]){let a=e.running[t];throw new h(t,a.run_id,a.agent_id)}let s=await this.deps.taskService.get(t);e.claimed.add(t),await this.saveState();try{let a=await this.cachedAgentStore.list(),r=await this.deps.agentService.findBestAgent(s);if(!r){if(a.length===0)throw new e$1;this.unclaim(t),await this.saveState();return}let{path:d,branch:n}=await this.deps.workspaceManager.prepare(s,r,this.deps.config),o=this.deps.config.prompt?.system_template??d$2,g=this.deps.config.prompt?.user_template??e$2,u=this.deps.config.prompt?.template,i=s.attempts+1,h;if(i>1){let S=await this.deps.runService.getLastFailedRunContext(s.id);S&&(h={previous_error:S.error,previous_output:S.output});}let c=s.goalId,[m,y,v]=await Promise.all([this.deps.contextStore?.getAll(),this.deps.messageService?this.deps.messageService.drainMailbox(r.id,s.id):[],c&&this.cachedGoalStore?this.cachedGoalStore.get(c).catch(()=>null):null]),p;if(v){let lt=(await this.cachedTaskStore.list()).filter(D=>D.goalId===c),dt=await this.deps.contextStore?.get(`${c}-progress`),ut=lt.map(D=>`[${D.status}] ${D.title}`);p={id:v.id,title:v.title,description:v.description,status:v.status,task_names:ut,progress:dt?.value};}let f=c$1(s,r,i,d,this.deps.config,{allAgents:a,retryContext:h,sharedContext:m,feedback:s.feedback,messages:y.length?y:void 0,goal:p}),w,k;if(u?w=await this.deps.templateEngine.render(u,f):(k=await this.deps.templateEngine.render(o,f),w=await this.deps.templateEngine.render(g,f)),this.deps.skillLoader&&r.config.skills?.length){let S=await this.deps.skillLoader.loadSkills(r.config.skills);S&&(k!==void 0?k=k+`
12
+
13
+ `+S:w=w+`
14
+
15
+ `+S);}let E=await this.deps.runService.create({taskId:s.id,agentId:r.id,attempt:i,prompt:w,workspacePath:d});if((s.status==="failed"||s.status==="cancelled")&&(await this.deps.taskService.retry(t),s.status="todo",s.attempts=0),await this.deps.taskService.updateStatus(t,"in_progress"),await this.deps.taskService.assign(t,r.id),await this.deps.taskService.incrementAttempts(t),n){let S=await this.deps.taskStore.get(t);S&&(S.proof={...S.proof??{files_changed:[]},branch:n},S.workspace=d,await this.deps.taskStore.save(S));}await this.deps.agentService.setStatus(r.id,"running");let _=await this.deps.agentService.get(r.id);_.current_task=t,_.last_error=void 0,await this.deps.agentStore.save(_);let ct=this.deps.adapterRegistry.require(r.adapter),I=new AbortController;this.abortControllers.set(t,I);let N=ct.execute({prompt:w,systemPrompt:k,workspace:d,env:{...r.config.env,ORCH_AGENT_ID:r.id,ORCH_AGENT_NAME:r.name,ORCH_TASK_ID:s.id},config:_.config,signal:I.signal}),U=N.pid,W=new Date().toISOString();await this.deps.runService.start(E.id,U),this.unclaim(t),e.running[t]={run_id:E.id,agent_id:r.id,task_id:t,pid:U,started_at:W,last_event_at:W},await this.saveState(),this.collectEvents(N.events,E.id,t,r.id).catch(S=>{this.deps.eventBus.emit({type:"orchestrator:error",error:S instanceof Error?S.message:String(S),context:`adapter execution for ${t}`,fatal:!1});});}catch(a){throw this.abortControllers.delete(t),this.unclaim(t),await this.saveState(),a}}async collectEvents(t,e,s,a){let r,d,n,o,g=new Set;try{for await(let i of t){if(this.shuttingDown)break;if(i.type==="done"){if(i.tokens){let{input:f,output:w,reasoning:k,cache_read:E,cache_write:_}=i.tokens;r=a$1(f,w,{reasoning:k,cache_read:E,cache_write:_});}let p=i.data;p&&typeof p.result=="string"&&(d=p.result);}if(i.type==="output"){let p=i.data;if(p){let f=typeof p.text=="string"?p.text:typeof p.message=="string"?p.message:void 0;f?.trim()&&(n=f);}}if(i.type==="file_change"){let p=i.data;if(p&&Array.isArray(p.paths))for(let f of p.paths)typeof f=="string"&&g.add(f);else {let f=p&&typeof p.path=="string"?p.path:typeof i.data=="string"?i.data:String(i.data);g.add(f);}}let h=Tt(i.timestamp)?i.timestamp:new Date().toISOString(),c=i.type==="file_change"?(()=>{let p=i.data;return p&&typeof p.path=="string"?p.path:typeof i.data=="string"?i.data:String(i.data)})():null,m=ot(i.data,kt);i.data=void 0;let y={timestamp:h,type:i.type==="output"?"agent_output":i.type==="file_change"?"file_changed":i.type==="command"?"command_run":i.type==="tool_call"?"tool_call":i.type==="error"?"error":"done",data:m};await this.deps.runService.appendEvent(e,y),this.state?.running[s]&&(this.state.running[s].last_event_at=h,this.saveStateLazy());let v=ot(m,_t);i.type==="output"||i.type==="tool_call"?this.deps.eventBus.emit({type:"agent:output",runId:e,agentId:a,data:v}):i.type==="file_change"?this.deps.eventBus.emit({type:"agent:file_changed",runId:e,agentId:a,path:c}):i.type==="error"&&(i.errorKind&&(o=i.errorKind),this.deps.eventBus.emit({type:"agent:error",runId:e,agentId:a,error:v,...i.errorKind?{errorKind:i.errorKind}:{}}));}let u=d??n;await this.handleRunSuccess(s,e,a,r,u,[...g]);}catch(u){let i=u instanceof Error?u.message:String(u),h=o??(u instanceof Error?u.errorKind:void 0),c=this.state?.running[s];c&&await this.handleRunFailure(s,c,i,h);}finally{this.deps.runStore.closeRunEvents(e);}}async handleRunSuccess(t,e,s,a,r,d){return this.withStateLock(()=>this._handleRunSuccess(t,e,s,a,r,d))}async _handleRunSuccess(t,e,s,a$1,r,d){await this.flushStateLazy(),this.abortControllers.delete(t);let n=this.state;if(!n.running[t])return;let o=await this.deps.taskStore.get(t);if(!o)return;let g=d;(!g||g.length===0)&&o.proof?.branch&&(g=await this.deps.workspaceManager.getChangedFiles(o.proof.branch)),o.proof={...o.proof,agent_summary:r?.slice(0,2e3)??o.proof?.agent_summary,files_changed:g?.length?g:o.proof?.files_changed??[]},delete o.feedback,await this.deps.taskStore.save(o);let u=await this.deps.agentStore.get(s),h=o.labels?.includes(a)||u?.config.approval_policy==="auto",c=f(o,true,h);await this.deps.runService.finish(e,"succeeded",a$1);let m=n.running[t],y=m?Date.now()-new Date(m.started_at).getTime():0;m&&(n.stats.total_runtime_ms+=y),delete n.running[t];let v={tasks_completed:(u?.stats.tasks_completed??0)+1,total_runs:(u?.stats.total_runs??0)+1,total_runtime_ms:(u?.stats.total_runtime_ms??0)+y};if(a$1&&(v.tokens_used=(u?.stats.tokens_used??0)+a$1.total),await this.deps.agentService.updateStats(s,v).catch(f=>{this.deps.eventBus.emit({type:"orchestrator:error",error:f instanceof Error?f.message:String(f),context:`agent stats update for ${s}`,fatal:false});}),n.stats.total_tasks_completed++,n.stats.total_runs++,a$1&&(n.stats.total_tokens.input+=a$1.input,n.stats.total_tokens.output+=a$1.output,n.stats.total_tokens.reasoning+=a$1.reasoning,n.stats.total_tokens.cache_read+=a$1.cache_read,n.stats.total_tokens.cache_write+=a$1.cache_write,n.stats.total_tokens.total=n.stats.total_tokens.input+n.stats.total_tokens.output+n.stats.total_tokens.reasoning),o.proof?.branch)try{let f=await this.deps.workspaceManager.mergeBack(o.proof.branch);if(f.success)this.deps.eventBus.emit({type:"workspace:merge_succeeded",taskId:t,branch:o.proof.branch}),await this.deps.workspaceManager.cleanup(t,o.proof.branch).catch(w=>{this.deps.eventBus.emit({type:"orchestrator:error",error:w instanceof Error?w.message:String(w),context:`workspace cleanup for ${t}`,fatal:!1});});else {this.deps.eventBus.emit({type:"workspace:merge_conflict",taskId:t,branch:o.proof.branch,conflictInfo:f.conflictInfo}),await this.forceTaskToReview(o,s,`MERGE CONFLICT: ${f.conflictInfo}`);return}}catch(f){let w=f instanceof Error?f.message:String(f);await this.forceTaskToReview(o,s,`MERGE ERROR: ${w}`);return}try{await this.deps.taskService.updateStatus(t,c);}catch(f){let w=f instanceof Error?f.message:String(f);this.deps.eventBus.emit({type:"orchestrator:error",error:w,context:`state machine validation failed for task ${t} -> ${c}, force-writing`,fatal:false}),o.status=c,o.updated_at=new Date().toISOString(),await this.deps.taskStore.save(o).catch(k=>{this.deps.eventBus.emit({type:"orchestrator:error",error:k instanceof Error?k.message:String(k),context:`force-write task ${t} to store failed`,fatal:false});});}await this.deps.agentService.setStatus(s,"idle").catch(f=>{this.deps.eventBus.emit({type:"orchestrator:error",error:f instanceof Error?f.message:String(f),context:`_handleRunSuccess setStatus idle for agent ${s}`,fatal:false});});let p=await this.deps.agentStore.get(s);p&&(p.current_task=void 0,await this.deps.agentStore.save(p)),c==="review"&&o.review_criteria?.length?await this.runAutoReview(t,o.review_criteria,o.workspace??this.deps.projectRoot,h):c==="review"&&h&&await this.deps.taskService.updateStatus(t,"done"),await this.saveState(),this.scheduleImmediateDispatch();}async handleRunFailure(t,e,s,a){return this.withStateLock(()=>this._handleRunFailure(t,e,s,a))}async _handleRunFailure(t,e$1,s,a){await this.flushStateLazy(),this.abortControllers.delete(t);let r=this.state,d=await this.deps.taskStore.get(t);if(!d)return;await this.deps.runService.finish(e$1.run_id,"failed",void 0,s),await this.deps.agentService.setStatus(e$1.agent_id,"idle");let n$1=await this.deps.agentStore.get(e$1.agent_id);n$1&&(n$1.current_task=void 0,n$1.last_error={message:s.slice(0,500),kind:a??n(s),timestamp:new Date().toISOString()},await this.deps.agentStore.save(n$1));let o=Date.now()-new Date(e$1.started_at).getTime();await this.deps.agentService.updateStats(e$1.agent_id,{tasks_failed:(n$1?.stats.tasks_failed??0)+1,total_runs:(n$1?.stats.total_runs??0)+1,total_runtime_ms:(n$1?.stats.total_runtime_ms??0)+o});let g$1=e(d);if(await this.deps.taskService.updateStatus(t,g$1),g$1==="retrying"){let u=g(d.attempts-1,this.deps.config.scheduling.retry_base_delay_ms,this.deps.config.scheduling.retry_max_delay_ms);this.enqueueRetry(r,t,d.attempts+1,u,s),this.deps.eventBus.emit({type:"run:retry",runId:e$1.run_id,attempt:d.attempts+1,delay_ms:u});}else {r.stats.total_tasks_failed++,this.cachedTaskStore.invalidate();let u=await this.cachedTaskStore.list();await this.cascadeFailDependents(t,u,`dependency ${t} failed: ${s}`);}r.stats.total_runtime_ms+=o,d.proof?.branch&&await this.deps.workspaceManager.cleanup(t,d.proof.branch).catch(u=>{this.deps.eventBus.emit({type:"orchestrator:error",error:u instanceof Error?u.message:String(u),context:`workspace cleanup for ${t}`,fatal:false});}),delete r.running[t],r.stats.total_runs++,await this.saveState(),this.scheduleImmediateDispatch();}async runAutoReview(t,e,s,a=false){let d=await new R({cwd:s}).runAll(e),n=R.allPassed(d),o=await this.deps.taskStore.get(t);if(o&&(o.review_results=d,o.proof={...o.proof,test_results:R.formatReport(d),files_changed:o.proof?.files_changed??[]},await this.deps.taskStore.save(o),this.deps.eventBus.emit({type:"task:auto_reviewed",taskId:t,passed:n,results:d}),n||a)){n||this.deps.eventBus.emit({type:"orchestrator:error",error:`Review criteria failed for task ${t} but autoApprove is set \u2014 force-approving`,context:"auto-review-with-auto-approve",fatal:false});try{await this.deps.taskService.updateStatus(t,"done");}catch(g){let u=g instanceof Error?g.message:String(g);this.deps.eventBus.emit({type:"orchestrator:error",error:u,context:`auto-review transition failed for task ${t} -> done, force-writing`,fatal:false}),o.status="done",o.updated_at=new Date().toISOString(),await this.deps.taskStore.save(o).catch(i=>{this.deps.eventBus.emit({type:"orchestrator:error",error:i instanceof Error?i.message:String(i),context:`force-write task ${t} to store failed (auto-review)`,fatal:false});});}}}async forceTaskToReview(t,e,s){t.proof={...t.proof,agent_summary:`${s}
16
+
17
+ ${t.proof?.agent_summary??""}`.slice(0,2e3),files_changed:t.proof?.files_changed??[]},t.status="review",t.updated_at=new Date().toISOString(),await this.deps.taskStore.save(t),await this.deps.agentService.setStatus(e,"idle").catch(r=>{this.deps.eventBus.emit({type:"orchestrator:error",error:r instanceof Error?r.message:String(r),context:`forceTaskToReview setStatus idle for agent ${e}`,fatal:false});});let a=await this.deps.agentStore.get(e);a&&(a.current_task=void 0,await this.deps.agentStore.save(a)),await this.saveState();}unclaim(t){this.state.claimed.delete(t);}requireOwnership(){if(!this.lockAcquired)throw new d(0)}async loadState(){this.state=await this.deps.stateStore.read();}async cleanupStaleRunningEntries(){let t=this.state,e=Object.entries(t.running).filter(([,a])=>!this.deps.processManager.isAlive(a.pid)),s=new Set;if(e.length>0){for(let[a]of e)delete t.running[a],s.add(a);await Promise.all(e.map(async([a,r])=>{await this.deps.agentService.setStatus(r.agent_id,"idle").catch(d=>{this.deps.eventBus.emit({type:"orchestrator:error",error:d instanceof Error?d.message:String(d),context:`startup cleanup: setStatus idle for agent ${r.agent_id}`,fatal:false});}),await this.forceTaskCancelled(a),await this.deps.runService.finish(r.run_id,"cancelled",void 0,"Orchestrator restarted").catch(d=>{this.deps.eventBus.emit({type:"orchestrator:error",error:d instanceof Error?d.message:String(d),context:`startup cleanup: finish run ${r.run_id}`,fatal:false});});}));}if(t.claimed=new Set,s.size>0){let r=(await this.cachedTaskStore.list()).filter(n=>n.status==="in_progress"&&!t.running[n.id]);r.length>0&&await Promise.all(r.map(n=>this.forceTaskCancelled(n.id)));let d=new Set([...s,...r.map(n=>n.id)]);t.retry_queue=t.retry_queue.filter(n=>!d.has(n.task_id)),await this.saveState();}}async forceTaskCancelled(t){try{await this.deps.taskService.updateStatus(t,"cancelled");}catch{let e=await this.deps.taskStore.get(t);e&&!b(e.status)&&(e.status="cancelled",e.updated_at=new Date().toISOString(),await this.deps.taskStore.save(e).catch(s=>{this.deps.eventBus.emit({type:"orchestrator:error",error:s instanceof Error?s.message:String(s),context:`startup cleanup: force-cancel task ${t}`,fatal:false});}));}}async saveState(){this.state&&await this.deps.stateStore.write(this.state);}saveStateLazy(){this.saveStateDirty=true,!this.saveStateTimer&&(this.saveStateTimer=setTimeout(()=>{this.saveStateTimer=null,this.saveStateDirty&&(this.saveStateDirty=false,this.saveState().catch(t=>{this.deps.eventBus.emit({type:"orchestrator:error",error:t instanceof Error?t.message:String(t),context:"debounced state save",fatal:false});}));},500));}async flushStateLazy(){this.saveStateTimer&&(clearTimeout(this.saveStateTimer),this.saveStateTimer=null),this.saveStateDirty&&(this.saveStateDirty=false,await this.saveState());}};function Tt(l){if(typeof l!="string")return false;let t=new Date(l);return !isNaN(t.getTime())&&t.toISOString()===l}function ot(l,t){let e=typeof l=="string"?l:JSON.stringify(l);return e.length>t?e.slice(0,t)+"\u2026":e}export{nt as Orchestrator};
@@ -17,4 +17,4 @@ import {j,q,g,d,e,o,l,n,m}from'./chunk-64WUDYEM.js';function x(_,a){let c=_.comm
17
17
  Review Results
18
18
  ${"\u2500".repeat(42)}`);for(let o of t.review_results){let n=o.passed?"\u2713":"\u2717";if(console.log(` ${n} ${o.criterion}: ${o.passed?"passed":"failed"}`),o.output)for(let l of o.output.split(`
19
19
  `))console.log(` ${l}`);}}console.log();}),c.command("edit <id>").description("Open task in $EDITOR to modify title, priority and description").action(async e=>{let t=await a.taskService.get(e),{openInEditor:i,toEditorContent:o,fromEditorContent:n}=await import('./editor-7IFRWVTL.js'),l=t.attachments?.length?`
20
- # Attachments: ${t.attachments.join(", ")}`:"",d=o({title:t.title,priority:t.priority,description:t.description})+l,s=await i(d),r=n(s),g={};if(r.title&&r.title!==t.title&&(g.title=r.title),r.priority&&r.priority!==t.priority&&(g.priority=r.priority),r.description!==void 0&&r.description!==t.description&&(g.description=r.description??""),Object.keys(g).length===0){console.log(" No changes.");return}let w=await a.taskService.update(e,g);j(`Updated ${w.id} "${w.title}"`);}),c.command("assign <task-id> <agent-id>").description("Assign task to agent").action(async(e,t)=>{let i=await a.taskService.assign(e,t);j(`Assigned ${i.id} \u2192 ${t}`);}),c.command("cancel <id>").description("Cancel a task").action(async e=>{if((await a.taskService.get(e)).status==="in_progress"){let{buildFullContainer:i}=await import('./container-NS3YS47A.js');await(await i(a.context)).orchestrator.cancelTask(e);}else await a.taskService.cancel(e);j(`Cancelled ${e}`);}),c.command("approve <id>").description("Approve a task in review").action(async e=>{await a.taskService.updateStatus(e,"done"),j(`Approved ${e}`);}),c.command("reject <id>").description("Reject a task and send it back for rework").option("-r, --reason <reason>","Feedback for the agent explaining what to fix").action(async(e,t)=>{await a.taskService.reject(e,t.reason),j(`Rejected ${e} \u2192 todo${t.reason?` (reason: ${t.reason})`:""}`);}),c.command("retry <id>").description("Retry a failed task").action(async e=>{await a.taskService.retry(e),j(`Reset ${e} to todo`);});}export{x as registerTaskCommand};
20
+ # Attachments: ${t.attachments.join(", ")}`:"",d=o({title:t.title,priority:t.priority,description:t.description})+l,s=await i(d),r=n(s),g={};if(r.title&&r.title!==t.title&&(g.title=r.title),r.priority&&r.priority!==t.priority&&(g.priority=r.priority),r.description!==void 0&&r.description!==t.description&&(g.description=r.description??""),Object.keys(g).length===0){console.log(" No changes.");return}let w=await a.taskService.update(e,g);j(`Updated ${w.id} "${w.title}"`);}),c.command("assign <task-id> <agent-id>").description("Assign task to agent").action(async(e,t)=>{let i=await a.taskService.assign(e,t);j(`Assigned ${i.id} \u2192 ${t}`);}),c.command("cancel <id>").description("Cancel a task").action(async e=>{if((await a.taskService.get(e)).status==="in_progress"){let{buildFullContainer:i}=await import('./container-DUCZ7DUL.js');await(await i(a.context)).orchestrator.cancelTask(e);}else await a.taskService.cancel(e);j(`Cancelled ${e}`);}),c.command("approve <id>").description("Approve a task in review").action(async e=>{await a.taskService.updateStatus(e,"done"),j(`Approved ${e}`);}),c.command("reject <id>").description("Reject a task and send it back for rework").option("-r, --reason <reason>","Feedback for the agent explaining what to fix").action(async(e,t)=>{await a.taskService.reject(e,t.reason),j(`Rejected ${e} \u2192 todo${t.reason?` (reason: ${t.reason})`:""}`);}),c.command("retry <id>").description("Retry a failed task").action(async e=>{await a.taskService.retry(e),j(`Reset ${e} to todo`);});}export{x as registerTaskCommand};
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ function ct(d,e){d.command("tui").description("Launch interactive TUI dashboard").action(async()=>{let S=await e.taskService.list(),w=await e.agentService.list(),h=await e.stateStore.read(),{render:k}=await import('ink'),{createElement:T}=await import('react'),{App:b}=await import('./App-BMY7F63C.js'),A=async t=>{await e.orchestrator.runTask(t);},R=async(t,s)=>e.taskService.create({title:t,priority:s?.priority,description:s?.description,attachments:s?.attachments}),C=async t=>{await e.orchestrator.cancelTask(t);},_=async t=>{await e.taskService.retry(t);},E=async(t,s)=>{await e.taskService.assign(t,s);},j=async()=>{await e.orchestrator.runAll();},D=async t=>{await e.agentService.disable(t);},U=async t=>{await e.agentService.enable(t);},m=t=>e.eventBus.onAny(t),P=async()=>e.taskService.list(),G=async()=>e.agentService.list(),x=async()=>e.stateStore.read(),I=async(t,s,n)=>e.agentService.create({name:t,adapter:s??"claude",model:n?.model||void 0,effort:n?.effort||void 0,role:n?.role||void 0,approval_policy:n?.approval_policy||void 0,skills:n?.skills||void 0}),L=async t=>{await e.agentService.remove(t);},F=async t=>{await e.taskService.delete(t);},H=async t=>{await e.taskService.updateStatus(t,"done");},O=async(t,s)=>{await e.taskService.reject(t,s);},W=async(t,s)=>e.taskService.update(t,s),N=async(t,s)=>e.agentService.update(t,{...s,effort:s.effort,approval_policy:s.approval_policy}),B=async t=>{await e.orchestrator.forceStopAgent(t);},M=async(t,s)=>e.agentService.setAutonomous(t,s),V=async t=>{let s=await e.runService.listAll();s.sort((a,i)=>new Date(i.started_at).getTime()-new Date(a.started_at).getTime());let n=s.filter(a=>a.status==="succeeded"||a.status==="failed"),u=3,ot=10,y=n.slice(0,u),v=n.slice(u,ot),f=async a=>(await e.runService.readEventsTail(a.id,30)).map(r=>({timestamp:r.timestamp,agentId:a.agent_id,taskId:a.task_id,type:r.type,data:r.data}));if(y.length>0){let a=(await Promise.all(y.map(f))).flat();a.sort((i,r)=>new Date(i.timestamp).getTime()-new Date(r.timestamp).getTime()),t(a.slice(-200));}if(v.length>0){let a=(await Promise.all(v.map(f))).flat();a.sort((i,r)=>new Date(i.timestamp).getTime()-new Date(r.timestamp).getTime()),t(a.slice(-200));}},J=async t=>e.teamService.create(t),K=async()=>e.teamService.list(),q=async(t,s)=>e.teamService.join(t,s),z=async(t,s)=>e.teamService.leave(t,s),Q=async t=>{await e.teamService.disband(t);},X=async(t,s)=>e.teamService.setLead(t,s),Y=async()=>e.goalService.list(),Z=async t=>e.goalService.create(t),$=async(t,s)=>e.goalService.update(t,s),tt=async(t,s)=>e.goalService.updateStatus(t,s),et=async t=>{await e.goalService.delete(t);},st=async t=>e.goalService.getProgressReport(t),at=async()=>{await e.orchestrator.startWatch();},nt=async()=>{await e.orchestrator.stop();},c=d.version()??"0.0.0",rt=import('./update-check-R5ABF6HE.js').then(t=>t.checkForUpdateSWR(c)).catch(()=>null),l=false,p,g=false,o;try{await e.orchestrator.startWatch(),l=!0;}catch(t){p=t instanceof Error?t.message:String(t);let{DiskObserver:s}=await import('./disk-observer-B3NOZ2QA.js');o=new s({paths:e.paths,stateStore:e.stateStore}),g=true,m=n=>o.subscribe(n);}let{waitUntilExit:it}=k(T(b,{projectName:e.config.project.name,tasks:S,agents:w,state:h,onRunTask:A,onCreateTask:R,onCancelTask:C,onRetryTask:_,onAssignTask:E,onRunAll:j,onDisableAgent:D,onEnableAgent:U,onSubscribeEvents:m,onRefreshTasks:P,onRefreshAgents:G,onRefreshState:x,onLoadHistory:V,onAddAgent:I,onDeleteAgent:L,onApproveTask:H,onRejectTask:O,onDeleteTask:F,onUpdateTask:W,onUpdateAgent:N,onForceStopAgent:B,onToggleAutonomous:M,onRefreshGoals:Y,onCreateGoal:Z,onUpdateGoal:$,onUpdateGoalStatus:tt,onDeleteGoal:et,onGetGoalProgress:st,onCreateTeam:J,onListTeams:K,onJoinTeam:q,onLeaveTeam:z,onDisbandTeam:Q,onSetTeamLead:X,onStartWatch:at,onStopWatch:nt,initialWatchActive:l,observerMode:g,watchError:g?void 0:p,version:c,latestVersion:void 0,onCheckUpdate:async()=>{let t=await rt;if(t?.updateAvailable)return t.latest;let n=await(await import('./update-check-R5ABF6HE.js')).checkForUpdateNow(c);return n?.updateAvailable?n.latest:void 0},onBackgroundInstall:async t=>(await import('./update-check-R5ABF6HE.js')).backgroundInstall(t),initialActivityFilter:e.globalConfig.tui.activity_filter,onSaveActivityFilter:async t=>{await e.globalConfigStore.set("activity_filter",t);},initialNotifications:e.globalConfig.tui.notifications,onSaveNotifications:async t=>{await e.globalConfigStore.set("notifications",t);},initialMaxConcurrent:e.config.scheduling.max_concurrent_agents,onSaveMaxConcurrent:async t=>{await e.configStore.set("scheduling.max_concurrent_agents",t),e.config.scheduling.max_concurrent_agents=t;},onCompleteOnboarding:async()=>{let t=await e.stateStore.read();t.onboardingCompleted=true,await e.stateStore.write(t);}}),{kittyKeyboard:{mode:"auto",flags:["disambiguateEscapeCodes"]}});await it(),l&&await e.orchestrator.stop().catch(()=>{}),o&&o.stop(),e.eventBus.clear();});}export{ct as registerTuiCommand};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxgeneral/orch",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "description": "AI agent runtime — orchestrate Claude, Cursor, Codex & OpenCode as one team. Multi-agent task automation with state machine, auto-retry, inter-agent messaging, goals and teams. Zero-config CLI + programmatic API.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -83,6 +83,7 @@ orch agent add "<name>" --adapter <type> [options]
83
83
  --adapter <type> # REQUIRED: claude|opencode|codex|cursor|shell
84
84
  --role <description> # Agent role/expertise
85
85
  --model <model> # Model name
86
+ --effort <level> # Reasoning effort: low, medium, high (Claude only)
86
87
  --command <cmd> # Shell command (for shell adapter)
87
88
  --max-turns <n> # Max turns per run
88
89
  --timeout <ms> # Timeout in milliseconds
@@ -245,6 +246,44 @@ orch logs [run-id] # View run logs
245
246
  - **All state** stored in `.orchestry/` (YAML/JSON, no database)
246
247
  - **IDs** are prefixed: `tsk_`, `agt_`, `run_`, `goal_`, `team_`, `msg_`
247
248
 
249
+ ## When to Use Goals vs Tasks
250
+
251
+ ### Use a Task when:
252
+ - You know **exactly what needs to be done** — one concrete action
253
+ - The scope is clear: fix a bug, write a test, update a file, review a PR
254
+ - You can describe the result in one sentence
255
+ - Examples: "Fix login crash on empty email", "Add unit tests for auth service", "Update README badges"
256
+
257
+ ```bash
258
+ orch task add "Fix login crash" -d "Empty email causes TypeError in validate()" --scope "src/auth/**" -p 1
259
+ ```
260
+
261
+ ### Use a Goal when:
262
+ - The objective is **high-level and needs decomposition** — you don't know all the steps upfront
263
+ - Multiple tasks will be needed, potentially across different agents/skills
264
+ - You want an agent to **autonomously plan and execute** the work
265
+ - Examples: "Implement OAuth2", "Migrate from REST to GraphQL", "Improve test coverage to 80%"
266
+
267
+ ```bash
268
+ orch goal add "Implement OAuth2 with Google and GitHub" --description "Support social login, add tests, update docs" --assignee <lead-agent>
269
+ ```
270
+
271
+ The assigned agent enters **autonomous mode**: it analyzes the codebase, creates tasks, assigns them to appropriate agents, and monitors progress until the goal is achieved.
272
+
273
+ ### Use a Goal for iterative improvement:
274
+ - You have a **measurable metric** and want the agent to keep working until it's met
275
+ - The agent runs cycles: measure → fix → measure again → repeat
276
+ - Examples: "Get test coverage to 80%", "Zero TypeScript errors", "All /simplify reviews clean"
277
+
278
+ ```bash
279
+ orch goal add "Reach 80% test coverage" --description "Run coverage, find gaps, write tests, repeat until ≥80%" --assignee <qa-agent>
280
+ ```
281
+
282
+ ### Rule of thumb
283
+ - **1 agent, 1 action** → Task
284
+ - **Multiple agents, unclear steps** → Goal
285
+ - **Iterative loop until metric is met** → Goal
286
+
248
287
  ## Configuration Reference
249
288
 
250
289
  ```yaml
@@ -404,6 +443,7 @@ Handled natively by Claude CLI. Use `package:skill-name` format (with colon):
404
443
  - Use `claude-sonnet-4-6` for execution roles (developer, QA, writer) — faster, cheaper
405
444
  - Set `--approval-policy suggest` for strategic agents so humans review decisions
406
445
  - Set `--approval-policy auto` for execution agents for fully autonomous operation
446
+ - Use `--effort low|medium|high` to control reasoning depth (Claude only) — `low` for simple tasks, `medium` for balanced, `high` for complex reasoning
407
447
  - Use `--workspace-mode shared` for analysis/strategy agents (they read, don't write code)
408
448
  - Use `--workspace-mode worktree` for coding agents (isolated branches, no conflicts)
409
449