@oxgeneral/orch 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{App-A5TZETZ2.js → App-SSYYVFGW.js} +8 -7
- package/dist/{chunk-FDSFFFMT.js → chunk-UTDC3OB3.js} +68 -4
- package/dist/chunk-UTDC3OB3.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{container-CFMUT5KS.js → container-FUHRQOV4.js} +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +3 -3
- package/dist/once-runner-UCMXCY6C.js +2 -0
- package/dist/orchestrator-64BHTD42.js +6 -0
- package/dist/{orchestrator-6XH2TY3T.js.map → orchestrator-64BHTD42.js.map} +1 -1
- package/dist/orchestrator-KEH7RQAV.js +13 -0
- package/dist/serve-3DV74ZSO.js +3 -0
- package/dist/structured-logger-EXMGTUDB.js +4 -0
- package/dist/{task-JUS5OZJR.js → task-M2JGNUYW.js} +1 -1
- package/dist/tui-4VRDSRVB.js +2 -0
- package/package.json +1 -1
- package/readme.md +417 -97
- package/dist/chunk-FDSFFFMT.js.map +0 -1
- package/dist/orchestrator-6XH2TY3T.js +0 -6
- package/dist/orchestrator-DRITPUWT.js +0 -13
- package/dist/tui-R6LXKKSH.js +0 -2
package/dist/index.d.ts
CHANGED
|
@@ -1090,6 +1090,8 @@ declare class Orchestrator {
|
|
|
1090
1090
|
private immediateDispatchTimer;
|
|
1091
1091
|
private taskCreatedUnsub;
|
|
1092
1092
|
private tickInProgress;
|
|
1093
|
+
/** When true, `tick()` skips `seedAutonomousTasks()`. Set via `startWatch()` options. */
|
|
1094
|
+
private skipAutonomousSeeding;
|
|
1093
1095
|
/** Promise-chain mutex to serialize critical state mutations. */
|
|
1094
1096
|
private stateMutex;
|
|
1095
1097
|
constructor(deps: OrchestratorDeps);
|
|
@@ -1128,7 +1130,9 @@ declare class Orchestrator {
|
|
|
1128
1130
|
* Start watch mode — continuous tick loop.
|
|
1129
1131
|
* Acquires a PID lock to prevent multiple orchestrators.
|
|
1130
1132
|
*/
|
|
1131
|
-
startWatch(
|
|
1133
|
+
startWatch(opts?: {
|
|
1134
|
+
skipAutonomousSeeding?: boolean;
|
|
1135
|
+
}): Promise<void>;
|
|
1132
1136
|
/**
|
|
1133
1137
|
* Register SIGINT/SIGTERM handlers for graceful shutdown.
|
|
1134
1138
|
*/
|
|
@@ -1211,6 +1215,16 @@ declare class Orchestrator {
|
|
|
1211
1215
|
*/
|
|
1212
1216
|
private requireOwnership;
|
|
1213
1217
|
private loadState;
|
|
1218
|
+
/**
|
|
1219
|
+
* On startup, clean up stale running entries left by a crashed/restarted process.
|
|
1220
|
+
*
|
|
1221
|
+
* Instead of marking orphaned tasks as 'failed' (which triggers retry → agents
|
|
1222
|
+
* redo already-committed work), we cancel them. Users can manually reactivate
|
|
1223
|
+
* specific tasks if needed.
|
|
1224
|
+
*/
|
|
1225
|
+
private cleanupStaleRunningEntries;
|
|
1226
|
+
/** Cancel a task, falling back to direct store write if transition is invalid. */
|
|
1227
|
+
private forceTaskCancelled;
|
|
1214
1228
|
private saveState;
|
|
1215
1229
|
/**
|
|
1216
1230
|
* Debounced saveState — batches rapid writes within 500ms window.
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ensureDir, Paths, readYaml, writeYaml, readJson, writeJson, listFiles, appendJsonl, readJsonl, readJsonlTail, pathExists } from './chunk-BSJVYRI3.js';
|
|
2
|
-
import { canTransition, isTerminal } from './chunk-
|
|
3
|
-
export { Orchestrator, canTransition, isBlocked, isDispatchable, isTerminal, resolveFailureStatus } from './chunk-
|
|
2
|
+
import { canTransition, isTerminal } from './chunk-UTDC3OB3.js';
|
|
3
|
+
export { Orchestrator, canTransition, isBlocked, isDispatchable, isTerminal, resolveFailureStatus } from './chunk-UTDC3OB3.js';
|
|
4
4
|
import { AUTONOMOUS_LABEL } from './chunk-VG4465AG.js';
|
|
5
5
|
export { AdapterRegistry } from './chunk-6DWHQPTE.js';
|
|
6
6
|
export { createTokenUsage } from './chunk-RHFRHCN5.js';
|
|
@@ -1945,7 +1945,7 @@ async function buildFullContainer(context) {
|
|
|
1945
1945
|
import('./opencode-ULT6DYCT.js'),
|
|
1946
1946
|
import('./workspace-manager-ABXFBL2A.js'),
|
|
1947
1947
|
import('./template-engine-5ZKVJMYA.js'),
|
|
1948
|
-
import('./orchestrator-
|
|
1948
|
+
import('./orchestrator-64BHTD42.js'),
|
|
1949
1949
|
import('./doctor-service-F2SXDWHS.js')
|
|
1950
1950
|
]);
|
|
1951
1951
|
const processManager = new ProcessManager();
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {b}from'./chunk-LXNRCJ22.js';async function p(a,r,s,t=2e3){await a.startWatch({skipAutonomousSeeding:true});let e=false,n=s.on("orchestrator:shutdown",()=>{e=true;});try{let i=await l(r,t,()=>e);return await a.stop(),i.some(u=>u.status==="failed")?"has_failed":"all_done"}finally{n();}}async function l(a,r,s){for(;;){let t=await a.list();if(t.length===0||t.every(e=>b(e.status))||s())return t;await new Promise(e=>{setTimeout(e,r);});}}export{p as runOnce};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"orchestrator-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"orchestrator-64BHTD42.js"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {d as d$2,e as e$2,c as c$1}from'./chunk-4MMHVHA6.js';import {e,c,b,d as d$1,f,g}from'./chunk-LXNRCJ22.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 b$1 from'fs/promises';import {execFile}from'child_process';function et(u,t){if(!u?.length||!t?.length)return false;for(let e of u)for(let s of t)if(ut(e,s))return true;return false}function L(u){let t=u.split("*")[0],e=!t.endsWith("/"),s=e?dirname(t):"";return {raw:u,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(L(s));}overlapsAny(t){if(!t?.length||this.entries.length===0)return false;for(let e of t){let s=L(e);for(let a of this.entries)if(dt(s,a))return true}return false}add(t){if(t?.length)for(let e of t)this.entries.push(L(e));}get size(){return this.entries.length}};function dt(u,t){return u.raw===t.raw||u.base.startsWith(t.base)||t.base.startsWith(u.base)?true:u.isFile&&t.isFile?u.dir===t.dir&&u.dir!==".":false}function ut(u,t){if(u===t)return true;let e=u.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 q(u){let t,e=new Promise(a=>{t=a;}),s=st;st=e,await s;try{return await ht(u)}finally{t();}}async function ht(u){let t=await it(u);if(t!==null){if(pt(t))return {acquired:false,pid:t};await b$1.unlink(u).catch(()=>{});}try{let e=await b$1.open(u,"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(u)??void 0};throw e}}async function G(u){await b$1.unlink(u).catch(()=>{});}async function it(u){try{let t=await b$1.readFile(u,"utf-8"),e=parseInt(t.trim(),10);return isNaN(e)?null:e}catch{return null}}function pt(u){try{return process.kill(u,0),!0}catch(t){return t.code==="EPERM"}}var D=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();}},C=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 gt={test_pass:{cmd:"npm",args:["test"]},typecheck:{cmd:"npx",args:["tsc","--noEmit"]},lint:{cmd:"npm",args:["run","lint"]}},_=class{cwd;timeoutMs;constructor(t){this.cwd=t.cwd,this.timeoutMs=t.timeout_ms??12e4;}async runAll(t){let e=[];for(let s of t){let a=await this.runCriterion(s);e.push(a);}return e}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.slice(0,500);return `${a} ${s.criterion}: ${s.passed?"PASSED":"FAILED"}
|
|
3
|
+
${r}`}).join(`
|
|
4
|
+
|
|
5
|
+
`)}runCriterion(t){let{cmd:e,args:s}=gt[t];return new Promise(a=>{execFile(e,s,{cwd:this.cwd,timeout:this.timeoutMs,maxBuffer:1024*1024},(r,d,n)=>{let l=(d+`
|
|
6
|
+
`+n).trim();a({criterion:t,passed:!r,output:l.slice(0,2e3)});});})}};var mt=8192,vt=4096,at=class{constructor(t){this.deps=t;this.cachedTaskStore=new D(t.taskStore),this.cachedAgentStore=new C(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;skipAutonomousSeeding=false;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 q(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 q(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);}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(){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());}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});});}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],S=a[i];if(!S||b(S.status)){this.abortControllers.delete(h),delete t.running[h],await this.deps.agentService.setStatus(c.agent_id,"idle").catch(o=>{this.deps.eventBus.emit({type:"orchestrator:error",error:o instanceof Error?o.message:String(o),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(o=>{this.deps.eventBus.emit({type:"orchestrator:error",error:o instanceof Error?o.message:String(o),context:`reconcile crash fallback setStatus idle for agent ${c.agent_id} (task ${h})`,fatal:false});});}continue}let w=new Date(c.last_event_at).getTime(),m=this.deps.config.defaults.agent.stall_timeout_ms;if(e-w>m){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(o=>{this.deps.eventBus.emit({type:"orchestrator:error",error:o instanceof Error?o.message:String(o),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()]),l=d.filter(i=>i.status==="running"&&!r.has(i.id));l.length>0&&await Promise.all(l.map(i=>this.deps.agentService.setStatus(i.id,"idle")));let p=n.filter(i=>i.status==="in_progress"&&!t.running[i.id]);p.length>0&&await Promise.all(p.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 f=[];t.retry_queue=t.retry_queue.filter(i=>e>=new Date(i.due_at).getTime()?(f.push(i.task_id),false):true);for(let i of f)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(c=>c.assignee===n.id&&!b(c.status)))continue;let p=a$1.find(c=>c.assignee===n.id&&!d.has(c.id))??a$1.find(c=>!c.assignee&&!d.has(c.id));p&&d.add(p.id);let f=n.role??"general assistant",i=p?`[auto] ${n.name}: ${p.title.slice(0,60)}`:`[auto] ${n.name}: ${f.slice(0,60)}`,h=p?`## GOAL (highest priority)
|
|
7
|
+
|
|
8
|
+
${p.description||p.title}
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
Agent role: ${f}`:`Autonomous work cycle. Agent role: ${f}`;try{await this.deps.taskService.create({title:i,description:h,assignee:n.id,labels:[a],priority:3,goalId:p?.id}),r=!0;}catch(c){this.deps.eventBus.emit({type:"orchestrator:error",error:c instanceof Error?c.message:String(c),context:`autonomous task for agent ${n.id}`,fatal:false});}}r&&this.cachedTaskStore.invalidate();}async dispatchAll(){let t=this.state,e=this.deps.config.scheduling.max_concurrent_agents,s=Object.keys(t.running).length,a=e-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 S=(i.goalId?0:1)-(h.goalId?0:1);if(S!==0)return S;let w=h.updated_at??"",m=i.updated_at??"";return w<m?-1:w>m?1:0}).slice(0,a),l$1=new Set,p=r.filter(i=>i.status==="in_progress"&&i.scope?.length),f=new x(p.map(i=>i.scope));for(let i of n)if(i.scope?.length)if(f.overlapsAny(i.scope)){let h=p.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}),l$1.add(i.id);}else f.add(i.scope);for(let i of n)if(!l$1.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);c&&!b(c.status)&&(c.status="failed",c.updated_at=new Date().toISOString(),await this.deps.taskStore.save(c));}catch{}this.deps.eventBus.emit({type:"orchestrator:error",error:h instanceof Error?h.message:String(h),context:`dispatch task ${i.id}`,fatal:false});}}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),l=this.deps.config.prompt?.system_template??d$2,p=this.deps.config.prompt?.user_template??e$2,f=this.deps.config.prompt?.template,i=s.attempts+1,h;if(i>1){let v=await this.deps.runService.getLastFailedRunContext(s.id);v&&(h={previous_error:v.error,previous_output:v.output});}let c=s.goalId,[S,w,m]=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]),o;if(m){let ot=(await this.cachedTaskStore.list()).filter(P=>P.goalId===c),ct=await this.deps.contextStore?.get(`${c}-progress`),lt=ot.map(P=>`[${P.status}] ${P.title}`);o={id:m.id,title:m.title,description:m.description,status:m.status,task_names:lt,progress:ct?.value};}let g=c$1(s,r,i,d,this.deps.config,{allAgents:a,retryContext:h,sharedContext:S,feedback:s.feedback,messages:w.length?w:void 0,goal:o}),y,R;f?y=await this.deps.templateEngine.render(f,g):(R=await this.deps.templateEngine.render(l,g),y=await this.deps.templateEngine.render(p,g));let T=await this.deps.runService.create({taskId:s.id,agentId:r.id,attempt:i,prompt:y,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 v=await this.deps.taskStore.get(t);v&&(v.proof={...v.proof??{files_changed:[]},branch:n},v.workspace=d,await this.deps.taskStore.save(v));}await this.deps.agentService.setStatus(r.id,"running");let k=await this.deps.agentService.get(r.id);k.current_task=t,k.last_error=void 0,await this.deps.agentStore.save(k);let nt=this.deps.adapterRegistry.require(r.adapter),I=new AbortController;this.abortControllers.set(t,I);let F=nt.execute({prompt:y,systemPrompt:R,workspace:d,env:{...r.config.env,ORCH_AGENT_ID:r.id,ORCH_AGENT_NAME:r.name,ORCH_TASK_ID:s.id},config:k.config,signal:I.signal}),N=F.pid,U=new Date().toISOString();await this.deps.runService.start(T.id,N),this.unclaim(t),e.running[t]={run_id:T.id,agent_id:r.id,task_id:t,pid:N,started_at:U,last_event_at:U},await this.saveState(),this.collectEvents(F.events,T.id,t,r.id).catch(v=>{this.deps.eventBus.emit({type:"orchestrator:error",error:v instanceof Error?v.message:String(v),context:`adapter execution for ${t}`,fatal:!1});});}catch(a){throw this.unclaim(t),await this.saveState(),a}}async collectEvents(t,e,s,a){let r,d,n,l,p=new Set;try{for await(let i of t){if(this.shuttingDown)break;if(i.type==="done"){if(i.tokens){let{input:g,output:y,reasoning:R,cache_read:T,cache_write:k}=i.tokens;r=a$1(g,y,{reasoning:R,cache_read:T,cache_write:k});}let o=i.data;o&&typeof o.result=="string"&&(d=o.result);}if(i.type==="output"){let o=i.data;if(o){let g=typeof o.text=="string"?o.text:typeof o.message=="string"?o.message:void 0;g?.trim()&&(n=g);}}if(i.type==="file_change"){let o=i.data;if(o&&Array.isArray(o.paths))for(let g of o.paths)typeof g=="string"&&p.add(g);else {let g=o&&typeof o.path=="string"?o.path:typeof i.data=="string"?i.data:String(i.data);p.add(g);}}let h=St(i.timestamp)?i.timestamp:new Date().toISOString(),c=i.type==="file_change"?(()=>{let o=i.data;return o&&typeof o.path=="string"?o.path:typeof i.data=="string"?i.data:String(i.data)})():null,S=rt(i.data,mt);i.data=void 0;let w={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:S};await this.deps.runService.appendEvent(e,w),this.state?.running[s]&&(this.state.running[s].last_event_at=h,this.saveStateLazy());let m=rt(S,vt);i.type==="output"||i.type==="tool_call"?this.deps.eventBus.emit({type:"agent:output",runId:e,agentId:a,data:m}):i.type==="file_change"?this.deps.eventBus.emit({type:"agent:file_changed",runId:e,agentId:a,path:c}):i.type==="error"&&(i.errorKind&&(l=i.errorKind),this.deps.eventBus.emit({type:"agent:error",runId:e,agentId:a,error:m,...i.errorKind?{errorKind:i.errorKind}:{}}));}let f=d??n;await this.handleRunSuccess(s,e,a,r,f,[...p]);}catch(f){let i=f instanceof Error?f.message:String(f),h=l??(f instanceof Error?f.errorKind:void 0),c=this.state?.running[s];c&&await this.handleRunFailure(s,c,i,h);}}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 l=await this.deps.taskStore.get(t);if(!l)return;l.proof={...l.proof,agent_summary:r?.slice(0,2e3)??l.proof?.agent_summary,files_changed:d?.length?d:l.proof?.files_changed??[]},delete l.feedback,await this.deps.taskStore.save(l);let p=await this.deps.agentStore.get(s),i=l.labels?.includes(a)||p?.config.approval_policy==="auto",h=f(l,true,i);await this.deps.runService.finish(e,"succeeded",a$1);let c=n.running[t],S=c?Date.now()-new Date(c.started_at).getTime():0;c&&(n.stats.total_runtime_ms+=S),delete n.running[t];let w={tasks_completed:(p?.stats.tasks_completed??0)+1,total_runs:(p?.stats.total_runs??0)+1,total_runtime_ms:(p?.stats.total_runtime_ms??0)+S};if(a$1&&(w.tokens_used=(p?.stats.tokens_used??0)+a$1.total),await this.deps.agentService.updateStats(s,w).catch(o=>{this.deps.eventBus.emit({type:"orchestrator:error",error:o instanceof Error?o.message:String(o),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),l.proof?.branch)try{let o=await this.deps.workspaceManager.mergeBack(l.proof.branch);if(o.success)this.deps.eventBus.emit({type:"workspace:merge_succeeded",taskId:t,branch:l.proof.branch}),await this.deps.workspaceManager.cleanup(t).catch(g=>{this.deps.eventBus.emit({type:"orchestrator:error",error:g instanceof Error?g.message:String(g),context:`workspace cleanup for ${t}`,fatal:!1});});else {this.deps.eventBus.emit({type:"workspace:merge_conflict",taskId:t,branch:l.proof.branch,conflictInfo:o.conflictInfo}),await this.forceTaskToReview(l,s,`MERGE CONFLICT: ${o.conflictInfo}`);return}}catch(o){let g=o instanceof Error?o.message:String(o);await this.forceTaskToReview(l,s,`MERGE ERROR: ${g}`);return}try{await this.deps.taskService.updateStatus(t,h);}catch(o){let g=o instanceof Error?o.message:String(o);this.deps.eventBus.emit({type:"orchestrator:error",error:g,context:`state machine validation failed for task ${t} -> ${h}, force-writing`,fatal:false}),l.status=h,l.updated_at=new Date().toISOString(),await this.deps.taskStore.save(l).catch(y=>{this.deps.eventBus.emit({type:"orchestrator:error",error:y instanceof Error?y.message:String(y),context:`force-write task ${t} to store failed`,fatal:false});});}await this.deps.agentService.setStatus(s,"idle").catch(o=>{this.deps.eventBus.emit({type:"orchestrator:error",error:o instanceof Error?o.message:String(o),context:`_handleRunSuccess setStatus idle for agent ${s}`,fatal:false});});let m=await this.deps.agentStore.get(s);m&&(m.current_task=void 0,await this.deps.agentStore.save(m)),h==="review"&&l.review_criteria?.length?await this.runAutoReview(t,l.review_criteria,l.workspace??this.deps.projectRoot,i):h==="review"&&i&&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 l=await this.deps.agentStore.get(e$1.agent_id),p=Date.now()-new Date(e$1.started_at).getTime();await this.deps.agentService.updateStats(e$1.agent_id,{tasks_failed:(l?.stats.tasks_failed??0)+1,total_runs:(l?.stats.total_runs??0)+1,total_runtime_ms:(l?.stats.total_runtime_ms??0)+p});let f=e(d);if(await this.deps.taskService.updateStatus(t,f),f==="retrying"){let i=g(d.attempts-1,this.deps.config.scheduling.retry_base_delay_ms,this.deps.config.scheduling.retry_max_delay_ms);r.retry_queue.some(c=>c.task_id===t)||(r.retry_queue.length>=this.maxRetryQueueSize&&r.retry_queue.shift(),r.retry_queue.push({task_id:t,attempt:d.attempts+1,due_at:new Date(Date.now()+i).toISOString(),error:s})),this.deps.eventBus.emit({type:"run:retry",runId:e$1.run_id,attempt:d.attempts+1,delay_ms:i});}else r.stats.total_tasks_failed++;r.stats.total_runtime_ms+=p,delete r.running[t],r.stats.total_runs++,await this.saveState(),this.scheduleImmediateDispatch();}async runAutoReview(t,e,s,a=false){let d=await new _({cwd:s}).runAll(e),n=_.allPassed(d),l=await this.deps.taskStore.get(t);if(l&&(l.review_results=d,l.proof={...l.proof,test_results:_.formatReport(d),files_changed:l.proof?.files_changed??[]},await this.deps.taskStore.save(l),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(p){let f=p instanceof Error?p.message:String(p);this.deps.eventBus.emit({type:"orchestrator:error",error:f,context:`auto-review transition failed for task ${t} -> done, force-writing`,fatal:false}),l.status="done",l.updated_at=new Date().toISOString(),await this.deps.taskStore.save(l).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}
|
|
12
|
+
|
|
13
|
+
${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(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 St(u){if(typeof u!="string")return false;let t=new Date(u);return !isNaN(t.getTime())&&t.toISOString()===u}function rt(u,t){let e=typeof u=="string"?u:JSON.stringify(u);return e.length>t?e.slice(0,t)+"\u2026":e}export{at as Orchestrator};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {i}from'./chunk-64WUDYEM.js';import d from'fs';var f=6;function h(o,e){o.command("serve").description("Headless daemon mode \u2014 structured logs to stdout").option("--once","Process todo tasks and exit when all are terminal").option("--tick-interval <ms>","Override polling interval (ms)").option("--log-file <path>","Also write logs to file (append mode)").option("--log-format <format>","Log format: json or text (default: json)","json").option("--verbose","Include high-frequency agent:output events").action(async s=>{await p(e,s);});}var g=new Set(["json","text"]);async function p(o,e){if(e.logFormat&&!g.has(e.logFormat)){i(`Unknown --log-format "${e.logFormat}". Valid: json, text`),process.exitCode=2;return}let s=e.logFormat==="text"?"text":"json",a=[process.stdout],n;if(e.logFile&&(n=d.createWriteStream(e.logFile,{flags:"a"}),n.on("error",t=>{process.stderr.write(`Log file error: ${t.message}
|
|
3
|
+
`);}),a.push(n)),e.tickInterval){let t=parseInt(e.tickInterval,10);!isNaN(t)&&t>0&&(o.config.scheduling.poll_interval_ms=t);}let{StructuredLogger:m}=await import('./structured-logger-EXMGTUDB.js'),r=new m({format:s,verbose:e.verbose??false,streams:a,idleLogInterval:f}),c=r.subscribe(o.eventBus);r.log("info","serve:started",{mode:e.once?"once":"watch",pid:process.pid,poll_interval_ms:o.config.scheduling.poll_interval_ms});try{if(e.once){let{runOnce:t}=await import('./once-runner-UCMXCY6C.js'),i=await t(o.orchestrator,o.taskStore,o.eventBus);r.log("info","serve:finished",{result:i,exit_code:i==="has_failed"?1:0}),process.exitCode=i==="has_failed"?1:0;}else await o.orchestrator.startWatch();}finally{c(),await r.flush();}}export{h as registerServeCommand};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var o=class{tickCounter=0;opts;constructor(r){this.opts=r;}subscribe(r){return r.onAny(t=>{let e=this.transform(t);e&&this.write(e);})}log(r,t,e){this.write({ts:new Date().toISOString(),level:r,event:t,...e});}async flush(){let r=this.opts.streams.filter(t=>t!==process.stdout&&t!==process.stderr).map(t=>new Promise(e=>{t.end(()=>{e();});}));await Promise.all(r);}transform(r){let t=new Date().toISOString();switch(r.type){case "orchestrator:tick":{this.tickCounter++;let e=r.running===0&&r.queued===0;if(!this.opts.verbose&&e&&this.tickCounter%this.opts.idleLogInterval!==0)return null;let a=+(process.memoryUsage().heapUsed/1048576).toFixed(1);return {ts:t,level:"info",event:r.type,running:r.running,queued:r.queued,heap_mb:a}}case "orchestrator:shutdown":return {ts:t,level:"info",event:r.type,reason:r.reason};case "orchestrator:error":return {ts:t,level:r.fatal?"error":"warn",event:r.type,error:r.error,context:r.context,fatal:r.fatal};case "orchestrator:stall_detected":return {ts:t,level:"warn",event:r.type,runId:r.runId};case "agent:started":return {ts:t,level:"info",event:r.type,agentId:r.agentId,taskId:r.taskId,runId:r.runId};case "agent:completed":return {ts:t,level:r.success?"info":"warn",event:r.type,runId:r.runId,agentId:r.agentId,success:r.success};case "agent:error":return {ts:t,level:"error",event:r.type,runId:r.runId,agentId:r.agentId,error:r.error,errorKind:r.errorKind};case "agent:output":return this.opts.verbose?{ts:t,level:"debug",event:r.type,runId:r.runId,agentId:r.agentId,data:r.data.slice(0,200)}:null;case "agent:file_changed":return {ts:t,level:"info",event:r.type,runId:r.runId,agentId:r.agentId,path:r.path};case "run:retry":return {ts:t,level:"warn",event:r.type,runId:r.runId,attempt:r.attempt,delay_ms:r.delay_ms};case "task:created":return {ts:t,level:"info",event:r.type,taskId:r.task.id,title:r.task.title};case "task:status_changed":return {ts:t,level:"info",event:r.type,taskId:r.taskId,from:r.from,to:r.to};case "task:auto_reviewed":return {ts:t,level:"info",event:r.type,taskId:r.taskId,passed:r.passed};case "workspace:merge_succeeded":return {ts:t,level:"info",event:r.type,taskId:r.taskId,branch:r.branch};case "workspace:merge_conflict":return {ts:t,level:"warn",event:r.type,taskId:r.taskId,branch:r.branch,conflictInfo:r.conflictInfo};case "task:orphaned":return {ts:t,level:"warn",event:r.type,taskId:r.taskId};case "task:scope_overlap":return {ts:t,level:"warn",event:r.type,taskId:r.taskId,overlappingTaskId:r.overlappingTaskId,patterns:r.patterns};default:return null}}write(r){let t=this.opts.format==="json"?JSON.stringify(r)+`
|
|
3
|
+
`:this.formatText(r);for(let e of this.opts.streams)e.write(t);}formatText(r){let t=r.ts.slice(11,23),e=r.level.toUpperCase().padEnd(5),{ts:a,level:p,event:n,...i}=r,l=Object.entries(i).map(([d,s])=>`${d}=${typeof s=="string"?s:JSON.stringify(s)}`).join(" ");return `${t} ${e} ${n} ${l}
|
|
4
|
+
`}};export{o as StructuredLogger};
|
|
@@ -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-
|
|
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-FUHRQOV4.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 ot(c,e){c.command("tui").description("Launch interactive TUI dashboard").action(async()=>{let v=await e.taskService.list(),S=await e.agentService.list(),w=await e.stateStore.read(),{render:f}=await import('ink'),{createElement:h}=await import('react'),{App:T}=await import('./App-SSYYVFGW.js'),k=async t=>{await e.orchestrator.runTask(t);},A=async(t,s)=>e.taskService.create({title:t,priority:s?.priority,description:s?.description,attachments:s?.attachments}),b=async t=>{await e.orchestrator.cancelTask(t);},C=async t=>{await e.taskService.retry(t);},R=async(t,s)=>{await e.taskService.assign(t,s);},_=async()=>{await e.orchestrator.runAll();},E=async t=>{await e.agentService.disable(t);},j=async t=>{await e.agentService.enable(t);},D=t=>e.eventBus.onAny(t),P=async()=>e.taskService.list(),G=async()=>e.agentService.list(),U=async()=>e.stateStore.read(),x=async(t,s,n)=>e.agentService.create({name:t,adapter:s??"claude",model:n?.model||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);},H=async t=>{await e.taskService.delete(t);},I=async t=>{await e.taskService.updateStatus(t,"done");},W=async(t,s)=>{await e.taskService.reject(t,s);},F=async(t,s)=>e.taskService.update(t,s),N=async(t,s)=>e.agentService.update(t,{...s,approval_policy:s.approval_policy}),O=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,r)=>new Date(r.started_at).getTime()-new Date(a.started_at).getTime());let n=s.filter(a=>a.status==="succeeded"||a.status==="failed"),m=3,rt=10,p=n.slice(0,m),u=n.slice(m,rt),y=async a=>(await e.runService.readEventsTail(a.id,30)).map(i=>({timestamp:i.timestamp,agentId:a.agent_id,taskId:a.task_id,type:i.type,data:i.data}));if(p.length>0){let a=(await Promise.all(p.map(y))).flat();a.sort((r,i)=>new Date(r.timestamp).getTime()-new Date(i.timestamp).getTime()),t(a.slice(-200));}if(u.length>0){let a=(await Promise.all(u.map(y))).flat();a.sort((r,i)=>new Date(r.timestamp).getTime()-new Date(i.timestamp).getTime()),t(a.slice(-200));}},B=async t=>e.teamService.create(t),J=async()=>e.teamService.list(),K=async(t,s)=>e.teamService.join(t,s),q=async(t,s)=>e.teamService.leave(t,s),z=async t=>{await e.teamService.disband(t);},Q=async(t,s)=>e.teamService.setLead(t,s),X=async()=>e.goalService.list(),Y=async t=>e.goalService.create(t),Z=async(t,s)=>e.goalService.update(t,s),$=async(t,s)=>e.goalService.updateStatus(t,s),tt=async t=>{await e.goalService.delete(t);},et=async t=>e.goalService.getProgressReport(t),st=async()=>{await e.orchestrator.startWatch();},at=async()=>{await e.orchestrator.stop();},l=c.version()??"0.0.0",nt=import('./update-check-HGMBDYHL.js').then(t=>t.checkForUpdateSWR(l)).catch(()=>null),o=false,g;try{await e.orchestrator.startWatch(),o=!0;}catch(t){g=t instanceof Error?t.message:String(t);}let d=await nt,{waitUntilExit:it}=f(h(T,{projectName:e.config.project.name,tasks:v,agents:S,state:w,onRunTask:k,onCreateTask:A,onCancelTask:b,onRetryTask:C,onAssignTask:R,onRunAll:_,onDisableAgent:E,onEnableAgent:j,onSubscribeEvents:D,onRefreshTasks:P,onRefreshAgents:G,onRefreshState:U,onLoadHistory:V,onAddAgent:x,onDeleteAgent:L,onApproveTask:I,onRejectTask:W,onDeleteTask:H,onUpdateTask:F,onUpdateAgent:N,onForceStopAgent:O,onToggleAutonomous:M,onRefreshGoals:X,onCreateGoal:Y,onUpdateGoal:Z,onUpdateGoalStatus:$,onDeleteGoal:tt,onGetGoalProgress:et,onCreateTeam:B,onListTeams:J,onJoinTeam:K,onLeaveTeam:q,onDisbandTeam:z,onSetTeamLead:Q,onStartWatch:st,onStopWatch:at,initialWatchActive:o,watchError:g,version:l,latestVersion:d?.updateAvailable?d.latest:void 0,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(),o&&await e.orchestrator.stop().catch(()=>{});});}export{ot as registerTuiCommand};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxgeneral/orch",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Open-source orchestration for zero-human companies, processes and departments — deploy AI engineering, editorial, sales, analytics teams from your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|