@automagik/genie 4.260324.19 → 4.260324.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/dist/genie.js +21 -20
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/genie/.claude-plugin/plugin.json +1 -1
- package/plugins/genie/package.json +1 -1
- package/src/lib/protocol-router-spawn.ts +17 -1
- package/src/term-commands/agents.ts +23 -10
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "genie",
|
|
13
|
-
"version": "4.260324.
|
|
13
|
+
"version": "4.260324.20",
|
|
14
14
|
"source": "./plugins/genie",
|
|
15
15
|
"description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, wish them into plans, make with parallel agents, ship as one team. A coding genie that grows with your project."
|
|
16
16
|
}
|
package/dist/genie.js
CHANGED
|
@@ -126,11 +126,9 @@ ${errCtx.stack}`;sub.unsubscribe(),d.reject(err)}else if(err=(0,msg_1.isRequestE
|
|
|
126
126
|
|
|
127
127
|
${errCtx.stack}`;d.reject(err)}else d.resolve(msg)}});return sub.requestSubject=subject,this.protocol.publish(subject,data,{reply:inbox,headers:opts.headers}),d}else{let r=new request_1.RequestOne(this.protocol.muxSubscriptions,subject,opts,asyncTraces);this.protocol.request(r);try{this.publish(subject,data,{reply:`${this.protocol.muxSubscriptions.baseInbox}${r.token}`,headers:opts.headers})}catch(err){r.cancel(err)}let p=Promise.race([r.timer,r.deferred]);return p.catch(()=>{r.cancel()}),p}}flush(){if(this.isClosed())return Promise.reject(types_1.NatsError.errorForCode(core_1.ErrorCode.ConnectionClosed));return this.protocol.flush()}drain(){if(this.isClosed())return Promise.reject(types_1.NatsError.errorForCode(core_1.ErrorCode.ConnectionClosed));if(this.isDraining())return Promise.reject(types_1.NatsError.errorForCode(core_1.ErrorCode.ConnectionDraining));return this.draining=!0,this.protocol.drain()}isClosed(){return this.protocol.isClosed()}isDraining(){return this.draining}getServer(){let srv=this.protocol.getServer();return srv?srv.listen:""}status(){let iter=new queued_iterator_1.QueuedIteratorImpl;return iter.iterClosed.then(()=>{let idx=this.listeners.indexOf(iter);this.listeners.splice(idx,1)}),this.listeners.push(iter),iter}get info(){return this.protocol.isClosed()?void 0:this.protocol.info}context(){return __awaiter(this,void 0,void 0,function*(){return(yield this.request("$SYS.REQ.USER.INFO")).json((key,value)=>{if(key==="time")return new Date(Date.parse(value));return value})})}stats(){return{inBytes:this.protocol.inBytes,outBytes:this.protocol.outBytes,inMsgs:this.protocol.inMsgs,outMsgs:this.protocol.outMsgs}}jetstreamManager(){return __awaiter(this,arguments,void 0,function*(opts={}){let adm=new jsm_1.JetStreamManagerImpl(this,opts);if(opts.checkAPI!==!1)try{yield adm.getAccountInfo()}catch(err){let ne=err;if(ne.code===core_1.ErrorCode.NoResponders)ne.code=core_1.ErrorCode.JetStreamNotEnabled;throw ne}return adm})}jetstream(opts={}){return new jsclient_1.JetStreamClientImpl(this,opts)}getServerVersion(){let info=this.info;return info?(0,semver_1.parseSemVer)(info.version):void 0}rtt(){return __awaiter(this,void 0,void 0,function*(){if(!this.protocol._closed&&!this.protocol.connected)throw types_1.NatsError.errorForCode(core_1.ErrorCode.Disconnect);let start=Date.now();return yield this.flush(),Date.now()-start})}get features(){return this.protocol.features}get services(){if(!this._services)this._services=new ServicesFactory(this);return this._services}reconnect(){if(this.isClosed())return Promise.reject(types_1.NatsError.errorForCode(core_1.ErrorCode.ConnectionClosed));if(this.isDraining())return Promise.reject(types_1.NatsError.errorForCode(core_1.ErrorCode.ConnectionDraining));return this.protocol.reconnect()}}exports.NatsConnectionImpl=NatsConnectionImpl;class ServicesFactory{constructor(nc){this.nc=nc}add(config){try{return new service_1.ServiceImpl(this.nc,config).start()}catch(err){return Promise.reject(err)}}client(opts,prefix){return new serviceclient_1.ServiceClientImpl(this.nc,opts,prefix)}}exports.ServicesFactory=ServicesFactory});var require_bench=__commonJS((exports)=>{var __awaiter=exports&&exports.__awaiter||function(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve4){resolve4(value)})}return new(P||(P=Promise))(function(resolve4,reject){function fulfilled(value){try{step(generator.next(value))}catch(e){reject(e)}}function rejected(value){try{step(generator.throw(value))}catch(e){reject(e)}}function step(result){result.done?resolve4(result.value):adopt(result.value).then(fulfilled,rejected)}step((generator=generator.apply(thisArg,_arguments||[])).next())})},__asyncValues=exports&&exports.__asyncValues||function(o){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var m=o[Symbol.asyncIterator],i2;return m?m.call(o):(o=typeof __values==="function"?__values(o):o[Symbol.iterator](),i2={},verb("next"),verb("throw"),verb("return"),i2[Symbol.asyncIterator]=function(){return this},i2);function verb(n){i2[n]=o[n]&&function(v){return new Promise(function(resolve4,reject){v=o[n](v),settle(resolve4,reject,v.done,v.value)})}}function settle(resolve4,reject,d,v){Promise.resolve(v).then(function(v2){resolve4({value:v2,done:d})},reject)}};Object.defineProperty(exports,"__esModule",{value:!0});exports.Bench=exports.Metric=void 0;exports.throughput=throughput;exports.msgThroughput=msgThroughput;exports.humanizeBytes=humanizeBytes;var types_1=require_types(),nuid_1=require_nuid(),util_1=require_util(),core_1=require_core();class Metric{constructor(name,duration){this.name=name,this.duration=duration,this.date=Date.now(),this.payload=0,this.msgs=0,this.bytes=0}toString(){let sec=this.duration/1000,mps=Math.round(this.msgs/sec),label=this.asyncRequests?"asyncRequests":"",minmax="";if(this.max)minmax=`${this.min}/${this.max}`;return`${this.name}${label?" [asyncRequests]":""} ${humanizeNumber(mps)} msgs/sec - [${sec.toFixed(2)} secs] ~ ${throughput(this.bytes,sec)} ${minmax}`}toCsv(){return`"${this.name}",${new Date(this.date).toISOString()},${this.lang},${this.version},${this.msgs},${this.payload},${this.bytes},${this.duration},${this.asyncRequests?this.asyncRequests:!1}
|
|
128
128
|
`}static header(){return`Test,Date,Lang,Version,Count,MsgPayload,Bytes,Millis,Async
|
|
129
|
-
`}}exports.Metric=Metric;class Bench{constructor(nc,opts={msgs:1e5,size:128,subject:"",asyncRequests:!1,pub:!1,sub:!1,req:!1,rep:!1}){if(this.nc=nc,this.callbacks=opts.callbacks||!1,this.msgs=opts.msgs||0,this.size=opts.size||0,this.subject=opts.subject||nuid_1.nuid.next(),this.asyncRequests=opts.asyncRequests||!1,this.pub=opts.pub||!1,this.sub=opts.sub||!1,this.req=opts.req||!1,this.rep=opts.rep||!1,this.perf=new util_1.Perf,this.payload=this.size?new Uint8Array(this.size):types_1.Empty,!this.pub&&!this.sub&&!this.req&&!this.rep)throw Error("no bench option selected")}run(){return __awaiter(this,void 0,void 0,function*(){if(this.nc.closed().then((err)=>{if(err)throw new core_1.NatsError(`bench closed with an error: ${err.message}`,core_1.ErrorCode.Unknown,err)}),this.callbacks)yield this.runCallbacks();else yield this.runAsync();return this.processMetrics()})}processMetrics(){let nc=this.nc,{lang,version}=nc.protocol.transport;if(this.pub&&this.sub)this.perf.measure("pubsub","pubStart","subStop");if(this.req&&this.rep)this.perf.measure("reqrep","reqStart","reqStop");let measures=this.perf.getEntries(),pubsub=measures.find((m)=>m.name==="pubsub"),reqrep=measures.find((m)=>m.name==="reqrep"),req=measures.find((m)=>m.name==="req"),rep=measures.find((m)=>m.name==="rep"),pub=measures.find((m)=>m.name==="pub"),sub=measures.find((m)=>m.name==="sub"),stats=this.nc.stats(),metrics=[];if(pubsub){let{name,duration}=pubsub,m=new Metric(name,duration);m.msgs=this.msgs*2,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(reqrep){let{name,duration}=reqrep,m=new Metric(name,duration);m.msgs=this.msgs*2,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(pub){let{name,duration}=pub,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(sub){let{name,duration}=sub,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.inBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(rep){let{name,duration}=rep,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(req){let{name,duration}=req,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}return metrics}runCallbacks(){return __awaiter(this,void 0,void 0,function*(){let jobs=[];if(this.sub){let d=(0,util_1.deferred)();jobs.push(d);let i2=0;this.nc.subscribe(this.subject,{max:this.msgs,callback:()=>{if(i2++,i2===1)this.perf.mark("subStart");if(i2===this.msgs)this.perf.mark("subStop"),this.perf.measure("sub","subStart","subStop"),d.resolve()}})}if(this.rep){let d=(0,util_1.deferred)();jobs.push(d);let i2=0;this.nc.subscribe(this.subject,{max:this.msgs,callback:(_,m)=>{if(m.respond(this.payload),i2++,i2===1)this.perf.mark("repStart");if(i2===this.msgs)this.perf.mark("repStop"),this.perf.measure("rep","repStart","repStop"),d.resolve()}})}if(this.pub){let job=(()=>__awaiter(this,void 0,void 0,function*(){this.perf.mark("pubStart");for(let i2=0;i2<this.msgs;i2++)this.nc.publish(this.subject,this.payload);yield this.nc.flush(),this.perf.mark("pubStop"),this.perf.measure("pub","pubStart","pubStop")}))();jobs.push(job)}if(this.req){let job=(()=>__awaiter(this,void 0,void 0,function*(){if(this.asyncRequests){this.perf.mark("reqStart");let a=[];for(let i2=0;i2<this.msgs;i2++)a.push(this.nc.request(this.subject,this.payload,{timeout:20000}));yield Promise.all(a),this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}else{this.perf.mark("reqStart");for(let i2=0;i2<this.msgs;i2++)yield this.nc.request(this.subject);this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}}))();jobs.push(job)}yield Promise.all(jobs)})}runAsync(){return __awaiter(this,void 0,void 0,function*(){let jobs=[];if(this.rep){let first=!1,sub=this.nc.subscribe(this.subject,{max:this.msgs}),job=(()=>__awaiter(this,void 0,void 0,function*(){var _a,e_1,_b,_c;try{for(var _d=!0,sub_1=__asyncValues(sub),sub_1_1;sub_1_1=yield sub_1.next(),_a=sub_1_1.done,!_a;_d=!0){_c=sub_1_1.value,_d=!1;let m=_c;if(!first)this.perf.mark("repStart"),first=!0;m.respond(this.payload)}}catch(e_1_1){e_1={error:e_1_1}}finally{try{if(!_d&&!_a&&(_b=sub_1.return))yield _b.call(sub_1)}finally{if(e_1)throw e_1.error}}yield this.nc.flush(),this.perf.mark("repStop"),this.perf.measure("rep","repStart","repStop")}))();jobs.push(job)}if(this.sub){let first=!1,sub=this.nc.subscribe(this.subject,{max:this.msgs}),job=(()=>__awaiter(this,void 0,void 0,function*(){var _a,e_2,_b,_c;try{for(var _d=!0,sub_2=__asyncValues(sub),sub_2_1;sub_2_1=yield sub_2.next(),_a=sub_2_1.done,!_a;_d=!0){_c=sub_2_1.value,_d=!1;let _m=_c;if(!first)this.perf.mark("subStart"),first=!0}}catch(e_2_1){e_2={error:e_2_1}}finally{try{if(!_d&&!_a&&(_b=sub_2.return))yield _b.call(sub_2)}finally{if(e_2)throw e_2.error}}this.perf.mark("subStop"),this.perf.measure("sub","subStart","subStop")}))();jobs.push(job)}if(this.pub){let job=(()=>__awaiter(this,void 0,void 0,function*(){this.perf.mark("pubStart");for(let i2=0;i2<this.msgs;i2++)this.nc.publish(this.subject,this.payload);yield this.nc.flush(),this.perf.mark("pubStop"),this.perf.measure("pub","pubStart","pubStop")}))();jobs.push(job)}if(this.req){let job=(()=>__awaiter(this,void 0,void 0,function*(){if(this.asyncRequests){this.perf.mark("reqStart");let a=[];for(let i2=0;i2<this.msgs;i2++)a.push(this.nc.request(this.subject,this.payload,{timeout:20000}));yield Promise.all(a),this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}else{this.perf.mark("reqStart");for(let i2=0;i2<this.msgs;i2++)yield this.nc.request(this.subject);this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}}))();jobs.push(job)}yield Promise.all(jobs)})}}exports.Bench=Bench;function throughput(bytes,seconds){return`${humanizeBytes(bytes/seconds)}/sec`}function msgThroughput(msgs,seconds){return`${Math.floor(msgs/seconds)} msgs/sec`}function humanizeBytes(bytes,si=!1){let base=si?1000:1024,pre=si?["k","M","G","T","P","E"]:["K","M","G","T","P","E"],post=si?"iB":"B";if(bytes<base)return`${bytes.toFixed(2)} ${post}`;let exp=parseInt(Math.log(bytes)/Math.log(base)+""),index=parseInt(exp-1+"");return`${(bytes/Math.pow(base,exp)).toFixed(2)} ${pre[index]}${post}`}function humanizeNumber(n){return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}});var require_internal_mod=__commonJS((exports)=>{var __createBinding=exports&&exports.__createBinding||(Object.create?function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))desc={enumerable:!0,get:function(){return m[k]}};Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}),__exportStar=exports&&exports.__exportStar||function(m,exports2){for(var p in m)if(p!=="default"&&!Object.prototype.hasOwnProperty.call(exports2,p))__createBinding(exports2,m,p)};Object.defineProperty(exports,"__esModule",{value:!0});exports.parseIP=exports.isIP=exports.TE=exports.TD=exports.Metric=exports.Bench=exports.writeAll=exports.readAll=exports.MAX_SIZE=exports.DenoBuffer=exports.State=exports.Parser=exports.Kind=exports.QueuedIteratorImpl=exports.StringCodec=exports.JSONCodec=exports.usernamePasswordAuthenticator=exports.tokenAuthenticator=exports.nkeyAuthenticator=exports.jwtAuthenticator=exports.credsAuthenticator=exports.RequestOne=exports.checkUnsupportedOption=exports.checkOptions=exports.buildAuthenticator=exports.DataBuffer=exports.MuxSubscription=exports.Heartbeat=exports.MsgHdrsImpl=exports.headers=exports.canonicalMIMEHeaderKey=exports.timeout=exports.render=exports.nanos=exports.millis=exports.extend=exports.delay=exports.deferred=exports.deadline=exports.collect=exports.backoff=exports.ProtocolHandler=exports.INFO=exports.Connect=exports.setTransportFactory=exports.getResolveFn=exports.MsgImpl=exports.nuid=exports.Nuid=exports.NatsConnectionImpl=void 0;exports.Subscriptions=exports.SubscriptionImpl=exports.syncIterator=exports.ServiceVerb=exports.ServiceResponseType=exports.ServiceErrorHeader=exports.ServiceErrorCodeHeader=exports.ServiceError=exports.RequestStrategy=exports.NatsError=exports.Match=exports.isNatsError=exports.Events=exports.ErrorCode=exports.DebugEvents=exports.createInbox=exports.extractProtocolMessage=exports.Empty=exports.parseSemVer=exports.compare=exports.NoopKvCodecs=exports.defaultBucketOpts=exports.Bucket=exports.Base64KeyCodec=exports.TypedSubscription=void 0;var nats_1=require_nats();Object.defineProperty(exports,"NatsConnectionImpl",{enumerable:!0,get:function(){return nats_1.NatsConnectionImpl}});var nuid_1=require_nuid();Object.defineProperty(exports,"Nuid",{enumerable:!0,get:function(){return nuid_1.Nuid}});Object.defineProperty(exports,"nuid",{enumerable:!0,get:function(){return nuid_1.nuid}});var msg_1=require_msg();Object.defineProperty(exports,"MsgImpl",{enumerable:!0,get:function(){return msg_1.MsgImpl}});var transport_1=require_transport();Object.defineProperty(exports,"getResolveFn",{enumerable:!0,get:function(){return transport_1.getResolveFn}});Object.defineProperty(exports,"setTransportFactory",{enumerable:!0,get:function(){return transport_1.setTransportFactory}});var protocol_1=require_protocol();Object.defineProperty(exports,"Connect",{enumerable:!0,get:function(){return protocol_1.Connect}});Object.defineProperty(exports,"INFO",{enumerable:!0,get:function(){return protocol_1.INFO}});Object.defineProperty(exports,"ProtocolHandler",{enumerable:!0,get:function(){return protocol_1.ProtocolHandler}});var util_1=require_util();Object.defineProperty(exports,"backoff",{enumerable:!0,get:function(){return util_1.backoff}});Object.defineProperty(exports,"collect",{enumerable:!0,get:function(){return util_1.collect}});Object.defineProperty(exports,"deadline",{enumerable:!0,get:function(){return util_1.deadline}});Object.defineProperty(exports,"deferred",{enumerable:!0,get:function(){return util_1.deferred}});Object.defineProperty(exports,"delay",{enumerable:!0,get:function(){return util_1.delay}});Object.defineProperty(exports,"extend",{enumerable:!0,get:function(){return util_1.extend}});Object.defineProperty(exports,"millis",{enumerable:!0,get:function(){return util_1.millis}});Object.defineProperty(exports,"nanos",{enumerable:!0,get:function(){return util_1.nanos}});Object.defineProperty(exports,"render",{enumerable:!0,get:function(){return util_1.render}});Object.defineProperty(exports,"timeout",{enumerable:!0,get:function(){return util_1.timeout}});var headers_1=require_headers();Object.defineProperty(exports,"canonicalMIMEHeaderKey",{enumerable:!0,get:function(){return headers_1.canonicalMIMEHeaderKey}});Object.defineProperty(exports,"headers",{enumerable:!0,get:function(){return headers_1.headers}});Object.defineProperty(exports,"MsgHdrsImpl",{enumerable:!0,get:function(){return headers_1.MsgHdrsImpl}});var heartbeats_1=require_heartbeats();Object.defineProperty(exports,"Heartbeat",{enumerable:!0,get:function(){return heartbeats_1.Heartbeat}});var muxsubscription_1=require_muxsubscription();Object.defineProperty(exports,"MuxSubscription",{enumerable:!0,get:function(){return muxsubscription_1.MuxSubscription}});var databuffer_1=require_databuffer();Object.defineProperty(exports,"DataBuffer",{enumerable:!0,get:function(){return databuffer_1.DataBuffer}});var options_1=require_options();Object.defineProperty(exports,"buildAuthenticator",{enumerable:!0,get:function(){return options_1.buildAuthenticator}});Object.defineProperty(exports,"checkOptions",{enumerable:!0,get:function(){return options_1.checkOptions}});Object.defineProperty(exports,"checkUnsupportedOption",{enumerable:!0,get:function(){return options_1.checkUnsupportedOption}});var request_1=require_request();Object.defineProperty(exports,"RequestOne",{enumerable:!0,get:function(){return request_1.RequestOne}});var authenticator_1=require_authenticator();Object.defineProperty(exports,"credsAuthenticator",{enumerable:!0,get:function(){return authenticator_1.credsAuthenticator}});Object.defineProperty(exports,"jwtAuthenticator",{enumerable:!0,get:function(){return authenticator_1.jwtAuthenticator}});Object.defineProperty(exports,"nkeyAuthenticator",{enumerable:!0,get:function(){return authenticator_1.nkeyAuthenticator}});Object.defineProperty(exports,"tokenAuthenticator",{enumerable:!0,get:function(){return authenticator_1.tokenAuthenticator}});Object.defineProperty(exports,"usernamePasswordAuthenticator",{enumerable:!0,get:function(){return authenticator_1.usernamePasswordAuthenticator}});var codec_1=require_codec();Object.defineProperty(exports,"JSONCodec",{enumerable:!0,get:function(){return codec_1.JSONCodec}});Object.defineProperty(exports,"StringCodec",{enumerable:!0,get:function(){return codec_1.StringCodec}});__exportStar(require_nkeys2(),exports);var queued_iterator_1=require_queued_iterator();Object.defineProperty(exports,"QueuedIteratorImpl",{enumerable:!0,get:function(){return queued_iterator_1.QueuedIteratorImpl}});var parser_1=require_parser();Object.defineProperty(exports,"Kind",{enumerable:!0,get:function(){return parser_1.Kind}});Object.defineProperty(exports,"Parser",{enumerable:!0,get:function(){return parser_1.Parser}});Object.defineProperty(exports,"State",{enumerable:!0,get:function(){return parser_1.State}});var denobuffer_1=require_denobuffer();Object.defineProperty(exports,"DenoBuffer",{enumerable:!0,get:function(){return denobuffer_1.DenoBuffer}});Object.defineProperty(exports,"MAX_SIZE",{enumerable:!0,get:function(){return denobuffer_1.MAX_SIZE}});Object.defineProperty(exports,"readAll",{enumerable:!0,get:function(){return denobuffer_1.readAll}});Object.defineProperty(exports,"writeAll",{enumerable:!0,get:function(){return denobuffer_1.writeAll}});var bench_1=require_bench();Object.defineProperty(exports,"Bench",{enumerable:!0,get:function(){return bench_1.Bench}});Object.defineProperty(exports,"Metric",{enumerable:!0,get:function(){return bench_1.Metric}});var encoders_1=require_encoders();Object.defineProperty(exports,"TD",{enumerable:!0,get:function(){return encoders_1.TD}});Object.defineProperty(exports,"TE",{enumerable:!0,get:function(){return encoders_1.TE}});var ipparser_1=require_ipparser();Object.defineProperty(exports,"isIP",{enumerable:!0,get:function(){return ipparser_1.isIP}});Object.defineProperty(exports,"parseIP",{enumerable:!0,get:function(){return ipparser_1.parseIP}});var typedsub_1=require_typedsub();Object.defineProperty(exports,"TypedSubscription",{enumerable:!0,get:function(){return typedsub_1.TypedSubscription}});var kv_1=require_kv();Object.defineProperty(exports,"Base64KeyCodec",{enumerable:!0,get:function(){return kv_1.Base64KeyCodec}});Object.defineProperty(exports,"Bucket",{enumerable:!0,get:function(){return kv_1.Bucket}});Object.defineProperty(exports,"defaultBucketOpts",{enumerable:!0,get:function(){return kv_1.defaultBucketOpts}});Object.defineProperty(exports,"NoopKvCodecs",{enumerable:!0,get:function(){return kv_1.NoopKvCodecs}});var semver_1=require_semver();Object.defineProperty(exports,"compare",{enumerable:!0,get:function(){return semver_1.compare}});Object.defineProperty(exports,"parseSemVer",{enumerable:!0,get:function(){return semver_1.parseSemVer}});var types_1=require_types();Object.defineProperty(exports,"Empty",{enumerable:!0,get:function(){return types_1.Empty}});var transport_2=require_transport();Object.defineProperty(exports,"extractProtocolMessage",{enumerable:!0,get:function(){return transport_2.extractProtocolMessage}});var core_1=require_core();Object.defineProperty(exports,"createInbox",{enumerable:!0,get:function(){return core_1.createInbox}});Object.defineProperty(exports,"DebugEvents",{enumerable:!0,get:function(){return core_1.DebugEvents}});Object.defineProperty(exports,"ErrorCode",{enumerable:!0,get:function(){return core_1.ErrorCode}});Object.defineProperty(exports,"Events",{enumerable:!0,get:function(){return core_1.Events}});Object.defineProperty(exports,"isNatsError",{enumerable:!0,get:function(){return core_1.isNatsError}});Object.defineProperty(exports,"Match",{enumerable:!0,get:function(){return core_1.Match}});Object.defineProperty(exports,"NatsError",{enumerable:!0,get:function(){return core_1.NatsError}});Object.defineProperty(exports,"RequestStrategy",{enumerable:!0,get:function(){return core_1.RequestStrategy}});Object.defineProperty(exports,"ServiceError",{enumerable:!0,get:function(){return core_1.ServiceError}});Object.defineProperty(exports,"ServiceErrorCodeHeader",{enumerable:!0,get:function(){return core_1.ServiceErrorCodeHeader}});Object.defineProperty(exports,"ServiceErrorHeader",{enumerable:!0,get:function(){return core_1.ServiceErrorHeader}});Object.defineProperty(exports,"ServiceResponseType",{enumerable:!0,get:function(){return core_1.ServiceResponseType}});Object.defineProperty(exports,"ServiceVerb",{enumerable:!0,get:function(){return core_1.ServiceVerb}});Object.defineProperty(exports,"syncIterator",{enumerable:!0,get:function(){return core_1.syncIterator}});var protocol_2=require_protocol();Object.defineProperty(exports,"SubscriptionImpl",{enumerable:!0,get:function(){return protocol_2.SubscriptionImpl}});Object.defineProperty(exports,"Subscriptions",{enumerable:!0,get:function(){return protocol_2.Subscriptions}})});var require_internal_mod2=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.ConsumerEvents=exports.ConsumerDebugEvents=exports.StoreCompression=exports.StorageType=exports.RetentionPolicy=exports.ReplayPolicy=exports.DiscardPolicy=exports.DeliverPolicy=exports.AckPolicy=exports.RepublishHeaders=exports.KvWatchInclude=exports.JsHeaders=exports.isConsumerOptsBuilder=exports.DirectMsgHeaders=exports.consumerOpts=exports.AdvisoryKind=exports.isHeartbeatMsg=exports.isFlowControlMsg=exports.checkJsError=void 0;var jsutil_1=require_jsutil();Object.defineProperty(exports,"checkJsError",{enumerable:!0,get:function(){return jsutil_1.checkJsError}});Object.defineProperty(exports,"isFlowControlMsg",{enumerable:!0,get:function(){return jsutil_1.isFlowControlMsg}});Object.defineProperty(exports,"isHeartbeatMsg",{enumerable:!0,get:function(){return jsutil_1.isHeartbeatMsg}});var types_1=require_types2();Object.defineProperty(exports,"AdvisoryKind",{enumerable:!0,get:function(){return types_1.AdvisoryKind}});Object.defineProperty(exports,"consumerOpts",{enumerable:!0,get:function(){return types_1.consumerOpts}});Object.defineProperty(exports,"DirectMsgHeaders",{enumerable:!0,get:function(){return types_1.DirectMsgHeaders}});Object.defineProperty(exports,"isConsumerOptsBuilder",{enumerable:!0,get:function(){return types_1.isConsumerOptsBuilder}});Object.defineProperty(exports,"JsHeaders",{enumerable:!0,get:function(){return types_1.JsHeaders}});Object.defineProperty(exports,"KvWatchInclude",{enumerable:!0,get:function(){return types_1.KvWatchInclude}});Object.defineProperty(exports,"RepublishHeaders",{enumerable:!0,get:function(){return types_1.RepublishHeaders}});var jsapi_types_1=require_jsapi_types();Object.defineProperty(exports,"AckPolicy",{enumerable:!0,get:function(){return jsapi_types_1.AckPolicy}});Object.defineProperty(exports,"DeliverPolicy",{enumerable:!0,get:function(){return jsapi_types_1.DeliverPolicy}});Object.defineProperty(exports,"DiscardPolicy",{enumerable:!0,get:function(){return jsapi_types_1.DiscardPolicy}});Object.defineProperty(exports,"ReplayPolicy",{enumerable:!0,get:function(){return jsapi_types_1.ReplayPolicy}});Object.defineProperty(exports,"RetentionPolicy",{enumerable:!0,get:function(){return jsapi_types_1.RetentionPolicy}});Object.defineProperty(exports,"StorageType",{enumerable:!0,get:function(){return jsapi_types_1.StorageType}});Object.defineProperty(exports,"StoreCompression",{enumerable:!0,get:function(){return jsapi_types_1.StoreCompression}});var consumer_1=require_consumer();Object.defineProperty(exports,"ConsumerDebugEvents",{enumerable:!0,get:function(){return consumer_1.ConsumerDebugEvents}});Object.defineProperty(exports,"ConsumerEvents",{enumerable:!0,get:function(){return consumer_1.ConsumerEvents}})});var require_nats_base_client=__commonJS((exports)=>{var __createBinding=exports&&exports.__createBinding||(Object.create?function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))desc={enumerable:!0,get:function(){return m[k]}};Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}),__exportStar=exports&&exports.__exportStar||function(m,exports2){for(var p in m)if(p!=="default"&&!Object.prototype.hasOwnProperty.call(exports2,p))__createBinding(exports2,m,p)};Object.defineProperty(exports,"__esModule",{value:!0});__exportStar(require_internal_mod(),exports);__exportStar(require_internal_mod2(),exports)});var require_node_transport=__commonJS((exports)=>{var __awaiter=exports&&exports.__awaiter||function(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve5){resolve5(value)})}return new(P||(P=Promise))(function(resolve5,reject){function fulfilled(value){try{step(generator.next(value))}catch(e){reject(e)}}function rejected(value){try{step(generator.throw(value))}catch(e){reject(e)}}function step(result){result.done?resolve5(result.value):adopt(result.value).then(fulfilled,rejected)}step((generator=generator.apply(thisArg,_arguments||[])).next())})},__await=exports&&exports.__await||function(v){return this instanceof __await?(this.v=v,this):new __await(v)},__asyncGenerator=exports&&exports.__asyncGenerator||function(thisArg,_arguments,generator){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var g=generator.apply(thisArg,_arguments||[]),i2,q=[];return i2=Object.create((typeof AsyncIterator==="function"?AsyncIterator:Object).prototype),verb("next"),verb("throw"),verb("return",awaitReturn),i2[Symbol.asyncIterator]=function(){return this},i2;function awaitReturn(f){return function(v){return Promise.resolve(v).then(f,reject)}}function verb(n,f){if(g[n]){if(i2[n]=function(v){return new Promise(function(a,b){q.push([n,v,a,b])>1||resume(n,v)})},f)i2[n]=f(i2[n])}}function resume(n,v){try{step(g[n](v))}catch(e){settle(q[0][3],e)}}function step(r){r.value instanceof __await?Promise.resolve(r.value.v).then(fulfill,reject):settle(q[0][2],r)}function fulfill(value){resume("next",value)}function reject(value){resume("throw",value)}function settle(f,v){if(f(v),q.shift(),q.length)resume(q[0][0],q[0][1])}};Object.defineProperty(exports,"__esModule",{value:!0});exports.NodeTransport=void 0;exports.nodeResolveHost=nodeResolveHost;var nats_base_client_1=require_nats_base_client(),net_1=__require("net"),util_1=require_util(),tls_1=__require("tls"),{resolve:resolve4}=__require("path"),{readFile:readFile4,existsSync:existsSync14}=__require("fs"),dns=__require("dns"),VERSION2="2.29.3",LANG="nats.js";class NodeTransport{constructor(){this.yields=[],this.signal=(0,nats_base_client_1.deferred)(),this.closedNotification=(0,nats_base_client_1.deferred)(),this.connected=!1,this.tlsName="",this.done=!1,this.lang=LANG,this.version=VERSION2}connect(hp,options){return __awaiter(this,void 0,void 0,function*(){this.tlsName=hp.tlsName,this.options=options;let{tls}=this.options,{handshakeFirst}=tls||{};try{if(handshakeFirst===!0)this.socket=yield this.tlsFirst(hp);else this.socket=yield this.dial(hp);let info=yield this.peekInfo();(0,nats_base_client_1.checkOptions)(info,options);let{tls_required:tlsRequired,tls_available:tlsAvailable}=info,desired=tlsAvailable===!0&&options.tls!==null;if(!handshakeFirst&&(tlsRequired||desired))this.socket=yield this.startTLS();if(tlsRequired&&this.socket.encrypted!==!0)throw new nats_base_client_1.NatsError("tls",nats_base_client_1.ErrorCode.ServerOptionNotAvailable);return this.connected=!0,this.setupHandlers(),this.signal.resolve(),Promise.resolve()}catch(err){if(!err)err=nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.ConnectionRefused,Error("node provided an undefined error!"));let{code}=err,perr=code==="ECONNREFUSED"?nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.ConnectionRefused,err):err;if(this.socket)this.socket.destroy();throw perr}})}dial(hp){let d=(0,nats_base_client_1.deferred)(),dialError,socket=(0,net_1.createConnection)(hp.port,hp.hostname,()=>{d.resolve(socket),socket.removeAllListeners()});return socket.on("error",(err)=>{dialError=err}),socket.on("close",()=>{socket.removeAllListeners(),d.reject(dialError)}),socket.setNoDelay(!0),d}get isClosed(){return this.done}close(err){return this._closed(err,!1)}peekInfo(){let d=(0,nats_base_client_1.deferred)(),peekError;return this.socket.on("data",(frame)=>{this.yields.push(frame);let t=nats_base_client_1.DataBuffer.concat(...this.yields),pm=(0,nats_base_client_1.extractProtocolMessage)(t);if(pm!=="")try{let m=nats_base_client_1.INFO.exec(pm);if(!m)throw Error("unexpected response from server");let info=JSON.parse(m[1]);d.resolve(info)}catch(err){d.reject(err)}finally{this.socket.removeAllListeners()}}),this.socket.on("error",(err)=>{peekError=err}),this.socket.on("close",()=>{this.socket.removeAllListeners(),d.reject(peekError)}),d}loadFile(fn){if(!fn)return Promise.resolve();let d=(0,nats_base_client_1.deferred)();try{if(fn=resolve4(fn),!existsSync14(fn))d.reject(Error(`${fn} doesn't exist`));readFile4(fn,(err,data)=>{if(err)return d.reject(err);d.resolve(data)})}catch(err){d.reject(err)}return d}loadClientCerts(){return __awaiter(this,void 0,void 0,function*(){let tlsOpts={},{certFile,cert,caFile,ca,keyFile,key}=this.options.tls;try{if(certFile){let data=yield this.loadFile(certFile);if(data)tlsOpts.cert=data}else if(cert)tlsOpts.cert=cert;if(keyFile){let data=yield this.loadFile(keyFile);if(data)tlsOpts.key=data}else if(key)tlsOpts.key=key;if(caFile){let data=yield this.loadFile(caFile);if(data)tlsOpts.ca=[data]}else if(ca)tlsOpts.ca=ca;return Promise.resolve(tlsOpts)}catch(err){return Promise.reject(err)}})}tlsFirst(hp){return __awaiter(this,void 0,void 0,function*(){let tlsError,tlsOpts={servername:this.tlsName,rejectUnauthorized:!0};if(this.socket)tlsOpts.socket=this.socket;if(typeof this.options.tls==="object")try{let certOpts=(yield this.loadClientCerts())||{};tlsOpts=(0,util_1.extend)(tlsOpts,this.options.tls,certOpts)}catch(err){return Promise.reject(new nats_base_client_1.NatsError(err.message,nats_base_client_1.ErrorCode.Tls,err))}let d=(0,nats_base_client_1.deferred)();try{let tlsSocket=(0,tls_1.connect)(hp.port,hp.hostname,tlsOpts,()=>{tlsSocket.removeAllListeners(),d.resolve(tlsSocket)});tlsSocket.on("error",(err)=>{tlsError=err}),tlsSocket.on("secureConnect",()=>{if(tlsOpts.rejectUnauthorized===!1)return;if(!tlsSocket.authorized)throw tlsSocket.authorizationError}),tlsSocket.on("close",()=>{d.reject(tlsError),tlsSocket.removeAllListeners()}),tlsSocket.setNoDelay(!0)}catch(err){d.reject(nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.Tls,err))}return d})}startTLS(){return __awaiter(this,void 0,void 0,function*(){let tlsError,tlsOpts={socket:this.socket,servername:this.tlsName,rejectUnauthorized:!0};if(typeof this.options.tls==="object")try{let certOpts=(yield this.loadClientCerts())||{};tlsOpts=(0,util_1.extend)(tlsOpts,this.options.tls,certOpts)}catch(err){return Promise.reject(new nats_base_client_1.NatsError(err.message,nats_base_client_1.ErrorCode.Tls,err))}let d=(0,nats_base_client_1.deferred)();try{let tlsSocket=(0,tls_1.connect)(tlsOpts,()=>{tlsSocket.removeAllListeners(),d.resolve(tlsSocket)});tlsSocket.on("error",(err)=>{tlsError=err}),tlsSocket.on("secureConnect",()=>{if(tlsOpts.rejectUnauthorized===!1)return;if(!tlsSocket.authorized)throw tlsSocket.authorizationError}),tlsSocket.on("close",()=>{d.reject(tlsError),tlsSocket.removeAllListeners()})}catch(err){d.reject(nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.Tls,err))}return d})}setupHandlers(){let connError;this.socket.on("data",(frame)=>{return this.yields.push(frame),this.signal.resolve()}),this.socket.on("error",(err)=>{connError=err}),this.socket.on("end",()=>{var _a,_b;if((_a=this.socket)===null||_a===void 0?void 0:_a.destroyed)return;(_b=this.socket)===null||_b===void 0||_b.write(new Uint8Array(0),()=>{var _a2;(_a2=this.socket)===null||_a2===void 0||_a2.end()})}),this.socket.on("close",()=>{this._closed(connError,!1)})}[Symbol.asyncIterator](){return this.iterate()}iterate(){return __asyncGenerator(this,arguments,function*(){let debug=this.options.debug;while(!0){if(this.yields.length===0)yield __await(this.signal);let yields=this.yields;this.yields=[];for(let i2=0;i2<yields.length;i2++){if(debug)console.info(`> ${(0,nats_base_client_1.render)(yields[i2])}`);yield yield __await(yields[i2])}if(this.done)break;else if(this.yields.length===0)yields.length=0,this.yields=yields,this.signal=(0,nats_base_client_1.deferred)()}})}discard(){}disconnect(){this._closed(void 0,!0).then().catch()}isEncrypted(){return this.socket instanceof tls_1.TLSSocket}_send(frame){if(this.isClosed||this.socket===void 0)return Promise.resolve();if(this.options.debug)console.info(`< ${(0,nats_base_client_1.render)(frame)}`);let d=(0,nats_base_client_1.deferred)();try{this.socket.write(frame,(err)=>{if(err){if(this.options.debug)console.error(`!!! ${(0,nats_base_client_1.render)(frame)}: ${err}`);return d.reject(err)}return d.resolve()})}catch(err){if(this.options.debug)console.error(`!!! ${(0,nats_base_client_1.render)(frame)}: ${err}`);d.reject(err)}return d}send(frame){this._send(frame).catch((_err)=>{})}_closed(err_1){return __awaiter(this,arguments,void 0,function*(err,internal=!0){if(!this.connected)return;if(this.done)return;if(this.closeError=err,!err&&this.socket&&internal)try{yield this._send(new TextEncoder().encode(""))}catch(err2){if(this.options.debug)console.log("transport close terminated with an error",err2)}try{if(this.socket)this.socket.removeAllListeners(),this.socket.destroy(),this.socket=void 0}catch(err2){console.log(err2)}this.done=!0,this.closedNotification.resolve(this.closeError)})}closed(){return this.closedNotification}}exports.NodeTransport=NodeTransport;function nodeResolveHost(s){return __awaiter(this,void 0,void 0,function*(){let a=(0,nats_base_client_1.deferred)(),aaaa=(0,nats_base_client_1.deferred)();dns.resolve4(s,(err,records)=>{if(err)a.resolve(err);else a.resolve(records)}),dns.resolve6(s,(err,records)=>{if(err)aaaa.resolve(err);else aaaa.resolve(records)});let ips=[],da=yield a;if(Array.isArray(da))ips.push(...da);let daaaa=yield aaaa;if(Array.isArray(daaaa))ips.push(...daaaa);if(ips.length===0)ips.push(s);return ips})}});var require_connect=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.connect=connect;var node_transport_1=require_node_transport(),nats_base_client_1=require_nats_base_client();function connect(opts={}){return(0,nats_base_client_1.setTransportFactory)({factory:()=>{return new node_transport_1.NodeTransport},dnsResolveFn:node_transport_1.nodeResolveHost}),nats_base_client_1.NatsConnectionImpl.connect(opts)}});var require_mod3=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.consumerOpts=exports.StoreCompression=exports.StorageType=exports.RetentionPolicy=exports.RepublishHeaders=exports.ReplayPolicy=exports.KvWatchInclude=exports.JsHeaders=exports.DiscardPolicy=exports.DirectMsgHeaders=exports.DeliverPolicy=exports.ConsumerEvents=exports.ConsumerDebugEvents=exports.AdvisoryKind=exports.AckPolicy=exports.isHeartbeatMsg=exports.isFlowControlMsg=exports.checkJsError=void 0;var internal_mod_1=require_internal_mod2();Object.defineProperty(exports,"checkJsError",{enumerable:!0,get:function(){return internal_mod_1.checkJsError}});Object.defineProperty(exports,"isFlowControlMsg",{enumerable:!0,get:function(){return internal_mod_1.isFlowControlMsg}});Object.defineProperty(exports,"isHeartbeatMsg",{enumerable:!0,get:function(){return internal_mod_1.isHeartbeatMsg}});var internal_mod_2=require_internal_mod2();Object.defineProperty(exports,"AckPolicy",{enumerable:!0,get:function(){return internal_mod_2.AckPolicy}});Object.defineProperty(exports,"AdvisoryKind",{enumerable:!0,get:function(){return internal_mod_2.AdvisoryKind}});Object.defineProperty(exports,"ConsumerDebugEvents",{enumerable:!0,get:function(){return internal_mod_2.ConsumerDebugEvents}});Object.defineProperty(exports,"ConsumerEvents",{enumerable:!0,get:function(){return internal_mod_2.ConsumerEvents}});Object.defineProperty(exports,"DeliverPolicy",{enumerable:!0,get:function(){return internal_mod_2.DeliverPolicy}});Object.defineProperty(exports,"DirectMsgHeaders",{enumerable:!0,get:function(){return internal_mod_2.DirectMsgHeaders}});Object.defineProperty(exports,"DiscardPolicy",{enumerable:!0,get:function(){return internal_mod_2.DiscardPolicy}});Object.defineProperty(exports,"JsHeaders",{enumerable:!0,get:function(){return internal_mod_2.JsHeaders}});Object.defineProperty(exports,"KvWatchInclude",{enumerable:!0,get:function(){return internal_mod_2.KvWatchInclude}});Object.defineProperty(exports,"ReplayPolicy",{enumerable:!0,get:function(){return internal_mod_2.ReplayPolicy}});Object.defineProperty(exports,"RepublishHeaders",{enumerable:!0,get:function(){return internal_mod_2.RepublishHeaders}});Object.defineProperty(exports,"RetentionPolicy",{enumerable:!0,get:function(){return internal_mod_2.RetentionPolicy}});Object.defineProperty(exports,"StorageType",{enumerable:!0,get:function(){return internal_mod_2.StorageType}});Object.defineProperty(exports,"StoreCompression",{enumerable:!0,get:function(){return internal_mod_2.StoreCompression}});var types_1=require_types2();Object.defineProperty(exports,"consumerOpts",{enumerable:!0,get:function(){return types_1.consumerOpts}})});var require_mod4=__commonJS((exports)=>{var __createBinding=exports&&exports.__createBinding||(Object.create?function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))desc={enumerable:!0,get:function(){return m[k]}};Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}),__exportStar=exports&&exports.__exportStar||function(m,exports2){for(var p in m)if(p!=="default"&&!Object.prototype.hasOwnProperty.call(exports2,p))__createBinding(exports2,m,p)};Object.defineProperty(exports,"__esModule",{value:!0});exports.connect=void 0;if(typeof TextEncoder>"u"){let{TextEncoder:TextEncoder2,TextDecoder:TextDecoder2}=__require("util");global.TextEncoder=TextEncoder2,global.TextDecoder=TextDecoder2}if(typeof globalThis.crypto>"u"){let c=__require("crypto");global.crypto=c.webcrypto}if(typeof globalThis.ReadableStream>"u"){let chunks=process.versions.node.split(".");if(parseInt(chunks[0])>=16){let streams=__require("stream/web");global.ReadableStream=streams.ReadableStream}}var connect_1=require_connect();Object.defineProperty(exports,"connect",{enumerable:!0,get:function(){return connect_1.connect}});__exportStar(require_mod2(),exports);__exportStar(require_mod3(),exports)});var exports_nats_client={};__export(exports_nats_client,{subscribe:()=>subscribe,publish:()=>publish,isAvailable:()=>isAvailable,close:()=>close,_resetForTesting:()=>_resetForTesting});function getNatsUrl(){return process.env.GENIE_NATS_URL||"nats://localhost:4222"}function warnOnce(key,message){if(!state[key])state[key]=!0,console.warn(`[genie:nats] ${message}`)}async function importNats(){try{return await Promise.resolve().then(() => __toESM(require_mod4(),1))}catch{return warnOnce("warnedMissingPackage","nats package not installed \u2014 real-time features disabled"),null}}async function ensureConnection(){if(state.connection&&!state.connection.isClosed())return resetIdleTimer(),!0;if(state.connecting)return state.connecting;return state.connecting=(async()=>{try{let natsModule=await importNats();if(!natsModule)return!1;return state.connection=await natsModule.connect({servers:getNatsUrl(),maxReconnectAttempts:2,reconnectTimeWait:500,timeout:2000}),state.codec=natsModule.JSONCodec(),state.warnedUnavailable=!1,resetIdleTimer(),!0}catch{return state.connection=null,state.codec=null,warnOnce("warnedUnavailable",`NATS not available at ${getNatsUrl()}`),!1}finally{state.connecting=null}})(),state.connecting}function resetIdleTimer(){if(state.idleTimer)clearTimeout(state.idleTimer);if(state.activeSubscriptions>0)return;state.idleTimer=setTimeout(()=>{if(state.activeSubscriptions===0)close().catch(()=>{})},500)}async function publish(subject,data){if(!await ensureConnection()||!state.connection||!state.codec)return;try{state.connection.publish(subject,state.codec.encode(data))}catch{}resetIdleTimer()}async function subscribe(subject,callback){let noop={unsubscribe:()=>{}};if(!await ensureConnection()||!state.connection||!state.codec)return noop;try{let sub=state.connection.subscribe(subject),codec=state.codec;if(state.activeSubscriptions++,state.idleTimer)clearTimeout(state.idleTimer),state.idleTimer=null;return(async()=>{try{for await(let msg of sub)try{callback(msg.subject,codec.decode(msg.data))}catch{}}catch{}})(),{unsubscribe:()=>{try{sub.unsubscribe()}catch{}state.activeSubscriptions=Math.max(0,state.activeSubscriptions-1),resetIdleTimer()}}}catch{return noop}}async function isAvailable(){return ensureConnection()}async function close(){if(state.idleTimer)clearTimeout(state.idleTimer),state.idleTimer=null;if(state.connection){try{await state.connection.drain()}catch{try{await state.connection.close()}catch{}}state.connection=null,state.codec=null}}function _resetForTesting(){if(state.connection=null,state.codec=null,state.connecting=null,state.warnedUnavailable=!1,state.warnedMissingPackage=!1,state.activeSubscriptions=0,state.idleTimer)clearTimeout(state.idleTimer);state.idleTimer=null}var state;var init_nats_client=__esm(()=>{state={connection:null,codec:null,connecting:null,warnedUnavailable:!1,warnedMissingPackage:!1,activeSubscriptions:0,idleTimer:null}});function isBlockingEvent(event){return BLOCKING_EVENTS.has(event)}var DISPATCHED_EVENTS,BLOCKING_EVENTS;var init_types2=__esm(()=>{DISPATCHED_EVENTS=["PreToolUse","PostToolUse","SessionStart","SessionEnd","TeammateIdle","TaskCompleted"],BLOCKING_EVENTS=new Set(["PreToolUse","UserPromptSubmit","TeammateIdle","TaskCompleted","PermissionRequest"])});function buildLayoutCommand(windowTarget,mode="mosaic"){return`select-layout -t '${windowTarget}' ${mode==="vertical"?"even-horizontal":"tiled"}`}function resolveLayoutMode(layoutFlag){if(layoutFlag==="vertical")return"vertical";return"mosaic"}function stripAnsi(str2){return str2.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,"")}function matchPatterns(content,patterns){let cleanContent=stripAnsi(content),matches=[];for(let pattern of patterns){let regex=new RegExp(pattern.pattern.source,pattern.pattern.flags||"g"),match=regex.exec(cleanContent);while(match!==null){if(matches.push({type:pattern.type,match,extracted:pattern.extract?pattern.extract(match):void 0}),!pattern.pattern.flags?.includes("g"))break;match=regex.exec(cleanContent)}}return matches}function hasMatch(content,patterns){return matchPatterns(content,patterns).length>0}function getFirstMatch(content,patterns){let matches=matchPatterns(content,patterns);return matches.length>0?matches[0]:null}var permissionPatterns,questionPatterns,errorPatterns,completionPatterns,workingPatterns,idlePatterns,toolUsePatterns;var init_patterns=__esm(()=>{permissionPatterns=[{type:"bash_permission",pattern:/Allow (?:Bash|bash|command|shell).*\?\s*(?:\[([YyNn])\/([YyNn])\])?/i,extract:(match)=>({default:match[1]||"y"})},{type:"file_permission",pattern:/Allow (?:Edit|Write|Read|file|reading|writing|editing).*\?\s*(?:\[([YyNn])\/([YyNn])\])?/i,extract:(match)=>({default:match[1]||"y"})},{type:"mcp_permission",pattern:/Allow (?:MCP|mcp|tool).*\?\s*(?:\[([YyNn])\/([YyNn])\])?/i,extract:(match)=>({default:match[1]||"y"})},{type:"generic_permission",pattern:/^(?:Allow|Confirm|Approve)\s+(?:this|the|once|always)?\s*(?:\w+)?\s*\?\s*(?:\[([YyNn])\/([YyNn])\])?/im,extract:(match)=>({default:match[1]||"y"})},{type:"claude_code_yes_no",pattern:/(?:Yes|No)\s*$/m},{type:"claude_code_permission_block",pattern:/(?:Allow|Run|Execute)\s+(?:once|always)/i}],questionPatterns=[{type:"numbered_options",pattern:/\[(\d+)\]\s+(.+?)(?=\[(\d+)\]|$)/g,extract:(match)=>({number:match[1],option:match[2].trim()})},{type:"lettered_options",pattern:/\(([a-z])\)\s+(.+?)(?=\([a-z]\)|$)/gi,extract:(match)=>({letter:match[1],option:match[2].trim()})},{type:"yes_no_question",pattern:/\?\s*\[([YyNn])\/([YyNn])\]\s*$/,extract:(match)=>({default:match[1]})},{type:"claude_code_numbered_options",pattern:/(?:\u276F|>)?\s*(\d+)\.\s+(.+?)(?:\n|$)/g,extract:(match)=>({number:match[1],option:match[2].trim()})},{type:"claude_code_plan_approval",pattern:/Would you like to proceed\?/i}],errorPatterns=[{type:"error",pattern:/(?:^|\n)\s*(?:Error|ERROR|error):\s*(.+)/,extract:(match)=>({message:match[1]})},{type:"failed",pattern:/(?:^|\n)\s*(?:Failed|FAILED|failed):\s*(.+)/,extract:(match)=>({message:match[1]})},{type:"exception",pattern:/(?:^|\n)\s*(?:Exception|EXCEPTION|Uncaught|Unhandled):\s*(.+)/,extract:(match)=>({message:match[1]})},{type:"api_error",pattern:/(?:API|api)\s+(?:error|Error|ERROR):\s*(.+)/,extract:(match)=>({message:match[1]})}],completionPatterns=[{type:"checkmark",pattern:/(?:\u2713|\u2714|\u2611\uFE0E)/},{type:"success_message",pattern:/(?:Successfully|Completed|Done|Finished|Created|Updated|Saved)/i},{type:"task_complete",pattern:/(?:task|operation|process)\s+(?:complete|completed|finished|done)/i}],workingPatterns=[{type:"thinking",pattern:/(?:Thinking|thinking|Processing|processing)\.\.\./},{type:"spinner",pattern:/[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F\u28FE\u28FD\u28FB\u28BF\u287F\u28DF\u28EF\u28F7]/},{type:"loading",pattern:/(?:Loading|loading|Working|working)\.\.\./},{type:"claude_code_working",pattern:/(?:\uD83D\uDEE0\uFE0F|\uD83D\uDD27|\u2699\uFE0F)\s*(?:Read|Edit|Write|Bash|Glob|Grep|Task)/u},{type:"claude_code_streaming",pattern:/\u258C$/},{type:"claude_code_propagating",pattern:/Propagating\u2026/}],idlePatterns=[{type:"claude_prompt",pattern:/(?:^|\n)\s*>\s*$/},{type:"claude_code_prompt",pattern:/\u276F\s*(?!\d\.)/},{type:"claude_code_input_line",pattern:/\u276F\s*.+\n\u2500+\n/},{type:"idle_indicator",pattern:/\|\s*idle\s*$/i},{type:"input_prompt",pattern:/(?:^|\n)(?:Enter|Input|Type|Provide).*:\s*$/i}],toolUsePatterns=[{type:"run_command",pattern:/(?:Run|Running|Executing)\s+(?:command|bash):\s*(.+)/i,extract:(match)=>({command:match[1]})},{type:"read_file",pattern:/(?:Read|Reading)\s+(?:file):\s*(.+)/i,extract:(match)=>({file:match[1]})},{type:"write_file",pattern:/(?:Write|Writing|Edit|Editing)\s+(?:file|to):\s*(.+)/i,extract:(match)=>({file:match[1]})},{type:"search",pattern:/(?:Search|Searching|Grep|Glob)(?:ing)?:\s*(.+)/i,extract:(match)=>({query:match[1]})}]});function detectQuestionState(questionMatches,hasPlanApproval,baseState){if(questionMatches.length===0&&!hasPlanApproval)return null;let menuOptions=questionMatches.filter((m)=>m.type==="claude_code_numbered_options"&&m.extracted?.option).map((m)=>m.extracted?.option).filter((o)=>o!==void 0);if(menuOptions.length>=2||hasPlanApproval)return{...baseState,type:"question",options:menuOptions.length>0?menuOptions:void 0,detail:hasPlanApproval?"plan_approval":void 0,confidence:0.85};let otherOptions=questionMatches.filter((m)=>m.extracted?.option&&m.type!=="claude_code_numbered_options").map((m)=>m.extracted?.option).filter((o)=>o!==void 0);if(otherOptions.length>=2)return{...baseState,type:"question",options:otherOptions,confidence:0.85};return null}function detectState(output,options={}){let{linesToAnalyze=50,minConfidence=0.3}=options,lines=output.split(`
|
|
130
|
-
`)
|
|
131
|
-
`),
|
|
132
|
-
`)),questionMatches=matchPatterns(cleanMenuLines,questionPatterns),questionState=detectQuestionState(questionMatches,hasPlanApproval,baseState);if(questionState)return questionState;let ynMatch=questionMatches.find((m)=>m.type==="yes_no_question");if(ynMatch)return{...baseState,type:"question",options:["Yes","No"],detail:`default: ${ynMatch.extracted?.default||"y"}`,confidence:0.85};let errorMatch=getFirstMatch(cleanOutput,errorPatterns);if(errorMatch)return{...baseState,type:"error",detail:errorMatch.extracted?.message||errorMatch.match[0],confidence:0.8};let toolMatch=getFirstMatch(cleanOutput,toolUsePatterns);if(toolMatch)return{...baseState,type:"tool_use",detail:`${toolMatch.type}: ${toolMatch.extracted?.command||toolMatch.extracted?.file||toolMatch.extracted?.query||""}`,confidence:0.75};if(hasMatch(cleanOutput,workingPatterns))return{...baseState,type:"working",confidence:0.7};if(hasMatch(cleanOutput,completionPatterns))return{...baseState,type:"complete",confidence:0.6};let cleanLastLines=stripAnsi(lines.slice(-5).join(`
|
|
133
|
-
`));if(hasMatch(cleanLastLines,idlePatterns))return{...baseState,type:"idle",confidence:0.7};let trimmedLast=cleanLastLines.trim();if(trimmedLast.endsWith(">")||trimmedLast.match(/>\s*$/))return{...baseState,type:"idle",detail:"prompt detected",confidence:0.65};return{...baseState,type:"unknown",confidence:minConfidence}}var init_state_detector=__esm(()=>{init_patterns()});var init_orchestrator=__esm(()=>{init_patterns();init_state_detector()});async function waitForAgentReady(paneId,opts){let timeoutMs=opts?.timeoutMs??(process.env.GENIE_SPAWN_TIMEOUT_MS?Number(process.env.GENIE_SPAWN_TIMEOUT_MS):DEFAULT_SPAWN_TIMEOUT_MS),pollIntervalMs=opts?.pollIntervalMs??READINESS_POLL_INTERVAL_MS,start=Date.now();while(Date.now()-start<timeoutMs){try{let content=await capturePaneContent(paneId,50);if(content){let state2=detectState(content);if(state2.type==="idle"||state2.type==="tool_use")return{ready:!0,elapsedMs:Date.now()-start}}}catch{}await new Promise((r)=>setTimeout(r,pollIntervalMs))}return{ready:!1,elapsedMs:Date.now()-start}}var DEFAULT_SPAWN_TIMEOUT_MS=30000,READINESS_POLL_INTERVAL_MS=2000;var init_spawn_command=__esm(()=>{init_orchestrator();init_tmux()});var exports_team_manager={};__export(exports_team_manager,{validateBranchName:()=>validateBranchName,updateTeamConfig:()=>updateTeamConfig,setTeamStatus:()=>setTeamStatus,pruneStaleWorktrees:()=>pruneStaleWorktrees,listTeams:()=>listTeams2,listMembers:()=>listMembers,killTeamMembers:()=>killTeamMembers,hireAgent:()=>hireAgent,getTeam:()=>getTeam2,fireAgent:()=>fireAgent,disbandTeam:()=>disbandTeam,createTeam:()=>createTeam});import{existsSync as existsSync14}from"fs";import{mkdir as mkdir5,readFile as readFile4,readdir as readdir2,rm as rm3,unlink as unlink4,writeFile as writeFile4}from"fs/promises";import{homedir as homedir13}from"os";import path,{join as join15}from"path";var{$:$3}=globalThis.Bun;function getGenieDir2(){return process.env.GENIE_HOME??join15(homedir13(),".genie")}function teamsDir(){return join15(getGenieDir2(),"teams")}function safeFileName(name){return name.replace(/\//g,"--")}function teamFilePath(name){let safeName=safeFileName(path.basename(name)===name?name:name);return join15(teamsDir(),`${safeName}.json`)}function getWorktreeBase(repoPath){let base=loadGenieConfigSync().terminal?.worktreeBase;if(base&&base!==".worktrees"){if(path.isAbsolute(base))return base;return join15(repoPath,base)}let projectName=path.basename(repoPath);return join15(getGenieDir2(),"worktrees",projectName)}function validateBranchName(name){let errors3=[];if(/\s/.test(name))errors3.push("contains spaces");if(name.includes(".."))errors3.push('contains ".."');if(name.includes("~"))errors3.push('contains "~"');if(name.includes("^"))errors3.push('contains "^"');if(name.includes(":"))errors3.push('contains ":"');if(name.includes("?"))errors3.push('contains "?"');if(name.includes("*"))errors3.push('contains "*"');if(name.includes("["))errors3.push('contains "["');if(name.includes("\\"))errors3.push('contains "\\"');if(/[\x00-\x1f\x7f]/.test(name))errors3.push("contains control characters");if(name.endsWith(".lock"))errors3.push('ends with ".lock"');if(name.endsWith("/"))errors3.push('ends with "/"');if(name.endsWith("."))errors3.push('ends with "."');if(name.startsWith("-"))errors3.push('starts with "-"');if(errors3.length>0)throw Error(`Invalid team name '${name}': must be a valid git branch name (${errors3.join(", ")})`)}async function killWorkersByName(agentName,teamName){let matches=(await list()).filter((w)=>(w.role===agentName||w.id===agentName)&&(!teamName||w.team===teamName));for(let w of matches){try{if(w.paneId&&w.paneId!=="inline"){let{execSync:execSync3}=__require("child_process");execSync3(`tmux kill-pane -t ${w.paneId}`,{stdio:"ignore"})}}catch{}await unregister(w.id)}}async function ensureWorktree(repoPath,branchName,worktreePath,baseBranch){try{await $3`git -C ${repoPath} fetch origin ${baseBranch}`.quiet()}catch{}if(await mkdir5(path.dirname(worktreePath),{recursive:!0}),existsSync14(worktreePath))return;let branchExists=!1;try{await $3`git -C ${repoPath} rev-parse --verify ${branchName}`.quiet(),branchExists=!0}catch{if(!branchExists)try{await $3`git -C ${repoPath} branch ${branchName} origin/${baseBranch}`.quiet()}catch{try{await $3`git -C ${repoPath} branch ${branchName} ${baseBranch}`.quiet()}catch{await $3`git -C ${repoPath} branch ${branchName}`.quiet()}}}await $3`git clone --shared --branch ${branchName} ${repoPath} ${worktreePath}`.quiet();try{let userName=(await $3`git -C ${repoPath} config user.name`.quiet()).text().trim(),userEmail=(await $3`git -C ${repoPath} config user.email`.quiet()).text().trim();if(userName)await $3`git -C ${worktreePath} config user.name ${userName}`.quiet();if(userEmail)await $3`git -C ${worktreePath} config user.email ${userEmail}`.quiet()}catch{}}async function createTeam(name,repo,baseBranch="dev"){validateBranchName(name);let repoPath=path.resolve(repo),dir=teamsDir();await mkdir5(dir,{recursive:!0});let filePath=teamFilePath(name);if(existsSync14(filePath)){let content=await readFile4(filePath,"utf-8");return JSON.parse(content)}let worktreeBase=getWorktreeBase(repoPath),worktreePath=join15(worktreeBase,name);await ensureWorktree(repoPath,name,worktreePath,baseBranch);let now=new Date().toISOString(),config={name,repo:repoPath,baseBranch,worktreePath,members:[],status:"in_progress",createdAt:now};if(isInsideClaudeCode()){config.nativeTeamsEnabled=!0;try{let result=await registerAsTeamLead(name);config.nativeTeamParentSessionId=result.sessionId}catch{}}return await writeFile4(filePath,JSON.stringify(config,null,2)),config}async function hireAgent(teamName,agentName){let config=await getTeam2(teamName);if(!config)throw Error(`Team "${teamName}" not found.`);let added;if(agentName==="council")added=BUILTIN_COUNCIL_MEMBERS.map((m)=>m.name).filter((n)=>!config.members.includes(n)),config.members.push(...added);else{if(config.members.includes(agentName))return[];config.members.push(agentName),added=[agentName]}let filePath=teamFilePath(teamName);return await writeFile4(filePath,JSON.stringify(config,null,2)),added}async function fireAgent(teamName,agentName){let config=await getTeam2(teamName);if(!config)throw Error(`Team "${teamName}" not found.`);let idx=config.members.indexOf(agentName);if(idx===-1)return!1;config.members.splice(idx,1);let filePath=teamFilePath(teamName);await writeFile4(filePath,JSON.stringify(config,null,2));try{await killWorkersByName(agentName)}catch{}return!0}async function disbandTeam(teamName){let config=await getTeam2(teamName);if(!config)return!1;if(config.nativeTeamsEnabled)try{await deleteNativeTeam(teamName)}catch{}for(let member of config.members)try{await killWorkersByName(member,teamName)}catch{}if(config.worktreePath&&existsSync14(config.worktreePath))try{await rm3(config.worktreePath,{recursive:!0,force:!0})}catch{}let filePath=teamFilePath(teamName);try{await unlink4(filePath)}catch{return!1}return await pruneStaleWorktrees(config.repo),!0}async function pruneStaleWorktrees(_repoPath){let dir=teamsDir(),files;try{files=await readdir2(dir)}catch{return}for(let file of files){if(!file.endsWith(".json"))continue;try{let content=await readFile4(join15(dir,file),"utf-8"),config=JSON.parse(content);if(config.worktreePath&&!existsSync14(config.worktreePath))await unlink4(join15(dir,file))}catch{}}}async function updateTeamConfig(name,config){let filePath=teamFilePath(name);await writeFile4(filePath,JSON.stringify(config,null,2))}async function getTeam2(name){try{let content=await readFile4(teamFilePath(name),"utf-8");return JSON.parse(content)}catch{return null}}async function listTeams2(){let dir=teamsDir();try{let files=await readdir2(dir),teams=[];for(let file of files){if(!file.endsWith(".json"))continue;try{let content=await readFile4(join15(dir,file),"utf-8");teams.push(JSON.parse(content))}catch{}}return teams}catch{return[]}}async function listMembers(teamName){let config=await getTeam2(teamName);if(!config)return null;return config.members}async function killTeamMembers(teamName){let config=await getTeam2(teamName);if(!config)return;for(let member of config.members)try{await killWorkersByName(member,teamName)}catch{}}async function setTeamStatus(teamName,status){let filePath=teamFilePath(teamName),release=await acquireLock(filePath);try{let config=await getTeam2(teamName);if(!config)throw Error(`Team "${teamName}" not found.`);config.status=status,await writeFile4(filePath,JSON.stringify(config,null,2))}finally{await release()}}var init_team_manager=__esm(()=>{init_agent_registry();init_builtin_agents();init_claude_native_teams();init_file_lock();init_genie_config2()});var exports_inject={};__export(exports_inject,{isTeamHooked:()=>isTeamHooked,injectTeamHooks:()=>injectTeamHooks});import{existsSync as existsSync15}from"fs";import{mkdir as mkdir6,readFile as readFile5,writeFile as writeFile5}from"fs/promises";import{homedir as homedir14}from"os";import{join as join16}from"path";function claudeConfigDir2(){return process.env.CLAUDE_CONFIG_DIR??join16(homedir14(),".claude")}function teamSettingsPath(teamName){let sanitized=teamName.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase();return join16(claudeConfigDir2(),"teams",sanitized,"settings.json")}function buildHooksConfig(){let hooks={};for(let event of DISPATCHED_EVENTS)hooks[event]=[{hooks:[{type:"command",command:DISPATCH_COMMAND,timeout:DISPATCH_TIMEOUT}]}];return hooks}async function injectIntoFile(settingsPath){let settings={};if(existsSync15(settingsPath))try{let content=await readFile5(settingsPath,"utf-8");settings=JSON.parse(content)}catch{}let hooksConfig=buildHooksConfig(),existingHooks=settings.hooks;if(existingHooks){if(DISPATCHED_EVENTS.every((event)=>{return existingHooks[event]?.some((m)=>m.hooks?.some((h)=>h.command===DISPATCH_COMMAND))}))return!1}let mergedHooks=existingHooks?{...existingHooks}:{};for(let event of DISPATCHED_EVENTS){let genieEntry=hooksConfig[event][0],existingEntries=mergedHooks[event]??[];if(!existingEntries.some((m)=>m.hooks?.some((h)=>h.command===DISPATCH_COMMAND)))mergedHooks[event]=[...existingEntries,genieEntry]}settings.hooks=mergedHooks;let dir=join16(settingsPath,"..");return await mkdir6(dir,{recursive:!0}),await writeFile5(settingsPath,JSON.stringify(settings,null,2)),!0}async function injectTeamHooks(teamName){let path2=teamSettingsPath(teamName);return injectIntoFile(path2)}async function isTeamHooked(teamName){let path2=teamSettingsPath(teamName);if(!existsSync15(path2))return!1;try{let content=await readFile5(path2,"utf-8"),hooks=JSON.parse(content).hooks;if(!hooks)return!1;return DISPATCHED_EVENTS.every((event)=>{return hooks[event]?.some((m)=>m.hooks?.some((h)=>h.command===DISPATCH_COMMAND))})}catch{return!1}}var DISPATCH_COMMAND="genie hook dispatch",DISPATCH_TIMEOUT=15;var init_inject=__esm(()=>{init_types2()});var exports_idle_timeout={};__export(exports_idle_timeout,{suspendWorker:()=>suspendWorker,getIdleTimeoutMs:()=>getIdleTimeoutMs,checkIdleWorkers:()=>checkIdleWorkers,WATCHDOG_POLL_INTERVAL_MS:()=>WATCHDOG_POLL_INTERVAL_MS});function getIdleTimeoutMs(){let env=process.env.GENIE_IDLE_TIMEOUT_MS;if(env!==void 0){if(env==="")return DEFAULT_IDLE_TIMEOUT_MS;let parsed=Number(env);if(!Number.isNaN(parsed)&&parsed>=0)return parsed}return DEFAULT_IDLE_TIMEOUT_MS}async function suspendWorker(workerId,deps=defaultDeps){let worker=await deps.registryGet(workerId);if(!worker)return!1;if(worker.state==="suspended")return!0;if(worker.paneId&&worker.paneId!=="inline")try{await deps.executeTmux(`kill-pane -t '${worker.paneId}'`)}catch{}return await deps.registryUpdate(workerId,{state:"suspended",suspendedAt:new Date().toISOString()}),!0}async function checkIdleWorkers(deps=defaultDeps){let timeoutMs=getIdleTimeoutMs();if(timeoutMs===0)return[];let workers=await deps.registryList(),suspended=[];for(let w of workers){if(w.state!=="idle")continue;if(Date.now()-new Date(w.lastStateChange).getTime()<timeoutMs)continue;if(!await deps.isPaneAlive(w.paneId)){await deps.registryUpdate(w.id,{state:"suspended",suspendedAt:new Date().toISOString()}),suspended.push(w.id);continue}if(await suspendWorker(w.id,deps))suspended.push(w.id)}return suspended}var defaultDeps,DEFAULT_IDLE_TIMEOUT_MS=1800000,WATCHDOG_POLL_INTERVAL_MS=60000;var init_idle_timeout=__esm(()=>{init_agent_registry();init_tmux();defaultDeps={registryGet:get,registryList:list,registryUpdate:update,executeTmux:executeTmux2,isPaneAlive}});import{readdirSync as readdirSync4}from"fs";import{join as join17}from"path";function getMigrationsDir(){return join17(import.meta.dir,"..","db","migrations")}async function loadMigrationFiles(){let candidates=[getMigrationsDir(),join17(process.cwd(),"src","db","migrations")];for(let dir of candidates)try{let files=readdirSync4(dir).filter((f)=>f.endsWith(".sql")).sort();if(files.length===0)continue;let migrations=[];for(let file of files){let content=await Bun.file(join17(dir,file)).text();migrations.push({name:file.replace(/\.sql$/,""),sql:content})}return migrations}catch{}return[]}async function ensureMigrationsTable(sql){await sql`
|
|
129
|
+
`}}exports.Metric=Metric;class Bench{constructor(nc,opts={msgs:1e5,size:128,subject:"",asyncRequests:!1,pub:!1,sub:!1,req:!1,rep:!1}){if(this.nc=nc,this.callbacks=opts.callbacks||!1,this.msgs=opts.msgs||0,this.size=opts.size||0,this.subject=opts.subject||nuid_1.nuid.next(),this.asyncRequests=opts.asyncRequests||!1,this.pub=opts.pub||!1,this.sub=opts.sub||!1,this.req=opts.req||!1,this.rep=opts.rep||!1,this.perf=new util_1.Perf,this.payload=this.size?new Uint8Array(this.size):types_1.Empty,!this.pub&&!this.sub&&!this.req&&!this.rep)throw Error("no bench option selected")}run(){return __awaiter(this,void 0,void 0,function*(){if(this.nc.closed().then((err)=>{if(err)throw new core_1.NatsError(`bench closed with an error: ${err.message}`,core_1.ErrorCode.Unknown,err)}),this.callbacks)yield this.runCallbacks();else yield this.runAsync();return this.processMetrics()})}processMetrics(){let nc=this.nc,{lang,version}=nc.protocol.transport;if(this.pub&&this.sub)this.perf.measure("pubsub","pubStart","subStop");if(this.req&&this.rep)this.perf.measure("reqrep","reqStart","reqStop");let measures=this.perf.getEntries(),pubsub=measures.find((m)=>m.name==="pubsub"),reqrep=measures.find((m)=>m.name==="reqrep"),req=measures.find((m)=>m.name==="req"),rep=measures.find((m)=>m.name==="rep"),pub=measures.find((m)=>m.name==="pub"),sub=measures.find((m)=>m.name==="sub"),stats=this.nc.stats(),metrics=[];if(pubsub){let{name,duration}=pubsub,m=new Metric(name,duration);m.msgs=this.msgs*2,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(reqrep){let{name,duration}=reqrep,m=new Metric(name,duration);m.msgs=this.msgs*2,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(pub){let{name,duration}=pub,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(sub){let{name,duration}=sub,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.inBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(rep){let{name,duration}=rep,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}if(req){let{name,duration}=req,m=new Metric(name,duration);m.msgs=this.msgs,m.bytes=stats.inBytes+stats.outBytes,m.lang=lang,m.version=version,m.payload=this.payload.length,metrics.push(m)}return metrics}runCallbacks(){return __awaiter(this,void 0,void 0,function*(){let jobs=[];if(this.sub){let d=(0,util_1.deferred)();jobs.push(d);let i2=0;this.nc.subscribe(this.subject,{max:this.msgs,callback:()=>{if(i2++,i2===1)this.perf.mark("subStart");if(i2===this.msgs)this.perf.mark("subStop"),this.perf.measure("sub","subStart","subStop"),d.resolve()}})}if(this.rep){let d=(0,util_1.deferred)();jobs.push(d);let i2=0;this.nc.subscribe(this.subject,{max:this.msgs,callback:(_,m)=>{if(m.respond(this.payload),i2++,i2===1)this.perf.mark("repStart");if(i2===this.msgs)this.perf.mark("repStop"),this.perf.measure("rep","repStart","repStop"),d.resolve()}})}if(this.pub){let job=(()=>__awaiter(this,void 0,void 0,function*(){this.perf.mark("pubStart");for(let i2=0;i2<this.msgs;i2++)this.nc.publish(this.subject,this.payload);yield this.nc.flush(),this.perf.mark("pubStop"),this.perf.measure("pub","pubStart","pubStop")}))();jobs.push(job)}if(this.req){let job=(()=>__awaiter(this,void 0,void 0,function*(){if(this.asyncRequests){this.perf.mark("reqStart");let a=[];for(let i2=0;i2<this.msgs;i2++)a.push(this.nc.request(this.subject,this.payload,{timeout:20000}));yield Promise.all(a),this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}else{this.perf.mark("reqStart");for(let i2=0;i2<this.msgs;i2++)yield this.nc.request(this.subject);this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}}))();jobs.push(job)}yield Promise.all(jobs)})}runAsync(){return __awaiter(this,void 0,void 0,function*(){let jobs=[];if(this.rep){let first=!1,sub=this.nc.subscribe(this.subject,{max:this.msgs}),job=(()=>__awaiter(this,void 0,void 0,function*(){var _a,e_1,_b,_c;try{for(var _d=!0,sub_1=__asyncValues(sub),sub_1_1;sub_1_1=yield sub_1.next(),_a=sub_1_1.done,!_a;_d=!0){_c=sub_1_1.value,_d=!1;let m=_c;if(!first)this.perf.mark("repStart"),first=!0;m.respond(this.payload)}}catch(e_1_1){e_1={error:e_1_1}}finally{try{if(!_d&&!_a&&(_b=sub_1.return))yield _b.call(sub_1)}finally{if(e_1)throw e_1.error}}yield this.nc.flush(),this.perf.mark("repStop"),this.perf.measure("rep","repStart","repStop")}))();jobs.push(job)}if(this.sub){let first=!1,sub=this.nc.subscribe(this.subject,{max:this.msgs}),job=(()=>__awaiter(this,void 0,void 0,function*(){var _a,e_2,_b,_c;try{for(var _d=!0,sub_2=__asyncValues(sub),sub_2_1;sub_2_1=yield sub_2.next(),_a=sub_2_1.done,!_a;_d=!0){_c=sub_2_1.value,_d=!1;let _m=_c;if(!first)this.perf.mark("subStart"),first=!0}}catch(e_2_1){e_2={error:e_2_1}}finally{try{if(!_d&&!_a&&(_b=sub_2.return))yield _b.call(sub_2)}finally{if(e_2)throw e_2.error}}this.perf.mark("subStop"),this.perf.measure("sub","subStart","subStop")}))();jobs.push(job)}if(this.pub){let job=(()=>__awaiter(this,void 0,void 0,function*(){this.perf.mark("pubStart");for(let i2=0;i2<this.msgs;i2++)this.nc.publish(this.subject,this.payload);yield this.nc.flush(),this.perf.mark("pubStop"),this.perf.measure("pub","pubStart","pubStop")}))();jobs.push(job)}if(this.req){let job=(()=>__awaiter(this,void 0,void 0,function*(){if(this.asyncRequests){this.perf.mark("reqStart");let a=[];for(let i2=0;i2<this.msgs;i2++)a.push(this.nc.request(this.subject,this.payload,{timeout:20000}));yield Promise.all(a),this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}else{this.perf.mark("reqStart");for(let i2=0;i2<this.msgs;i2++)yield this.nc.request(this.subject);this.perf.mark("reqStop"),this.perf.measure("req","reqStart","reqStop")}}))();jobs.push(job)}yield Promise.all(jobs)})}}exports.Bench=Bench;function throughput(bytes,seconds){return`${humanizeBytes(bytes/seconds)}/sec`}function msgThroughput(msgs,seconds){return`${Math.floor(msgs/seconds)} msgs/sec`}function humanizeBytes(bytes,si=!1){let base=si?1000:1024,pre=si?["k","M","G","T","P","E"]:["K","M","G","T","P","E"],post=si?"iB":"B";if(bytes<base)return`${bytes.toFixed(2)} ${post}`;let exp=parseInt(Math.log(bytes)/Math.log(base)+""),index=parseInt(exp-1+"");return`${(bytes/Math.pow(base,exp)).toFixed(2)} ${pre[index]}${post}`}function humanizeNumber(n){return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}});var require_internal_mod=__commonJS((exports)=>{var __createBinding=exports&&exports.__createBinding||(Object.create?function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))desc={enumerable:!0,get:function(){return m[k]}};Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}),__exportStar=exports&&exports.__exportStar||function(m,exports2){for(var p in m)if(p!=="default"&&!Object.prototype.hasOwnProperty.call(exports2,p))__createBinding(exports2,m,p)};Object.defineProperty(exports,"__esModule",{value:!0});exports.parseIP=exports.isIP=exports.TE=exports.TD=exports.Metric=exports.Bench=exports.writeAll=exports.readAll=exports.MAX_SIZE=exports.DenoBuffer=exports.State=exports.Parser=exports.Kind=exports.QueuedIteratorImpl=exports.StringCodec=exports.JSONCodec=exports.usernamePasswordAuthenticator=exports.tokenAuthenticator=exports.nkeyAuthenticator=exports.jwtAuthenticator=exports.credsAuthenticator=exports.RequestOne=exports.checkUnsupportedOption=exports.checkOptions=exports.buildAuthenticator=exports.DataBuffer=exports.MuxSubscription=exports.Heartbeat=exports.MsgHdrsImpl=exports.headers=exports.canonicalMIMEHeaderKey=exports.timeout=exports.render=exports.nanos=exports.millis=exports.extend=exports.delay=exports.deferred=exports.deadline=exports.collect=exports.backoff=exports.ProtocolHandler=exports.INFO=exports.Connect=exports.setTransportFactory=exports.getResolveFn=exports.MsgImpl=exports.nuid=exports.Nuid=exports.NatsConnectionImpl=void 0;exports.Subscriptions=exports.SubscriptionImpl=exports.syncIterator=exports.ServiceVerb=exports.ServiceResponseType=exports.ServiceErrorHeader=exports.ServiceErrorCodeHeader=exports.ServiceError=exports.RequestStrategy=exports.NatsError=exports.Match=exports.isNatsError=exports.Events=exports.ErrorCode=exports.DebugEvents=exports.createInbox=exports.extractProtocolMessage=exports.Empty=exports.parseSemVer=exports.compare=exports.NoopKvCodecs=exports.defaultBucketOpts=exports.Bucket=exports.Base64KeyCodec=exports.TypedSubscription=void 0;var nats_1=require_nats();Object.defineProperty(exports,"NatsConnectionImpl",{enumerable:!0,get:function(){return nats_1.NatsConnectionImpl}});var nuid_1=require_nuid();Object.defineProperty(exports,"Nuid",{enumerable:!0,get:function(){return nuid_1.Nuid}});Object.defineProperty(exports,"nuid",{enumerable:!0,get:function(){return nuid_1.nuid}});var msg_1=require_msg();Object.defineProperty(exports,"MsgImpl",{enumerable:!0,get:function(){return msg_1.MsgImpl}});var transport_1=require_transport();Object.defineProperty(exports,"getResolveFn",{enumerable:!0,get:function(){return transport_1.getResolveFn}});Object.defineProperty(exports,"setTransportFactory",{enumerable:!0,get:function(){return transport_1.setTransportFactory}});var protocol_1=require_protocol();Object.defineProperty(exports,"Connect",{enumerable:!0,get:function(){return protocol_1.Connect}});Object.defineProperty(exports,"INFO",{enumerable:!0,get:function(){return protocol_1.INFO}});Object.defineProperty(exports,"ProtocolHandler",{enumerable:!0,get:function(){return protocol_1.ProtocolHandler}});var util_1=require_util();Object.defineProperty(exports,"backoff",{enumerable:!0,get:function(){return util_1.backoff}});Object.defineProperty(exports,"collect",{enumerable:!0,get:function(){return util_1.collect}});Object.defineProperty(exports,"deadline",{enumerable:!0,get:function(){return util_1.deadline}});Object.defineProperty(exports,"deferred",{enumerable:!0,get:function(){return util_1.deferred}});Object.defineProperty(exports,"delay",{enumerable:!0,get:function(){return util_1.delay}});Object.defineProperty(exports,"extend",{enumerable:!0,get:function(){return util_1.extend}});Object.defineProperty(exports,"millis",{enumerable:!0,get:function(){return util_1.millis}});Object.defineProperty(exports,"nanos",{enumerable:!0,get:function(){return util_1.nanos}});Object.defineProperty(exports,"render",{enumerable:!0,get:function(){return util_1.render}});Object.defineProperty(exports,"timeout",{enumerable:!0,get:function(){return util_1.timeout}});var headers_1=require_headers();Object.defineProperty(exports,"canonicalMIMEHeaderKey",{enumerable:!0,get:function(){return headers_1.canonicalMIMEHeaderKey}});Object.defineProperty(exports,"headers",{enumerable:!0,get:function(){return headers_1.headers}});Object.defineProperty(exports,"MsgHdrsImpl",{enumerable:!0,get:function(){return headers_1.MsgHdrsImpl}});var heartbeats_1=require_heartbeats();Object.defineProperty(exports,"Heartbeat",{enumerable:!0,get:function(){return heartbeats_1.Heartbeat}});var muxsubscription_1=require_muxsubscription();Object.defineProperty(exports,"MuxSubscription",{enumerable:!0,get:function(){return muxsubscription_1.MuxSubscription}});var databuffer_1=require_databuffer();Object.defineProperty(exports,"DataBuffer",{enumerable:!0,get:function(){return databuffer_1.DataBuffer}});var options_1=require_options();Object.defineProperty(exports,"buildAuthenticator",{enumerable:!0,get:function(){return options_1.buildAuthenticator}});Object.defineProperty(exports,"checkOptions",{enumerable:!0,get:function(){return options_1.checkOptions}});Object.defineProperty(exports,"checkUnsupportedOption",{enumerable:!0,get:function(){return options_1.checkUnsupportedOption}});var request_1=require_request();Object.defineProperty(exports,"RequestOne",{enumerable:!0,get:function(){return request_1.RequestOne}});var authenticator_1=require_authenticator();Object.defineProperty(exports,"credsAuthenticator",{enumerable:!0,get:function(){return authenticator_1.credsAuthenticator}});Object.defineProperty(exports,"jwtAuthenticator",{enumerable:!0,get:function(){return authenticator_1.jwtAuthenticator}});Object.defineProperty(exports,"nkeyAuthenticator",{enumerable:!0,get:function(){return authenticator_1.nkeyAuthenticator}});Object.defineProperty(exports,"tokenAuthenticator",{enumerable:!0,get:function(){return authenticator_1.tokenAuthenticator}});Object.defineProperty(exports,"usernamePasswordAuthenticator",{enumerable:!0,get:function(){return authenticator_1.usernamePasswordAuthenticator}});var codec_1=require_codec();Object.defineProperty(exports,"JSONCodec",{enumerable:!0,get:function(){return codec_1.JSONCodec}});Object.defineProperty(exports,"StringCodec",{enumerable:!0,get:function(){return codec_1.StringCodec}});__exportStar(require_nkeys2(),exports);var queued_iterator_1=require_queued_iterator();Object.defineProperty(exports,"QueuedIteratorImpl",{enumerable:!0,get:function(){return queued_iterator_1.QueuedIteratorImpl}});var parser_1=require_parser();Object.defineProperty(exports,"Kind",{enumerable:!0,get:function(){return parser_1.Kind}});Object.defineProperty(exports,"Parser",{enumerable:!0,get:function(){return parser_1.Parser}});Object.defineProperty(exports,"State",{enumerable:!0,get:function(){return parser_1.State}});var denobuffer_1=require_denobuffer();Object.defineProperty(exports,"DenoBuffer",{enumerable:!0,get:function(){return denobuffer_1.DenoBuffer}});Object.defineProperty(exports,"MAX_SIZE",{enumerable:!0,get:function(){return denobuffer_1.MAX_SIZE}});Object.defineProperty(exports,"readAll",{enumerable:!0,get:function(){return denobuffer_1.readAll}});Object.defineProperty(exports,"writeAll",{enumerable:!0,get:function(){return denobuffer_1.writeAll}});var bench_1=require_bench();Object.defineProperty(exports,"Bench",{enumerable:!0,get:function(){return bench_1.Bench}});Object.defineProperty(exports,"Metric",{enumerable:!0,get:function(){return bench_1.Metric}});var encoders_1=require_encoders();Object.defineProperty(exports,"TD",{enumerable:!0,get:function(){return encoders_1.TD}});Object.defineProperty(exports,"TE",{enumerable:!0,get:function(){return encoders_1.TE}});var ipparser_1=require_ipparser();Object.defineProperty(exports,"isIP",{enumerable:!0,get:function(){return ipparser_1.isIP}});Object.defineProperty(exports,"parseIP",{enumerable:!0,get:function(){return ipparser_1.parseIP}});var typedsub_1=require_typedsub();Object.defineProperty(exports,"TypedSubscription",{enumerable:!0,get:function(){return typedsub_1.TypedSubscription}});var kv_1=require_kv();Object.defineProperty(exports,"Base64KeyCodec",{enumerable:!0,get:function(){return kv_1.Base64KeyCodec}});Object.defineProperty(exports,"Bucket",{enumerable:!0,get:function(){return kv_1.Bucket}});Object.defineProperty(exports,"defaultBucketOpts",{enumerable:!0,get:function(){return kv_1.defaultBucketOpts}});Object.defineProperty(exports,"NoopKvCodecs",{enumerable:!0,get:function(){return kv_1.NoopKvCodecs}});var semver_1=require_semver();Object.defineProperty(exports,"compare",{enumerable:!0,get:function(){return semver_1.compare}});Object.defineProperty(exports,"parseSemVer",{enumerable:!0,get:function(){return semver_1.parseSemVer}});var types_1=require_types();Object.defineProperty(exports,"Empty",{enumerable:!0,get:function(){return types_1.Empty}});var transport_2=require_transport();Object.defineProperty(exports,"extractProtocolMessage",{enumerable:!0,get:function(){return transport_2.extractProtocolMessage}});var core_1=require_core();Object.defineProperty(exports,"createInbox",{enumerable:!0,get:function(){return core_1.createInbox}});Object.defineProperty(exports,"DebugEvents",{enumerable:!0,get:function(){return core_1.DebugEvents}});Object.defineProperty(exports,"ErrorCode",{enumerable:!0,get:function(){return core_1.ErrorCode}});Object.defineProperty(exports,"Events",{enumerable:!0,get:function(){return core_1.Events}});Object.defineProperty(exports,"isNatsError",{enumerable:!0,get:function(){return core_1.isNatsError}});Object.defineProperty(exports,"Match",{enumerable:!0,get:function(){return core_1.Match}});Object.defineProperty(exports,"NatsError",{enumerable:!0,get:function(){return core_1.NatsError}});Object.defineProperty(exports,"RequestStrategy",{enumerable:!0,get:function(){return core_1.RequestStrategy}});Object.defineProperty(exports,"ServiceError",{enumerable:!0,get:function(){return core_1.ServiceError}});Object.defineProperty(exports,"ServiceErrorCodeHeader",{enumerable:!0,get:function(){return core_1.ServiceErrorCodeHeader}});Object.defineProperty(exports,"ServiceErrorHeader",{enumerable:!0,get:function(){return core_1.ServiceErrorHeader}});Object.defineProperty(exports,"ServiceResponseType",{enumerable:!0,get:function(){return core_1.ServiceResponseType}});Object.defineProperty(exports,"ServiceVerb",{enumerable:!0,get:function(){return core_1.ServiceVerb}});Object.defineProperty(exports,"syncIterator",{enumerable:!0,get:function(){return core_1.syncIterator}});var protocol_2=require_protocol();Object.defineProperty(exports,"SubscriptionImpl",{enumerable:!0,get:function(){return protocol_2.SubscriptionImpl}});Object.defineProperty(exports,"Subscriptions",{enumerable:!0,get:function(){return protocol_2.Subscriptions}})});var require_internal_mod2=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.ConsumerEvents=exports.ConsumerDebugEvents=exports.StoreCompression=exports.StorageType=exports.RetentionPolicy=exports.ReplayPolicy=exports.DiscardPolicy=exports.DeliverPolicy=exports.AckPolicy=exports.RepublishHeaders=exports.KvWatchInclude=exports.JsHeaders=exports.isConsumerOptsBuilder=exports.DirectMsgHeaders=exports.consumerOpts=exports.AdvisoryKind=exports.isHeartbeatMsg=exports.isFlowControlMsg=exports.checkJsError=void 0;var jsutil_1=require_jsutil();Object.defineProperty(exports,"checkJsError",{enumerable:!0,get:function(){return jsutil_1.checkJsError}});Object.defineProperty(exports,"isFlowControlMsg",{enumerable:!0,get:function(){return jsutil_1.isFlowControlMsg}});Object.defineProperty(exports,"isHeartbeatMsg",{enumerable:!0,get:function(){return jsutil_1.isHeartbeatMsg}});var types_1=require_types2();Object.defineProperty(exports,"AdvisoryKind",{enumerable:!0,get:function(){return types_1.AdvisoryKind}});Object.defineProperty(exports,"consumerOpts",{enumerable:!0,get:function(){return types_1.consumerOpts}});Object.defineProperty(exports,"DirectMsgHeaders",{enumerable:!0,get:function(){return types_1.DirectMsgHeaders}});Object.defineProperty(exports,"isConsumerOptsBuilder",{enumerable:!0,get:function(){return types_1.isConsumerOptsBuilder}});Object.defineProperty(exports,"JsHeaders",{enumerable:!0,get:function(){return types_1.JsHeaders}});Object.defineProperty(exports,"KvWatchInclude",{enumerable:!0,get:function(){return types_1.KvWatchInclude}});Object.defineProperty(exports,"RepublishHeaders",{enumerable:!0,get:function(){return types_1.RepublishHeaders}});var jsapi_types_1=require_jsapi_types();Object.defineProperty(exports,"AckPolicy",{enumerable:!0,get:function(){return jsapi_types_1.AckPolicy}});Object.defineProperty(exports,"DeliverPolicy",{enumerable:!0,get:function(){return jsapi_types_1.DeliverPolicy}});Object.defineProperty(exports,"DiscardPolicy",{enumerable:!0,get:function(){return jsapi_types_1.DiscardPolicy}});Object.defineProperty(exports,"ReplayPolicy",{enumerable:!0,get:function(){return jsapi_types_1.ReplayPolicy}});Object.defineProperty(exports,"RetentionPolicy",{enumerable:!0,get:function(){return jsapi_types_1.RetentionPolicy}});Object.defineProperty(exports,"StorageType",{enumerable:!0,get:function(){return jsapi_types_1.StorageType}});Object.defineProperty(exports,"StoreCompression",{enumerable:!0,get:function(){return jsapi_types_1.StoreCompression}});var consumer_1=require_consumer();Object.defineProperty(exports,"ConsumerDebugEvents",{enumerable:!0,get:function(){return consumer_1.ConsumerDebugEvents}});Object.defineProperty(exports,"ConsumerEvents",{enumerable:!0,get:function(){return consumer_1.ConsumerEvents}})});var require_nats_base_client=__commonJS((exports)=>{var __createBinding=exports&&exports.__createBinding||(Object.create?function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))desc={enumerable:!0,get:function(){return m[k]}};Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}),__exportStar=exports&&exports.__exportStar||function(m,exports2){for(var p in m)if(p!=="default"&&!Object.prototype.hasOwnProperty.call(exports2,p))__createBinding(exports2,m,p)};Object.defineProperty(exports,"__esModule",{value:!0});__exportStar(require_internal_mod(),exports);__exportStar(require_internal_mod2(),exports)});var require_node_transport=__commonJS((exports)=>{var __awaiter=exports&&exports.__awaiter||function(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve5){resolve5(value)})}return new(P||(P=Promise))(function(resolve5,reject){function fulfilled(value){try{step(generator.next(value))}catch(e){reject(e)}}function rejected(value){try{step(generator.throw(value))}catch(e){reject(e)}}function step(result){result.done?resolve5(result.value):adopt(result.value).then(fulfilled,rejected)}step((generator=generator.apply(thisArg,_arguments||[])).next())})},__await=exports&&exports.__await||function(v){return this instanceof __await?(this.v=v,this):new __await(v)},__asyncGenerator=exports&&exports.__asyncGenerator||function(thisArg,_arguments,generator){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var g=generator.apply(thisArg,_arguments||[]),i2,q=[];return i2=Object.create((typeof AsyncIterator==="function"?AsyncIterator:Object).prototype),verb("next"),verb("throw"),verb("return",awaitReturn),i2[Symbol.asyncIterator]=function(){return this},i2;function awaitReturn(f){return function(v){return Promise.resolve(v).then(f,reject)}}function verb(n,f){if(g[n]){if(i2[n]=function(v){return new Promise(function(a,b){q.push([n,v,a,b])>1||resume(n,v)})},f)i2[n]=f(i2[n])}}function resume(n,v){try{step(g[n](v))}catch(e){settle(q[0][3],e)}}function step(r){r.value instanceof __await?Promise.resolve(r.value.v).then(fulfill,reject):settle(q[0][2],r)}function fulfill(value){resume("next",value)}function reject(value){resume("throw",value)}function settle(f,v){if(f(v),q.shift(),q.length)resume(q[0][0],q[0][1])}};Object.defineProperty(exports,"__esModule",{value:!0});exports.NodeTransport=void 0;exports.nodeResolveHost=nodeResolveHost;var nats_base_client_1=require_nats_base_client(),net_1=__require("net"),util_1=require_util(),tls_1=__require("tls"),{resolve:resolve4}=__require("path"),{readFile:readFile4,existsSync:existsSync14}=__require("fs"),dns=__require("dns"),VERSION2="2.29.3",LANG="nats.js";class NodeTransport{constructor(){this.yields=[],this.signal=(0,nats_base_client_1.deferred)(),this.closedNotification=(0,nats_base_client_1.deferred)(),this.connected=!1,this.tlsName="",this.done=!1,this.lang=LANG,this.version=VERSION2}connect(hp,options){return __awaiter(this,void 0,void 0,function*(){this.tlsName=hp.tlsName,this.options=options;let{tls}=this.options,{handshakeFirst}=tls||{};try{if(handshakeFirst===!0)this.socket=yield this.tlsFirst(hp);else this.socket=yield this.dial(hp);let info=yield this.peekInfo();(0,nats_base_client_1.checkOptions)(info,options);let{tls_required:tlsRequired,tls_available:tlsAvailable}=info,desired=tlsAvailable===!0&&options.tls!==null;if(!handshakeFirst&&(tlsRequired||desired))this.socket=yield this.startTLS();if(tlsRequired&&this.socket.encrypted!==!0)throw new nats_base_client_1.NatsError("tls",nats_base_client_1.ErrorCode.ServerOptionNotAvailable);return this.connected=!0,this.setupHandlers(),this.signal.resolve(),Promise.resolve()}catch(err){if(!err)err=nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.ConnectionRefused,Error("node provided an undefined error!"));let{code}=err,perr=code==="ECONNREFUSED"?nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.ConnectionRefused,err):err;if(this.socket)this.socket.destroy();throw perr}})}dial(hp){let d=(0,nats_base_client_1.deferred)(),dialError,socket=(0,net_1.createConnection)(hp.port,hp.hostname,()=>{d.resolve(socket),socket.removeAllListeners()});return socket.on("error",(err)=>{dialError=err}),socket.on("close",()=>{socket.removeAllListeners(),d.reject(dialError)}),socket.setNoDelay(!0),d}get isClosed(){return this.done}close(err){return this._closed(err,!1)}peekInfo(){let d=(0,nats_base_client_1.deferred)(),peekError;return this.socket.on("data",(frame)=>{this.yields.push(frame);let t=nats_base_client_1.DataBuffer.concat(...this.yields),pm=(0,nats_base_client_1.extractProtocolMessage)(t);if(pm!=="")try{let m=nats_base_client_1.INFO.exec(pm);if(!m)throw Error("unexpected response from server");let info=JSON.parse(m[1]);d.resolve(info)}catch(err){d.reject(err)}finally{this.socket.removeAllListeners()}}),this.socket.on("error",(err)=>{peekError=err}),this.socket.on("close",()=>{this.socket.removeAllListeners(),d.reject(peekError)}),d}loadFile(fn){if(!fn)return Promise.resolve();let d=(0,nats_base_client_1.deferred)();try{if(fn=resolve4(fn),!existsSync14(fn))d.reject(Error(`${fn} doesn't exist`));readFile4(fn,(err,data)=>{if(err)return d.reject(err);d.resolve(data)})}catch(err){d.reject(err)}return d}loadClientCerts(){return __awaiter(this,void 0,void 0,function*(){let tlsOpts={},{certFile,cert,caFile,ca,keyFile,key}=this.options.tls;try{if(certFile){let data=yield this.loadFile(certFile);if(data)tlsOpts.cert=data}else if(cert)tlsOpts.cert=cert;if(keyFile){let data=yield this.loadFile(keyFile);if(data)tlsOpts.key=data}else if(key)tlsOpts.key=key;if(caFile){let data=yield this.loadFile(caFile);if(data)tlsOpts.ca=[data]}else if(ca)tlsOpts.ca=ca;return Promise.resolve(tlsOpts)}catch(err){return Promise.reject(err)}})}tlsFirst(hp){return __awaiter(this,void 0,void 0,function*(){let tlsError,tlsOpts={servername:this.tlsName,rejectUnauthorized:!0};if(this.socket)tlsOpts.socket=this.socket;if(typeof this.options.tls==="object")try{let certOpts=(yield this.loadClientCerts())||{};tlsOpts=(0,util_1.extend)(tlsOpts,this.options.tls,certOpts)}catch(err){return Promise.reject(new nats_base_client_1.NatsError(err.message,nats_base_client_1.ErrorCode.Tls,err))}let d=(0,nats_base_client_1.deferred)();try{let tlsSocket=(0,tls_1.connect)(hp.port,hp.hostname,tlsOpts,()=>{tlsSocket.removeAllListeners(),d.resolve(tlsSocket)});tlsSocket.on("error",(err)=>{tlsError=err}),tlsSocket.on("secureConnect",()=>{if(tlsOpts.rejectUnauthorized===!1)return;if(!tlsSocket.authorized)throw tlsSocket.authorizationError}),tlsSocket.on("close",()=>{d.reject(tlsError),tlsSocket.removeAllListeners()}),tlsSocket.setNoDelay(!0)}catch(err){d.reject(nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.Tls,err))}return d})}startTLS(){return __awaiter(this,void 0,void 0,function*(){let tlsError,tlsOpts={socket:this.socket,servername:this.tlsName,rejectUnauthorized:!0};if(typeof this.options.tls==="object")try{let certOpts=(yield this.loadClientCerts())||{};tlsOpts=(0,util_1.extend)(tlsOpts,this.options.tls,certOpts)}catch(err){return Promise.reject(new nats_base_client_1.NatsError(err.message,nats_base_client_1.ErrorCode.Tls,err))}let d=(0,nats_base_client_1.deferred)();try{let tlsSocket=(0,tls_1.connect)(tlsOpts,()=>{tlsSocket.removeAllListeners(),d.resolve(tlsSocket)});tlsSocket.on("error",(err)=>{tlsError=err}),tlsSocket.on("secureConnect",()=>{if(tlsOpts.rejectUnauthorized===!1)return;if(!tlsSocket.authorized)throw tlsSocket.authorizationError}),tlsSocket.on("close",()=>{d.reject(tlsError),tlsSocket.removeAllListeners()})}catch(err){d.reject(nats_base_client_1.NatsError.errorForCode(nats_base_client_1.ErrorCode.Tls,err))}return d})}setupHandlers(){let connError;this.socket.on("data",(frame)=>{return this.yields.push(frame),this.signal.resolve()}),this.socket.on("error",(err)=>{connError=err}),this.socket.on("end",()=>{var _a,_b;if((_a=this.socket)===null||_a===void 0?void 0:_a.destroyed)return;(_b=this.socket)===null||_b===void 0||_b.write(new Uint8Array(0),()=>{var _a2;(_a2=this.socket)===null||_a2===void 0||_a2.end()})}),this.socket.on("close",()=>{this._closed(connError,!1)})}[Symbol.asyncIterator](){return this.iterate()}iterate(){return __asyncGenerator(this,arguments,function*(){let debug=this.options.debug;while(!0){if(this.yields.length===0)yield __await(this.signal);let yields=this.yields;this.yields=[];for(let i2=0;i2<yields.length;i2++){if(debug)console.info(`> ${(0,nats_base_client_1.render)(yields[i2])}`);yield yield __await(yields[i2])}if(this.done)break;else if(this.yields.length===0)yields.length=0,this.yields=yields,this.signal=(0,nats_base_client_1.deferred)()}})}discard(){}disconnect(){this._closed(void 0,!0).then().catch()}isEncrypted(){return this.socket instanceof tls_1.TLSSocket}_send(frame){if(this.isClosed||this.socket===void 0)return Promise.resolve();if(this.options.debug)console.info(`< ${(0,nats_base_client_1.render)(frame)}`);let d=(0,nats_base_client_1.deferred)();try{this.socket.write(frame,(err)=>{if(err){if(this.options.debug)console.error(`!!! ${(0,nats_base_client_1.render)(frame)}: ${err}`);return d.reject(err)}return d.resolve()})}catch(err){if(this.options.debug)console.error(`!!! ${(0,nats_base_client_1.render)(frame)}: ${err}`);d.reject(err)}return d}send(frame){this._send(frame).catch((_err)=>{})}_closed(err_1){return __awaiter(this,arguments,void 0,function*(err,internal=!0){if(!this.connected)return;if(this.done)return;if(this.closeError=err,!err&&this.socket&&internal)try{yield this._send(new TextEncoder().encode(""))}catch(err2){if(this.options.debug)console.log("transport close terminated with an error",err2)}try{if(this.socket)this.socket.removeAllListeners(),this.socket.destroy(),this.socket=void 0}catch(err2){console.log(err2)}this.done=!0,this.closedNotification.resolve(this.closeError)})}closed(){return this.closedNotification}}exports.NodeTransport=NodeTransport;function nodeResolveHost(s){return __awaiter(this,void 0,void 0,function*(){let a=(0,nats_base_client_1.deferred)(),aaaa=(0,nats_base_client_1.deferred)();dns.resolve4(s,(err,records)=>{if(err)a.resolve(err);else a.resolve(records)}),dns.resolve6(s,(err,records)=>{if(err)aaaa.resolve(err);else aaaa.resolve(records)});let ips=[],da=yield a;if(Array.isArray(da))ips.push(...da);let daaaa=yield aaaa;if(Array.isArray(daaaa))ips.push(...daaaa);if(ips.length===0)ips.push(s);return ips})}});var require_connect=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.connect=connect;var node_transport_1=require_node_transport(),nats_base_client_1=require_nats_base_client();function connect(opts={}){return(0,nats_base_client_1.setTransportFactory)({factory:()=>{return new node_transport_1.NodeTransport},dnsResolveFn:node_transport_1.nodeResolveHost}),nats_base_client_1.NatsConnectionImpl.connect(opts)}});var require_mod3=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.consumerOpts=exports.StoreCompression=exports.StorageType=exports.RetentionPolicy=exports.RepublishHeaders=exports.ReplayPolicy=exports.KvWatchInclude=exports.JsHeaders=exports.DiscardPolicy=exports.DirectMsgHeaders=exports.DeliverPolicy=exports.ConsumerEvents=exports.ConsumerDebugEvents=exports.AdvisoryKind=exports.AckPolicy=exports.isHeartbeatMsg=exports.isFlowControlMsg=exports.checkJsError=void 0;var internal_mod_1=require_internal_mod2();Object.defineProperty(exports,"checkJsError",{enumerable:!0,get:function(){return internal_mod_1.checkJsError}});Object.defineProperty(exports,"isFlowControlMsg",{enumerable:!0,get:function(){return internal_mod_1.isFlowControlMsg}});Object.defineProperty(exports,"isHeartbeatMsg",{enumerable:!0,get:function(){return internal_mod_1.isHeartbeatMsg}});var internal_mod_2=require_internal_mod2();Object.defineProperty(exports,"AckPolicy",{enumerable:!0,get:function(){return internal_mod_2.AckPolicy}});Object.defineProperty(exports,"AdvisoryKind",{enumerable:!0,get:function(){return internal_mod_2.AdvisoryKind}});Object.defineProperty(exports,"ConsumerDebugEvents",{enumerable:!0,get:function(){return internal_mod_2.ConsumerDebugEvents}});Object.defineProperty(exports,"ConsumerEvents",{enumerable:!0,get:function(){return internal_mod_2.ConsumerEvents}});Object.defineProperty(exports,"DeliverPolicy",{enumerable:!0,get:function(){return internal_mod_2.DeliverPolicy}});Object.defineProperty(exports,"DirectMsgHeaders",{enumerable:!0,get:function(){return internal_mod_2.DirectMsgHeaders}});Object.defineProperty(exports,"DiscardPolicy",{enumerable:!0,get:function(){return internal_mod_2.DiscardPolicy}});Object.defineProperty(exports,"JsHeaders",{enumerable:!0,get:function(){return internal_mod_2.JsHeaders}});Object.defineProperty(exports,"KvWatchInclude",{enumerable:!0,get:function(){return internal_mod_2.KvWatchInclude}});Object.defineProperty(exports,"ReplayPolicy",{enumerable:!0,get:function(){return internal_mod_2.ReplayPolicy}});Object.defineProperty(exports,"RepublishHeaders",{enumerable:!0,get:function(){return internal_mod_2.RepublishHeaders}});Object.defineProperty(exports,"RetentionPolicy",{enumerable:!0,get:function(){return internal_mod_2.RetentionPolicy}});Object.defineProperty(exports,"StorageType",{enumerable:!0,get:function(){return internal_mod_2.StorageType}});Object.defineProperty(exports,"StoreCompression",{enumerable:!0,get:function(){return internal_mod_2.StoreCompression}});var types_1=require_types2();Object.defineProperty(exports,"consumerOpts",{enumerable:!0,get:function(){return types_1.consumerOpts}})});var require_mod4=__commonJS((exports)=>{var __createBinding=exports&&exports.__createBinding||(Object.create?function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))desc={enumerable:!0,get:function(){return m[k]}};Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}),__exportStar=exports&&exports.__exportStar||function(m,exports2){for(var p in m)if(p!=="default"&&!Object.prototype.hasOwnProperty.call(exports2,p))__createBinding(exports2,m,p)};Object.defineProperty(exports,"__esModule",{value:!0});exports.connect=void 0;if(typeof TextEncoder>"u"){let{TextEncoder:TextEncoder2,TextDecoder:TextDecoder2}=__require("util");global.TextEncoder=TextEncoder2,global.TextDecoder=TextDecoder2}if(typeof globalThis.crypto>"u"){let c=__require("crypto");global.crypto=c.webcrypto}if(typeof globalThis.ReadableStream>"u"){let chunks=process.versions.node.split(".");if(parseInt(chunks[0])>=16){let streams=__require("stream/web");global.ReadableStream=streams.ReadableStream}}var connect_1=require_connect();Object.defineProperty(exports,"connect",{enumerable:!0,get:function(){return connect_1.connect}});__exportStar(require_mod2(),exports);__exportStar(require_mod3(),exports)});var exports_nats_client={};__export(exports_nats_client,{subscribe:()=>subscribe,publish:()=>publish,isAvailable:()=>isAvailable,close:()=>close,_resetForTesting:()=>_resetForTesting});function getNatsUrl(){return process.env.GENIE_NATS_URL||"nats://localhost:4222"}function warnOnce(key,message){if(!state[key])state[key]=!0,console.warn(`[genie:nats] ${message}`)}async function importNats(){try{return await Promise.resolve().then(() => __toESM(require_mod4(),1))}catch{return warnOnce("warnedMissingPackage","nats package not installed \u2014 real-time features disabled"),null}}async function ensureConnection(){if(state.connection&&!state.connection.isClosed())return resetIdleTimer(),!0;if(state.connecting)return state.connecting;return state.connecting=(async()=>{try{let natsModule=await importNats();if(!natsModule)return!1;return state.connection=await natsModule.connect({servers:getNatsUrl(),maxReconnectAttempts:2,reconnectTimeWait:500,timeout:2000}),state.codec=natsModule.JSONCodec(),state.warnedUnavailable=!1,resetIdleTimer(),!0}catch{return state.connection=null,state.codec=null,warnOnce("warnedUnavailable",`NATS not available at ${getNatsUrl()}`),!1}finally{state.connecting=null}})(),state.connecting}function resetIdleTimer(){if(state.idleTimer)clearTimeout(state.idleTimer);if(state.activeSubscriptions>0)return;state.idleTimer=setTimeout(()=>{if(state.activeSubscriptions===0)close().catch(()=>{})},500)}async function publish(subject,data){if(!await ensureConnection()||!state.connection||!state.codec)return;try{state.connection.publish(subject,state.codec.encode(data))}catch{}resetIdleTimer()}async function subscribe(subject,callback){let noop={unsubscribe:()=>{}};if(!await ensureConnection()||!state.connection||!state.codec)return noop;try{let sub=state.connection.subscribe(subject),codec=state.codec;if(state.activeSubscriptions++,state.idleTimer)clearTimeout(state.idleTimer),state.idleTimer=null;return(async()=>{try{for await(let msg of sub)try{callback(msg.subject,codec.decode(msg.data))}catch{}}catch{}})(),{unsubscribe:()=>{try{sub.unsubscribe()}catch{}state.activeSubscriptions=Math.max(0,state.activeSubscriptions-1),resetIdleTimer()}}}catch{return noop}}async function isAvailable(){return ensureConnection()}async function close(){if(state.idleTimer)clearTimeout(state.idleTimer),state.idleTimer=null;if(state.connection){try{await state.connection.drain()}catch{try{await state.connection.close()}catch{}}state.connection=null,state.codec=null}}function _resetForTesting(){if(state.connection=null,state.codec=null,state.connecting=null,state.warnedUnavailable=!1,state.warnedMissingPackage=!1,state.activeSubscriptions=0,state.idleTimer)clearTimeout(state.idleTimer);state.idleTimer=null}var state;var init_nats_client=__esm(()=>{state={connection:null,codec:null,connecting:null,warnedUnavailable:!1,warnedMissingPackage:!1,activeSubscriptions:0,idleTimer:null}});function isBlockingEvent(event){return BLOCKING_EVENTS.has(event)}var DISPATCHED_EVENTS,BLOCKING_EVENTS;var init_types2=__esm(()=>{DISPATCHED_EVENTS=["PreToolUse","PostToolUse","SessionStart","SessionEnd","TeammateIdle","TaskCompleted"],BLOCKING_EVENTS=new Set(["PreToolUse","UserPromptSubmit","TeammateIdle","TaskCompleted","PermissionRequest"])});function buildLayoutCommand(windowTarget,mode="mosaic"){return`select-layout -t '${windowTarget}' ${mode==="vertical"?"even-horizontal":"tiled"}`}function resolveLayoutMode(layoutFlag){if(layoutFlag==="vertical")return"vertical";return"mosaic"}import{randomUUID}from"crypto";var native_default;var init_native=__esm(()=>{native_default={randomUUID}});import{randomFillSync}from"crypto";function rng(){if(poolPtr>rnds8Pool.length-16)randomFillSync(rnds8Pool),poolPtr=0;return rnds8Pool.slice(poolPtr,poolPtr+=16)}var rnds8Pool,poolPtr;var init_rng=__esm(()=>{rnds8Pool=new Uint8Array(256),poolPtr=rnds8Pool.length});function unsafeStringify(arr,offset=0){return(byteToHex[arr[offset+0]]+byteToHex[arr[offset+1]]+byteToHex[arr[offset+2]]+byteToHex[arr[offset+3]]+"-"+byteToHex[arr[offset+4]]+byteToHex[arr[offset+5]]+"-"+byteToHex[arr[offset+6]]+byteToHex[arr[offset+7]]+"-"+byteToHex[arr[offset+8]]+byteToHex[arr[offset+9]]+"-"+byteToHex[arr[offset+10]]+byteToHex[arr[offset+11]]+byteToHex[arr[offset+12]]+byteToHex[arr[offset+13]]+byteToHex[arr[offset+14]]+byteToHex[arr[offset+15]]).toLowerCase()}var byteToHex;var init_stringify=__esm(()=>{byteToHex=[];for(let i2=0;i2<256;++i2)byteToHex.push((i2+256).toString(16).slice(1))});function v4(options,buf,offset){if(native_default.randomUUID&&!buf&&!options)return native_default.randomUUID();options=options||{};let rnds=options.random??options.rng?.()??rng();if(rnds.length<16)throw Error("Random bytes length must be >= 16");if(rnds[6]=rnds[6]&15|64,rnds[8]=rnds[8]&63|128,buf){if(offset=offset||0,offset<0||offset+16>buf.length)throw RangeError(`UUID byte range ${offset}:${offset+15} is out of buffer bounds`);for(let i2=0;i2<16;++i2)buf[offset+i2]=rnds[i2];return buf}return unsafeStringify(rnds)}var v4_default;var init_v4=__esm(()=>{init_native();init_rng();init_stringify();v4_default=v4});var init_esm7=__esm(()=>{init_v4()});import{appendFile,mkdir as mkdir5,readFile as readFile4,writeFile as writeFile4}from"fs/promises";import path,{join as join15}from"path";function mailboxDir(repoPath){return join15(repoPath,".genie","mailbox")}function mailboxFilePath(repoPath,workerId){let safeId=path.basename(workerId);return join15(mailboxDir(repoPath),`${safeId}.json`)}function outboxFilePath(repoPath,workerId){let safeId=path.basename(workerId);return join15(mailboxDir(repoPath),`${safeId}-sent.jsonl`)}async function loadMailbox(repoPath,workerId){try{let content=await readFile4(mailboxFilePath(repoPath,workerId),"utf-8");return JSON.parse(content)}catch{return{workerId,messages:[],lastUpdated:new Date().toISOString()}}}async function saveMailbox(repoPath,mailbox){let dir=mailboxDir(repoPath);await mkdir5(dir,{recursive:!0}),mailbox.lastUpdated=new Date().toISOString(),await writeFile4(mailboxFilePath(repoPath,mailbox.workerId),JSON.stringify(mailbox,null,2))}function generateMessageId(){return`msg-${v4_default()}`}async function send(repoPath,from,to,body){await mkdir5(mailboxDir(repoPath),{recursive:!0});let release=await acquireLock(mailboxFilePath(repoPath,to));try{let mailbox=await loadMailbox(repoPath,to),message={id:generateMessageId(),from,to,body,createdAt:new Date().toISOString(),read:!1,deliveredAt:null};mailbox.messages.push(message),await saveMailbox(repoPath,mailbox),await appendFile(outboxFilePath(repoPath,from),`${JSON.stringify(message)}
|
|
130
|
+
`);try{let{publish:publish2}=await Promise.resolve().then(() => (init_nats_client(),exports_nats_client));await publish2(`genie.msg.${to}`,{timestamp:message.createdAt,kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:message.id,from,to},source:"mailbox"})}catch{}return message}finally{await release()}}async function inbox(repoPath,workerId){return(await loadMailbox(repoPath,workerId)).messages}async function readOutbox(repoPath,workerId){try{let lines=(await readFile4(outboxFilePath(repoPath,workerId),"utf-8")).trim().split(`
|
|
131
|
+
`).filter(Boolean),messages=[];for(let line of lines)try{messages.push(JSON.parse(line))}catch{}return messages}catch{return[]}}async function markDelivered(repoPath,workerId,messageId){await mkdir5(mailboxDir(repoPath),{recursive:!0});let release=await acquireLock(mailboxFilePath(repoPath,workerId));try{let mailbox=await loadMailbox(repoPath,workerId),msg=mailbox.messages.find((m)=>m.id===messageId);if(!msg)return!1;return msg.deliveredAt=new Date().toISOString(),await saveMailbox(repoPath,mailbox),!0}finally{await release()}}function toNativeInboxMessage(msg,color="blue"){let words=msg.body.split(/\s+/),summary=words.slice(0,8).join(" ")+(words.length>8?"...":"");return{from:msg.from,text:msg.body,summary,timestamp:msg.createdAt,color,read:!1}}var init_mailbox=__esm(()=>{init_esm7();init_file_lock()});var exports_team_manager={};__export(exports_team_manager,{validateBranchName:()=>validateBranchName,updateTeamConfig:()=>updateTeamConfig,setTeamStatus:()=>setTeamStatus,pruneStaleWorktrees:()=>pruneStaleWorktrees,listTeams:()=>listTeams2,listMembers:()=>listMembers,killTeamMembers:()=>killTeamMembers,hireAgent:()=>hireAgent,getTeam:()=>getTeam2,fireAgent:()=>fireAgent,disbandTeam:()=>disbandTeam,createTeam:()=>createTeam});import{existsSync as existsSync14}from"fs";import{mkdir as mkdir6,readFile as readFile5,readdir as readdir2,rm as rm3,unlink as unlink4,writeFile as writeFile5}from"fs/promises";import{homedir as homedir13}from"os";import path2,{join as join16}from"path";var{$:$3}=globalThis.Bun;function getGenieDir2(){return process.env.GENIE_HOME??join16(homedir13(),".genie")}function teamsDir(){return join16(getGenieDir2(),"teams")}function safeFileName(name){return name.replace(/\//g,"--")}function teamFilePath(name){let safeName=safeFileName(path2.basename(name)===name?name:name);return join16(teamsDir(),`${safeName}.json`)}function getWorktreeBase(repoPath){let base=loadGenieConfigSync().terminal?.worktreeBase;if(base&&base!==".worktrees"){if(path2.isAbsolute(base))return base;return join16(repoPath,base)}let projectName=path2.basename(repoPath);return join16(getGenieDir2(),"worktrees",projectName)}function validateBranchName(name){let errors3=[];if(/\s/.test(name))errors3.push("contains spaces");if(name.includes(".."))errors3.push('contains ".."');if(name.includes("~"))errors3.push('contains "~"');if(name.includes("^"))errors3.push('contains "^"');if(name.includes(":"))errors3.push('contains ":"');if(name.includes("?"))errors3.push('contains "?"');if(name.includes("*"))errors3.push('contains "*"');if(name.includes("["))errors3.push('contains "["');if(name.includes("\\"))errors3.push('contains "\\"');if(/[\x00-\x1f\x7f]/.test(name))errors3.push("contains control characters");if(name.endsWith(".lock"))errors3.push('ends with ".lock"');if(name.endsWith("/"))errors3.push('ends with "/"');if(name.endsWith("."))errors3.push('ends with "."');if(name.startsWith("-"))errors3.push('starts with "-"');if(errors3.length>0)throw Error(`Invalid team name '${name}': must be a valid git branch name (${errors3.join(", ")})`)}async function killWorkersByName(agentName,teamName){let matches=(await list()).filter((w)=>(w.role===agentName||w.id===agentName)&&(!teamName||w.team===teamName));for(let w of matches){try{if(w.paneId&&w.paneId!=="inline"){let{execSync:execSync3}=__require("child_process");execSync3(`tmux kill-pane -t ${w.paneId}`,{stdio:"ignore"})}}catch{}await unregister(w.id)}}async function ensureWorktree(repoPath,branchName,worktreePath,baseBranch){try{await $3`git -C ${repoPath} fetch origin ${baseBranch}`.quiet()}catch{}if(await mkdir6(path2.dirname(worktreePath),{recursive:!0}),existsSync14(worktreePath))return;let branchExists=!1;try{await $3`git -C ${repoPath} rev-parse --verify ${branchName}`.quiet(),branchExists=!0}catch{if(!branchExists)try{await $3`git -C ${repoPath} branch ${branchName} origin/${baseBranch}`.quiet()}catch{try{await $3`git -C ${repoPath} branch ${branchName} ${baseBranch}`.quiet()}catch{await $3`git -C ${repoPath} branch ${branchName}`.quiet()}}}await $3`git clone --shared --branch ${branchName} ${repoPath} ${worktreePath}`.quiet();try{let userName=(await $3`git -C ${repoPath} config user.name`.quiet()).text().trim(),userEmail=(await $3`git -C ${repoPath} config user.email`.quiet()).text().trim();if(userName)await $3`git -C ${worktreePath} config user.name ${userName}`.quiet();if(userEmail)await $3`git -C ${worktreePath} config user.email ${userEmail}`.quiet()}catch{}}async function createTeam(name,repo,baseBranch="dev"){validateBranchName(name);let repoPath=path2.resolve(repo),dir=teamsDir();await mkdir6(dir,{recursive:!0});let filePath=teamFilePath(name);if(existsSync14(filePath)){let content=await readFile5(filePath,"utf-8");return JSON.parse(content)}let worktreeBase=getWorktreeBase(repoPath),worktreePath=join16(worktreeBase,name);await ensureWorktree(repoPath,name,worktreePath,baseBranch);let now=new Date().toISOString(),config={name,repo:repoPath,baseBranch,worktreePath,members:[],status:"in_progress",createdAt:now};if(isInsideClaudeCode()){config.nativeTeamsEnabled=!0;try{let result=await registerAsTeamLead(name);config.nativeTeamParentSessionId=result.sessionId}catch{}}return await writeFile5(filePath,JSON.stringify(config,null,2)),config}async function hireAgent(teamName,agentName){let config=await getTeam2(teamName);if(!config)throw Error(`Team "${teamName}" not found.`);let added;if(agentName==="council")added=BUILTIN_COUNCIL_MEMBERS.map((m)=>m.name).filter((n)=>!config.members.includes(n)),config.members.push(...added);else{if(config.members.includes(agentName))return[];config.members.push(agentName),added=[agentName]}let filePath=teamFilePath(teamName);return await writeFile5(filePath,JSON.stringify(config,null,2)),added}async function fireAgent(teamName,agentName){let config=await getTeam2(teamName);if(!config)throw Error(`Team "${teamName}" not found.`);let idx=config.members.indexOf(agentName);if(idx===-1)return!1;config.members.splice(idx,1);let filePath=teamFilePath(teamName);await writeFile5(filePath,JSON.stringify(config,null,2));try{await killWorkersByName(agentName)}catch{}return!0}async function disbandTeam(teamName){let config=await getTeam2(teamName);if(!config)return!1;if(config.nativeTeamsEnabled)try{await deleteNativeTeam(teamName)}catch{}for(let member of config.members)try{await killWorkersByName(member,teamName)}catch{}if(config.worktreePath&&existsSync14(config.worktreePath))try{await rm3(config.worktreePath,{recursive:!0,force:!0})}catch{}let filePath=teamFilePath(teamName);try{await unlink4(filePath)}catch{return!1}return await pruneStaleWorktrees(config.repo),!0}async function pruneStaleWorktrees(_repoPath){let dir=teamsDir(),files;try{files=await readdir2(dir)}catch{return}for(let file of files){if(!file.endsWith(".json"))continue;try{let content=await readFile5(join16(dir,file),"utf-8"),config=JSON.parse(content);if(config.worktreePath&&!existsSync14(config.worktreePath))await unlink4(join16(dir,file))}catch{}}}async function updateTeamConfig(name,config){let filePath=teamFilePath(name);await writeFile5(filePath,JSON.stringify(config,null,2))}async function getTeam2(name){try{let content=await readFile5(teamFilePath(name),"utf-8");return JSON.parse(content)}catch{return null}}async function listTeams2(){let dir=teamsDir();try{let files=await readdir2(dir),teams=[];for(let file of files){if(!file.endsWith(".json"))continue;try{let content=await readFile5(join16(dir,file),"utf-8");teams.push(JSON.parse(content))}catch{}}return teams}catch{return[]}}async function listMembers(teamName){let config=await getTeam2(teamName);if(!config)return null;return config.members}async function killTeamMembers(teamName){let config=await getTeam2(teamName);if(!config)return;for(let member of config.members)try{await killWorkersByName(member,teamName)}catch{}}async function setTeamStatus(teamName,status){let filePath=teamFilePath(teamName),release=await acquireLock(filePath);try{let config=await getTeam2(teamName);if(!config)throw Error(`Team "${teamName}" not found.`);config.status=status,await writeFile5(filePath,JSON.stringify(config,null,2))}finally{await release()}}var init_team_manager=__esm(()=>{init_agent_registry();init_builtin_agents();init_claude_native_teams();init_file_lock();init_genie_config2()});import{readdirSync as readdirSync4}from"fs";import{join as join17}from"path";function getMigrationsDir(){return join17(import.meta.dir,"..","db","migrations")}async function loadMigrationFiles(){let candidates=[getMigrationsDir(),join17(process.cwd(),"src","db","migrations")];for(let dir of candidates)try{let files=readdirSync4(dir).filter((f)=>f.endsWith(".sql")).sort();if(files.length===0)continue;let migrations=[];for(let file of files){let content=await Bun.file(join17(dir,file)).text();migrations.push({name:file.replace(/\.sql$/,""),sql:content})}return migrations}catch{}return[]}async function ensureMigrationsTable(sql){await sql`
|
|
134
132
|
CREATE TABLE IF NOT EXISTS _genie_migrations (
|
|
135
133
|
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
136
134
|
name TEXT UNIQUE NOT NULL,
|
|
@@ -151,7 +149,7 @@ ${errCtx.stack}`;d.reject(err)}else d.resolve(msg)}});return sub.requestSubject=
|
|
|
151
149
|
`],[],execute)).forEach(({oid,typarray})=>addArrayType(oid,typarray))}function addArrayType(oid,typarray){if(!!options.parsers[typarray]&&!!options.serializers[typarray])return;let parser=options.parsers[oid];options.shared.typeArrayMap[oid]=typarray,options.parsers[typarray]=(xs)=>arrayParser(xs,parser,typarray),options.parsers[typarray].array=!0,options.serializers[typarray]=(xs)=>arraySerializer(xs,options.serializers[oid],options,typarray)}function tryNext(x,xs){return x==="read-write"&&xs.default_transaction_read_only==="on"||x==="read-only"&&xs.default_transaction_read_only==="off"||x==="primary"&&xs.in_hot_standby==="on"||x==="standby"&&xs.in_hot_standby==="off"||x==="prefer-standby"&&xs.in_hot_standby==="off"&&options.host[retries]}function fetchState(){let query2=new Query([`
|
|
152
150
|
show transaction_read_only;
|
|
153
151
|
select pg_catalog.pg_is_in_recovery()
|
|
154
|
-
`],[],execute,null,{simple:!0});query2.resolve=([[a],[b2]])=>{backendParameters.default_transaction_read_only=a.transaction_read_only,backendParameters.in_hot_standby=b2.pg_is_in_recovery?"on":"off"},query2.execute()}function ErrorResponse(x){if(query)(query.cursorFn||query.describeFirst)&&write(Sync),errorResponse=Errors.postgres(parseError(x));else errored(Errors.postgres(parseError(x)))}function retry(q,error3){delete statements[q.signature],q.retried=error3,execute(q)}function NotificationResponse(x){if(!onnotify)return;let index=9;while(x[index++]!==0);onnotify(x.toString("utf8",9,index-1),x.toString("utf8",index,x.length-1))}async function PortalSuspended(){try{let x=await Promise.resolve(query.cursorFn(result));rows=0,x===CLOSE?write(Close(query.portal)):(result=new Result,write(Execute("",query.cursorRows)))}catch(err){write(Sync),query.reject(err)}}function CloseComplete(){result.count&&query.cursorFn(result),query.resolve(result)}function CopyInResponse(){stream=new Stream.Writable({autoDestroy:!0,write(chunk2,encoding,callback){socket.write(bytes_default().d().raw(chunk2).end(),callback)},destroy(error3,callback){callback(error3),socket.write(bytes_default().f().str(error3+bytes_default.N).end()),stream=null},final(callback){socket.write(bytes_default().c().end()),final=callback,stream=null}}),query.resolve(stream)}function CopyOutResponse(){stream=new Stream.Readable({read(){socket.resume()}}),query.resolve(stream)}function CopyBothResponse(){stream=new Stream.Duplex({autoDestroy:!0,read(){socket.resume()},write(chunk2,encoding,callback){socket.write(bytes_default().d().raw(chunk2).end(),callback)},destroy(error3,callback){callback(error3),socket.write(bytes_default().f().str(error3+bytes_default.N).end()),stream=null},final(callback){socket.write(bytes_default().c().end()),final=callback}}),query.resolve(stream)}function CopyData(x){stream&&(stream.push(x.subarray(5))||socket.pause())}function CopyDone(){stream&&stream.push(null),stream=null}function NoticeResponse(x){onnotice?onnotice(parseError(x)):console.log(parseError(x))}function EmptyQueryResponse(){}function FunctionCallResponse(){errored(Errors.notSupported("FunctionCallResponse"))}function NegotiateProtocolVersion(){errored(Errors.notSupported("NegotiateProtocolVersion"))}function UnknownMessage(x){console.error("Postgres.js : Unknown Message:",x[0])}function UnknownAuth(x,type2){console.error("Postgres.js : Unknown Auth:",type2)}function Bind(parameters,types3,statement="",portal=""){let prev,type2;return bytes_default().B().str(portal+bytes_default.N).str(statement+bytes_default.N).i16(0).i16(parameters.length),parameters.forEach((x,i2)=>{if(x===null)return bytes_default.i32(4294967295);type2=types3[i2],parameters[i2]=x=type2 in options.serializers?options.serializers[type2](x):""+x,prev=bytes_default.i,bytes_default.inc(4).str(x).i32(bytes_default.i-prev-4,prev)}),bytes_default.i16(0),bytes_default.end()}function Parse(str2,parameters,types3,name=""){return bytes_default().P().str(name+bytes_default.N).str(str2+bytes_default.N).i16(parameters.length),parameters.forEach((x,i2)=>bytes_default.i32(types3[i2]||0)),bytes_default.end()}function Describe(x,name=""){return bytes_default().D().str(x).str(name+bytes_default.N).end()}function Execute(portal="",rows2=0){return Buffer.concat([bytes_default().E().str(portal+bytes_default.N).i32(rows2).end(),Flush])}function Close(portal=""){return Buffer.concat([bytes_default().C().str("P").str(portal+bytes_default.N).end(),bytes_default().S().end()])}function StartupMessage(){return cancelMessage||bytes_default().inc(4).i16(3).z(2).str(Object.entries(Object.assign({user,database,client_encoding:"UTF8"},options.connection)).filter(([,v])=>v).map(([k,v])=>k+bytes_default.N+v).join(bytes_default.N)).z(2).end(0)}}function parseError(x){let error2={},start=5;for(let i2=5;i2<x.length-1;i2++)if(x[i2]===0)error2[errorFields[x[start]]]=x.toString("utf8",start+1,i2),start=i2+1;return error2}function md5(x){return crypto2.createHash("md5").update(x).digest("hex")}function hmac(key,x){return crypto2.createHmac("sha256",key).update(x).digest()}function sha256(x){return crypto2.createHash("sha256").update(x).digest()}function xor(a,b2){let length=Math.max(a.length,b2.length),buffer2=Buffer.allocUnsafe(length);for(let i2=0;i2<length;i2++)buffer2[i2]=a[i2]^b2[i2];return buffer2}function timer(fn,seconds){if(seconds=typeof seconds==="function"?seconds():seconds,!seconds)return{cancel:noop,start:noop};let timer2;return{cancel(){timer2&&(clearTimeout(timer2),timer2=null)},start(){timer2&&clearTimeout(timer2),timer2=setTimeout(done,seconds*1000,arguments)}};function done(args){fn.apply(null,args),timer2=null}}var connection_default,uid=1,Sync,Flush,SSLRequest,ExecuteUnnamed,DescribeUnnamed,noop=()=>{},retryRoutines,errorFields;var init_connection=__esm(()=>{init_types3();init_errors3();init_result();init_queue();init_query();init_bytes();connection_default=Connection,Sync=bytes_default().S().end(),Flush=bytes_default().H().end(),SSLRequest=bytes_default().i32(8).i32(80877103).end(8),ExecuteUnnamed=Buffer.concat([bytes_default().E().str(bytes_default.N).i32(0).end(),Sync]),DescribeUnnamed=bytes_default().D().str("S").str(bytes_default.N).end(),retryRoutines=new Set(["FetchPreparedStatement","RevalidateCachedQuery","transformAssignedExpr"]),errorFields={83:"severity_local",86:"severity",67:"code",77:"message",68:"detail",72:"hint",80:"position",112:"internal_position",113:"internal_query",87:"where",115:"schema_name",116:"table_name",99:"column_name",100:"data type_name",110:"constraint_name",70:"file",76:"line",82:"routine"}});function Subscribe(postgres2,options){let subscribers=new Map,slot="postgresjs_"+Math.random().toString(36).slice(2),state2={},connection2,stream,ended=!1,sql=subscribe2.sql=postgres2({...options,transform:{column:{},value:{},row:{}},max:1,fetch_types:!1,idle_timeout:null,max_lifetime:null,connection:{...options.connection,replication:"database"},onclose:async function(){if(ended)return;stream=null,state2.pid=state2.secret=void 0,connected(await init(sql,slot,options.publications)),subscribers.forEach((event)=>event.forEach(({onsubscribe})=>onsubscribe()))},no_subscribe:!0}),end=sql.end,close2=sql.close;return sql.end=async()=>{return ended=!0,stream&&await new Promise((r)=>(stream.once("close",r),stream.end())),end()},sql.close=async()=>{return stream&&await new Promise((r)=>(stream.once("close",r),stream.end())),close2()},subscribe2;async function subscribe2(event,fn,onsubscribe=noop2,onerror=noop2){if(event=parseEvent(event),!connection2)connection2=init(sql,slot,options.publications);let subscriber={fn,onsubscribe},fns=subscribers.has(event)?subscribers.get(event).add(subscriber):subscribers.set(event,new Set([subscriber])).get(event),unsubscribe=()=>{fns.delete(subscriber),fns.size===0&&subscribers.delete(event)};return connection2.then((x)=>{return connected(x),onsubscribe(),stream&&stream.on("error",onerror),{unsubscribe,state:state2,sql}})}function connected(x){stream=x.stream,state2.pid=x.state.pid,state2.secret=x.state.secret}async function init(sql2,slot2,publications){if(!publications)throw Error("Missing publication names");let xs=await sql2.unsafe(`CREATE_REPLICATION_SLOT ${slot2} TEMPORARY LOGICAL pgoutput NOEXPORT_SNAPSHOT`),[x]=xs,stream2=await sql2.unsafe(`START_REPLICATION SLOT ${slot2} LOGICAL ${x.consistent_point} (proto_version '1', publication_names '${publications}')`).writable(),state3={lsn:Buffer.concat(x.consistent_point.split("/").map((x2)=>Buffer.from(("00000000"+x2).slice(-8),"hex")))};return stream2.on("data",data),stream2.on("error",error2),stream2.on("close",sql2.close),{stream:stream2,state:xs.state};function error2(e){console.error("Unexpected error during logical streaming - reconnecting",e)}function data(x2){if(x2[0]===119)parse(x2.subarray(25),state3,sql2.options.parsers,handle,options.transform);else if(x2[0]===107&&x2[17])state3.lsn=x2.subarray(1,9),pong()}function handle(a,b2){let path2=b2.relation.schema+"."+b2.relation.table;call("*",a,b2),call("*:"+path2,a,b2),b2.relation.keys.length&&call("*:"+path2+"="+b2.relation.keys.map((x2)=>a[x2.name]),a,b2),call(b2.command,a,b2),call(b2.command+":"+path2,a,b2),b2.relation.keys.length&&call(b2.command+":"+path2+"="+b2.relation.keys.map((x2)=>a[x2.name]),a,b2)}function pong(){let x2=Buffer.alloc(34);x2[0]=114,x2.fill(state3.lsn,1),x2.writeBigInt64BE(BigInt(Date.now()-Date.UTC(2000,0,1))*BigInt(1000),25),stream2.write(x2)}}function call(x,a,b2){subscribers.has(x)&&subscribers.get(x).forEach(({fn})=>fn(a,b2,x))}}function Time(x){return new Date(Date.UTC(2000,0,1)+Number(x/BigInt(1000)))}function parse(x,state2,parsers2,handle,transform){let char=(acc,[k,v])=>(acc[k.charCodeAt(0)]=v,acc);Object.entries({R:(x2)=>{let i2=1,r=state2[x2.readUInt32BE(i2)]={schema:x2.toString("utf8",i2+=4,i2=x2.indexOf(0,i2))||"pg_catalog",table:x2.toString("utf8",i2+1,i2=x2.indexOf(0,i2+1)),columns:Array(x2.readUInt16BE(i2+=2)),keys:[]};i2+=2;let columnIndex=0,column;while(i2<x2.length)column=r.columns[columnIndex++]={key:x2[i2++],name:transform.column.from?transform.column.from(x2.toString("utf8",i2,i2=x2.indexOf(0,i2))):x2.toString("utf8",i2,i2=x2.indexOf(0,i2)),type:x2.readUInt32BE(i2+=1),parser:parsers2[x2.readUInt32BE(i2)],atttypmod:x2.readUInt32BE(i2+=4)},column.key&&r.keys.push(column),i2+=4},Y:()=>{},O:()=>{},B:(x2)=>{state2.date=Time(x2.readBigInt64BE(9)),state2.lsn=x2.subarray(1,9)},I:(x2)=>{let i2=1,relation=state2[x2.readUInt32BE(i2)],{row}=tuples(x2,relation.columns,i2+=7,transform);handle(row,{command:"insert",relation})},D:(x2)=>{let i2=1,relation=state2[x2.readUInt32BE(i2)];i2+=4;let key=x2[i2]===75;handle(key||x2[i2]===79?tuples(x2,relation.columns,i2+=3,transform).row:null,{command:"delete",relation,key})},U:(x2)=>{let i2=1,relation=state2[x2.readUInt32BE(i2)];i2+=4;let key=x2[i2]===75,xs=key||x2[i2]===79?tuples(x2,relation.columns,i2+=3,transform):null;xs&&(i2=xs.i);let{row}=tuples(x2,relation.columns,i2+3,transform);handle(row,{command:"update",relation,key,old:xs&&xs.row})},T:()=>{},C:()=>{}}).reduce(char,{})[x[0]](x)}function tuples(x,columns,xi,transform){let type2,column,value,row=transform.raw?Array(columns.length):{};for(let i2=0;i2<columns.length;i2++)type2=x[xi++],column=columns[i2],value=type2===110?null:type2===117?void 0:column.parser===void 0?x.toString("utf8",xi+4,xi+=4+x.readUInt32BE(xi)):column.parser.array===!0?column.parser(x.toString("utf8",xi+5,xi+=4+x.readUInt32BE(xi))):column.parser(x.toString("utf8",xi+4,xi+=4+x.readUInt32BE(xi))),transform.raw?row[i2]=transform.raw===!0?value:transform.value.from?transform.value.from(value,column):value:row[column.name]=transform.value.from?transform.value.from(value,column):value;return{i:xi,row:transform.row.from?transform.row.from(row):row}}function parseEvent(x){let xs=x.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i)||[];if(!xs)throw Error("Malformed subscribe pattern: "+x);let[,command,path2,key]=xs;return(command||"*")+(path2?":"+(path2.indexOf(".")===-1?"public."+path2:path2):"")+(key?"="+key:"")}var noop2=()=>{};import Stream2 from"stream";function largeObject(sql,oid,mode=393216){return new Promise(async(resolve4,reject)=>{await sql.begin(async(sql2)=>{let finish;!oid&&([{oid}]=await sql2`select lo_creat(-1) as oid`);let[{fd}]=await sql2`select lo_open(${oid}, ${mode}) as fd`,lo={writable,readable,close:()=>sql2`select lo_close(${fd})`.then(finish),tell:()=>sql2`select lo_tell64(${fd})`,read:(x)=>sql2`select loread(${fd}, ${x}) as data`,write:(x)=>sql2`select lowrite(${fd}, ${x})`,truncate:(x)=>sql2`select lo_truncate64(${fd}, ${x})`,seek:(x,whence=0)=>sql2`select lo_lseek64(${fd}, ${x}, ${whence})`,size:()=>sql2`
|
|
152
|
+
`],[],execute,null,{simple:!0});query2.resolve=([[a],[b2]])=>{backendParameters.default_transaction_read_only=a.transaction_read_only,backendParameters.in_hot_standby=b2.pg_is_in_recovery?"on":"off"},query2.execute()}function ErrorResponse(x){if(query)(query.cursorFn||query.describeFirst)&&write(Sync),errorResponse=Errors.postgres(parseError(x));else errored(Errors.postgres(parseError(x)))}function retry(q,error3){delete statements[q.signature],q.retried=error3,execute(q)}function NotificationResponse(x){if(!onnotify)return;let index=9;while(x[index++]!==0);onnotify(x.toString("utf8",9,index-1),x.toString("utf8",index,x.length-1))}async function PortalSuspended(){try{let x=await Promise.resolve(query.cursorFn(result));rows=0,x===CLOSE?write(Close(query.portal)):(result=new Result,write(Execute("",query.cursorRows)))}catch(err){write(Sync),query.reject(err)}}function CloseComplete(){result.count&&query.cursorFn(result),query.resolve(result)}function CopyInResponse(){stream=new Stream.Writable({autoDestroy:!0,write(chunk2,encoding,callback){socket.write(bytes_default().d().raw(chunk2).end(),callback)},destroy(error3,callback){callback(error3),socket.write(bytes_default().f().str(error3+bytes_default.N).end()),stream=null},final(callback){socket.write(bytes_default().c().end()),final=callback,stream=null}}),query.resolve(stream)}function CopyOutResponse(){stream=new Stream.Readable({read(){socket.resume()}}),query.resolve(stream)}function CopyBothResponse(){stream=new Stream.Duplex({autoDestroy:!0,read(){socket.resume()},write(chunk2,encoding,callback){socket.write(bytes_default().d().raw(chunk2).end(),callback)},destroy(error3,callback){callback(error3),socket.write(bytes_default().f().str(error3+bytes_default.N).end()),stream=null},final(callback){socket.write(bytes_default().c().end()),final=callback}}),query.resolve(stream)}function CopyData(x){stream&&(stream.push(x.subarray(5))||socket.pause())}function CopyDone(){stream&&stream.push(null),stream=null}function NoticeResponse(x){onnotice?onnotice(parseError(x)):console.log(parseError(x))}function EmptyQueryResponse(){}function FunctionCallResponse(){errored(Errors.notSupported("FunctionCallResponse"))}function NegotiateProtocolVersion(){errored(Errors.notSupported("NegotiateProtocolVersion"))}function UnknownMessage(x){console.error("Postgres.js : Unknown Message:",x[0])}function UnknownAuth(x,type2){console.error("Postgres.js : Unknown Auth:",type2)}function Bind(parameters,types3,statement="",portal=""){let prev,type2;return bytes_default().B().str(portal+bytes_default.N).str(statement+bytes_default.N).i16(0).i16(parameters.length),parameters.forEach((x,i2)=>{if(x===null)return bytes_default.i32(4294967295);type2=types3[i2],parameters[i2]=x=type2 in options.serializers?options.serializers[type2](x):""+x,prev=bytes_default.i,bytes_default.inc(4).str(x).i32(bytes_default.i-prev-4,prev)}),bytes_default.i16(0),bytes_default.end()}function Parse(str2,parameters,types3,name=""){return bytes_default().P().str(name+bytes_default.N).str(str2+bytes_default.N).i16(parameters.length),parameters.forEach((x,i2)=>bytes_default.i32(types3[i2]||0)),bytes_default.end()}function Describe(x,name=""){return bytes_default().D().str(x).str(name+bytes_default.N).end()}function Execute(portal="",rows2=0){return Buffer.concat([bytes_default().E().str(portal+bytes_default.N).i32(rows2).end(),Flush])}function Close(portal=""){return Buffer.concat([bytes_default().C().str("P").str(portal+bytes_default.N).end(),bytes_default().S().end()])}function StartupMessage(){return cancelMessage||bytes_default().inc(4).i16(3).z(2).str(Object.entries(Object.assign({user,database,client_encoding:"UTF8"},options.connection)).filter(([,v])=>v).map(([k,v])=>k+bytes_default.N+v).join(bytes_default.N)).z(2).end(0)}}function parseError(x){let error2={},start=5;for(let i2=5;i2<x.length-1;i2++)if(x[i2]===0)error2[errorFields[x[start]]]=x.toString("utf8",start+1,i2),start=i2+1;return error2}function md5(x){return crypto2.createHash("md5").update(x).digest("hex")}function hmac(key,x){return crypto2.createHmac("sha256",key).update(x).digest()}function sha256(x){return crypto2.createHash("sha256").update(x).digest()}function xor(a,b2){let length=Math.max(a.length,b2.length),buffer2=Buffer.allocUnsafe(length);for(let i2=0;i2<length;i2++)buffer2[i2]=a[i2]^b2[i2];return buffer2}function timer(fn,seconds){if(seconds=typeof seconds==="function"?seconds():seconds,!seconds)return{cancel:noop,start:noop};let timer2;return{cancel(){timer2&&(clearTimeout(timer2),timer2=null)},start(){timer2&&clearTimeout(timer2),timer2=setTimeout(done,seconds*1000,arguments)}};function done(args){fn.apply(null,args),timer2=null}}var connection_default,uid=1,Sync,Flush,SSLRequest,ExecuteUnnamed,DescribeUnnamed,noop=()=>{},retryRoutines,errorFields;var init_connection=__esm(()=>{init_types3();init_errors3();init_result();init_queue();init_query();init_bytes();connection_default=Connection,Sync=bytes_default().S().end(),Flush=bytes_default().H().end(),SSLRequest=bytes_default().i32(8).i32(80877103).end(8),ExecuteUnnamed=Buffer.concat([bytes_default().E().str(bytes_default.N).i32(0).end(),Sync]),DescribeUnnamed=bytes_default().D().str("S").str(bytes_default.N).end(),retryRoutines=new Set(["FetchPreparedStatement","RevalidateCachedQuery","transformAssignedExpr"]),errorFields={83:"severity_local",86:"severity",67:"code",77:"message",68:"detail",72:"hint",80:"position",112:"internal_position",113:"internal_query",87:"where",115:"schema_name",116:"table_name",99:"column_name",100:"data type_name",110:"constraint_name",70:"file",76:"line",82:"routine"}});function Subscribe(postgres2,options){let subscribers=new Map,slot="postgresjs_"+Math.random().toString(36).slice(2),state2={},connection2,stream,ended=!1,sql=subscribe2.sql=postgres2({...options,transform:{column:{},value:{},row:{}},max:1,fetch_types:!1,idle_timeout:null,max_lifetime:null,connection:{...options.connection,replication:"database"},onclose:async function(){if(ended)return;stream=null,state2.pid=state2.secret=void 0,connected(await init(sql,slot,options.publications)),subscribers.forEach((event)=>event.forEach(({onsubscribe})=>onsubscribe()))},no_subscribe:!0}),end=sql.end,close2=sql.close;return sql.end=async()=>{return ended=!0,stream&&await new Promise((r)=>(stream.once("close",r),stream.end())),end()},sql.close=async()=>{return stream&&await new Promise((r)=>(stream.once("close",r),stream.end())),close2()},subscribe2;async function subscribe2(event,fn,onsubscribe=noop2,onerror=noop2){if(event=parseEvent(event),!connection2)connection2=init(sql,slot,options.publications);let subscriber={fn,onsubscribe},fns=subscribers.has(event)?subscribers.get(event).add(subscriber):subscribers.set(event,new Set([subscriber])).get(event),unsubscribe=()=>{fns.delete(subscriber),fns.size===0&&subscribers.delete(event)};return connection2.then((x)=>{return connected(x),onsubscribe(),stream&&stream.on("error",onerror),{unsubscribe,state:state2,sql}})}function connected(x){stream=x.stream,state2.pid=x.state.pid,state2.secret=x.state.secret}async function init(sql2,slot2,publications){if(!publications)throw Error("Missing publication names");let xs=await sql2.unsafe(`CREATE_REPLICATION_SLOT ${slot2} TEMPORARY LOGICAL pgoutput NOEXPORT_SNAPSHOT`),[x]=xs,stream2=await sql2.unsafe(`START_REPLICATION SLOT ${slot2} LOGICAL ${x.consistent_point} (proto_version '1', publication_names '${publications}')`).writable(),state3={lsn:Buffer.concat(x.consistent_point.split("/").map((x2)=>Buffer.from(("00000000"+x2).slice(-8),"hex")))};return stream2.on("data",data),stream2.on("error",error2),stream2.on("close",sql2.close),{stream:stream2,state:xs.state};function error2(e){console.error("Unexpected error during logical streaming - reconnecting",e)}function data(x2){if(x2[0]===119)parse(x2.subarray(25),state3,sql2.options.parsers,handle,options.transform);else if(x2[0]===107&&x2[17])state3.lsn=x2.subarray(1,9),pong()}function handle(a,b2){let path3=b2.relation.schema+"."+b2.relation.table;call("*",a,b2),call("*:"+path3,a,b2),b2.relation.keys.length&&call("*:"+path3+"="+b2.relation.keys.map((x2)=>a[x2.name]),a,b2),call(b2.command,a,b2),call(b2.command+":"+path3,a,b2),b2.relation.keys.length&&call(b2.command+":"+path3+"="+b2.relation.keys.map((x2)=>a[x2.name]),a,b2)}function pong(){let x2=Buffer.alloc(34);x2[0]=114,x2.fill(state3.lsn,1),x2.writeBigInt64BE(BigInt(Date.now()-Date.UTC(2000,0,1))*BigInt(1000),25),stream2.write(x2)}}function call(x,a,b2){subscribers.has(x)&&subscribers.get(x).forEach(({fn})=>fn(a,b2,x))}}function Time(x){return new Date(Date.UTC(2000,0,1)+Number(x/BigInt(1000)))}function parse(x,state2,parsers2,handle,transform){let char=(acc,[k,v])=>(acc[k.charCodeAt(0)]=v,acc);Object.entries({R:(x2)=>{let i2=1,r=state2[x2.readUInt32BE(i2)]={schema:x2.toString("utf8",i2+=4,i2=x2.indexOf(0,i2))||"pg_catalog",table:x2.toString("utf8",i2+1,i2=x2.indexOf(0,i2+1)),columns:Array(x2.readUInt16BE(i2+=2)),keys:[]};i2+=2;let columnIndex=0,column;while(i2<x2.length)column=r.columns[columnIndex++]={key:x2[i2++],name:transform.column.from?transform.column.from(x2.toString("utf8",i2,i2=x2.indexOf(0,i2))):x2.toString("utf8",i2,i2=x2.indexOf(0,i2)),type:x2.readUInt32BE(i2+=1),parser:parsers2[x2.readUInt32BE(i2)],atttypmod:x2.readUInt32BE(i2+=4)},column.key&&r.keys.push(column),i2+=4},Y:()=>{},O:()=>{},B:(x2)=>{state2.date=Time(x2.readBigInt64BE(9)),state2.lsn=x2.subarray(1,9)},I:(x2)=>{let i2=1,relation=state2[x2.readUInt32BE(i2)],{row}=tuples(x2,relation.columns,i2+=7,transform);handle(row,{command:"insert",relation})},D:(x2)=>{let i2=1,relation=state2[x2.readUInt32BE(i2)];i2+=4;let key=x2[i2]===75;handle(key||x2[i2]===79?tuples(x2,relation.columns,i2+=3,transform).row:null,{command:"delete",relation,key})},U:(x2)=>{let i2=1,relation=state2[x2.readUInt32BE(i2)];i2+=4;let key=x2[i2]===75,xs=key||x2[i2]===79?tuples(x2,relation.columns,i2+=3,transform):null;xs&&(i2=xs.i);let{row}=tuples(x2,relation.columns,i2+3,transform);handle(row,{command:"update",relation,key,old:xs&&xs.row})},T:()=>{},C:()=>{}}).reduce(char,{})[x[0]](x)}function tuples(x,columns,xi,transform){let type2,column,value,row=transform.raw?Array(columns.length):{};for(let i2=0;i2<columns.length;i2++)type2=x[xi++],column=columns[i2],value=type2===110?null:type2===117?void 0:column.parser===void 0?x.toString("utf8",xi+4,xi+=4+x.readUInt32BE(xi)):column.parser.array===!0?column.parser(x.toString("utf8",xi+5,xi+=4+x.readUInt32BE(xi))):column.parser(x.toString("utf8",xi+4,xi+=4+x.readUInt32BE(xi))),transform.raw?row[i2]=transform.raw===!0?value:transform.value.from?transform.value.from(value,column):value:row[column.name]=transform.value.from?transform.value.from(value,column):value;return{i:xi,row:transform.row.from?transform.row.from(row):row}}function parseEvent(x){let xs=x.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i)||[];if(!xs)throw Error("Malformed subscribe pattern: "+x);let[,command,path3,key]=xs;return(command||"*")+(path3?":"+(path3.indexOf(".")===-1?"public."+path3:path3):"")+(key?"="+key:"")}var noop2=()=>{};import Stream2 from"stream";function largeObject(sql,oid,mode=393216){return new Promise(async(resolve4,reject)=>{await sql.begin(async(sql2)=>{let finish;!oid&&([{oid}]=await sql2`select lo_creat(-1) as oid`);let[{fd}]=await sql2`select lo_open(${oid}, ${mode}) as fd`,lo={writable,readable,close:()=>sql2`select lo_close(${fd})`.then(finish),tell:()=>sql2`select lo_tell64(${fd})`,read:(x)=>sql2`select loread(${fd}, ${x}) as data`,write:(x)=>sql2`select lowrite(${fd}, ${x})`,truncate:(x)=>sql2`select lo_truncate64(${fd}, ${x})`,seek:(x,whence=0)=>sql2`select lo_lseek64(${fd}, ${x}, ${whence})`,size:()=>sql2`
|
|
155
153
|
select
|
|
156
154
|
lo_lseek64(${fd}, location, 0) as position,
|
|
157
155
|
seek.size
|
|
@@ -161,8 +159,8 @@ ${errCtx.stack}`;d.reject(err)}else d.resolve(msg)}});return sub.requestSubject=
|
|
|
161
159
|
tell.location
|
|
162
160
|
from (select lo_tell64($1) as location) tell
|
|
163
161
|
) seek
|
|
164
|
-
`};return resolve4(lo),new Promise(async(r)=>finish=r);async function readable({highWaterMark=16384,start=0,end=1/0}={}){let max=end-start;return start&&await lo.seek(start),new Stream2.Readable({highWaterMark,async read(size){let l=size>max?size-max:size;max-=size;let[{data}]=await lo.read(l);if(this.push(data),data.length<size)this.push(null)}})}async function writable({highWaterMark=16384,start=0}={}){return start&&await lo.seek(start),new Stream2.Writable({highWaterMark,write(chunk,encoding,callback){lo.write(chunk).then(()=>callback(),callback)}})}}).catch(reject)})}var init_large=()=>{};var exports_src={};__export(exports_src,{default:()=>src_default});import os from"os";import fs from"fs";function Postgres(a,b2){let options=parseOptions(a,b2),subscribe2=options.no_subscribe||Subscribe(Postgres,{...options}),ending=!1,queries=queue_default(),connecting=queue_default(),reserved=queue_default(),closed=queue_default(),ended=queue_default(),open2=queue_default(),busy=queue_default(),full=queue_default(),queues={connecting,reserved,closed,ended,open:open2,busy,full},connections=[...Array(options.max)].map(()=>connection_default(options,queues,{onopen,onend,onclose})),sql=Sql(handler);return Object.assign(sql,{get parameters(){return options.parameters},largeObject:largeObject.bind(null,sql),subscribe:subscribe2,CLOSE,END:CLOSE,PostgresError,options,reserve,listen,begin,close:close2,end}),sql;function Sql(handler2){return handler2.debug=options.debug,Object.entries(options.types).reduce((acc,[name,type2])=>{return acc[name]=(x)=>new Parameter(x,type2.to),acc},typed),Object.assign(sql2,{types:typed,typed,unsafe,notify,array,json:json2,file}),sql2;function typed(value,type2){return new Parameter(value,type2)}function sql2(strings,...args){return strings&&Array.isArray(strings.raw)?new Query(strings,args,handler2,cancel):typeof strings==="string"&&!args.length?new Identifier(options.transform.column.to?options.transform.column.to(strings):strings):new Builder(strings,args)}function unsafe(string,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([string],args,handler2,cancel,{prepare:!1,...options2,simple:"simple"in options2?options2.simple:args.length===0})}function file(path2,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([],args,(query2)=>{fs.readFile(path2,"utf8",(err,string)=>{if(err)return query2.reject(err);query2.strings=[string],handler2(query2)})},cancel,{...options2,simple:"simple"in options2?options2.simple:args.length===0})}}async function listen(name,fn,onlisten){let listener={fn,onlisten},sql2=listen.sql||(listen.sql=Postgres({...options,max:1,idle_timeout:null,max_lifetime:null,fetch_types:!1,onclose(){Object.entries(listen.channels).forEach(([name2,{listeners}])=>{delete listen.channels[name2],Promise.all(listeners.map((l)=>listen(name2,l.fn,l.onlisten).catch(()=>{})))})},onnotify(c,x){c in listen.channels&&listen.channels[c].listeners.forEach((l)=>l.fn(x))}})),channels=listen.channels||(listen.channels={});if(name in channels){channels[name].listeners.push(listener);let result2=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result2.state,unlisten}}channels[name]={result:sql2`listen ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`,listeners:[listener]};let result=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result.state,unlisten};async function unlisten(){if(name in channels===!1)return;if(channels[name].listeners=channels[name].listeners.filter((x)=>x!==listener),channels[name].listeners.length)return;return delete channels[name],sql2`unlisten ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`}}async function notify(channel,payload){return await sql`select pg_notify(${channel}, ${""+payload})`}async function reserve(){let queue=queue_default(),c=open2.length?open2.shift():await new Promise((resolve4,reject)=>{let query={reserve:resolve4,reject};queries.push(query),closed.length&&connect(closed.shift(),query)});move(c,reserved),c.reserved=()=>queue.length?c.execute(queue.shift()):move(c,reserved),c.reserved.release=!0;let sql2=Sql(handler2);return sql2.release=()=>{c.reserved=null,onopen(c)},sql2;function handler2(q){c.queue===full?queue.push(q):c.execute(q)||move(c,full)}}async function begin(options2,fn){!fn&&(fn=options2,options2="");let queries2=queue_default(),savepoints=0,connection2,prepare=null;try{return await sql.unsafe("begin "+options2.replace(/[^a-z ]/ig,""),[],{onexecute}).execute(),await Promise.race([scope(connection2,fn),new Promise((_,reject)=>connection2.onclose=reject)])}catch(error2){throw error2}async function scope(c,fn2,name){let sql2=Sql(handler2);sql2.savepoint=savepoint,sql2.prepare=(x)=>prepare=x.replace(/[^a-z0-9$-_. ]/gi);let uncaughtError,result;name&&await sql2`savepoint ${sql2(name)}`;try{if(result=await new Promise((resolve4,reject)=>{let x=fn2(sql2);Promise.resolve(Array.isArray(x)?Promise.all(x):x).then(resolve4,reject)}),uncaughtError)throw uncaughtError}catch(e){throw await(name?sql2`rollback to ${sql2(name)}`:sql2`rollback`),e instanceof PostgresError&&e.code==="25P02"&&uncaughtError||e}if(!name)prepare?await sql2`prepare transaction '${sql2.unsafe(prepare)}'`:await sql2`commit`;return result;function savepoint(name2,fn3){if(name2&&Array.isArray(name2.raw))return savepoint((sql3)=>sql3.apply(sql3,arguments));return arguments.length===1&&(fn3=name2,name2=null),scope(c,fn3,"s"+savepoints+++(name2?"_"+name2:""))}function handler2(q){q.catch((e)=>uncaughtError||(uncaughtError=e)),c.queue===full?queries2.push(q):c.execute(q)||move(c,full)}}function onexecute(c){connection2=c,move(c,reserved),c.reserved=()=>queries2.length?c.execute(queries2.shift()):move(c,reserved)}}function move(c,queue){return c.queue.remove(c),queue.push(c),c.queue=queue,queue===open2?c.idleTimer.start():c.idleTimer.cancel(),c}function json2(x){return new Parameter(x,3802)}function array(x,type2){if(!Array.isArray(x))return array(Array.from(arguments));return new Parameter(x,type2||(x.length?inferType(x)||25:0),options.shared.typeArrayMap)}function handler(query){if(ending)return query.reject(Errors.connection("CONNECTION_ENDED",options,options));if(open2.length)return go(open2.shift(),query);if(closed.length)return connect(closed.shift(),query);busy.length?go(busy.shift(),query):queries.push(query)}function go(c,query){return c.execute(query)?move(c,busy):move(c,full)}function cancel(query){return new Promise((resolve4,reject)=>{query.state?query.active?connection_default(options).cancel(query.state,resolve4,reject):query.cancelled={resolve:resolve4,reject}:(queries.remove(query),query.cancelled=!0,query.reject(Errors.generic("57014","canceling statement due to user request")),resolve4())})}async function end({timeout=null}={}){if(ending)return ending;await 1;let timer2;return ending=Promise.race([new Promise((r)=>timeout!==null&&(timer2=setTimeout(destroy,timeout*1000,r))),Promise.all(connections.map((c)=>c.end()).concat(listen.sql?listen.sql.end({timeout:0}):[],subscribe2.sql?subscribe2.sql.end({timeout:0}):[]))]).then(()=>clearTimeout(timer2))}async function close2(){await Promise.all(connections.map((c)=>c.end()))}async function destroy(resolve4){await Promise.all(connections.map((c)=>c.terminate()));while(queries.length)queries.shift().reject(Errors.connection("CONNECTION_DESTROYED",options));resolve4()}function connect(c,query){return move(c,connecting),c.connect(query),c}function onend(c){move(c,ended)}function onopen(c){if(queries.length===0)return move(c,open2);let max=Math.ceil(queries.length/(connecting.length+1)),ready=!0;while(ready&&queries.length&&max-- >0){let query=queries.shift();if(query.reserve)return query.reserve(c);ready=c.execute(query)}ready?move(c,busy):move(c,full)}function onclose(c,e){move(c,closed),c.reserved=null,c.onclose&&(c.onclose(e),c.onclose=null),options.onclose&&options.onclose(c.id),queries.length&&connect(c,queries.shift())}}function parseOptions(a,b2){if(a&&a.shared)return a;let env=process.env,o=(!a||typeof a==="string"?b2:a)||{},{url,multihost}=parseUrl(a),query=[...url.searchParams].reduce((a2,[b3,c])=>(a2[b3]=c,a2),{}),host=o.hostname||o.host||multihost||url.hostname||env.PGHOST||"localhost",port=o.port||url.port||env.PGPORT||5432,user=o.user||o.username||url.username||env.PGUSERNAME||env.PGUSER||osUsername();o.no_prepare&&(o.prepare=!1),query.sslmode&&(query.ssl=query.sslmode,delete query.sslmode),"timeout"in o&&(console.log("The timeout option is deprecated, use idle_timeout instead"),o.idle_timeout=o.timeout),query.sslrootcert==="system"&&(query.ssl="verify-full");let ints=["idle_timeout","connect_timeout","max_lifetime","max_pipeline","backoff","keep_alive"],defaults={max:globalThis.Cloudflare?3:10,ssl:!1,sslnegotiation:null,idle_timeout:null,connect_timeout:30,max_lifetime,max_pipeline:100,backoff,keep_alive:60,prepare:!0,debug:!1,fetch_types:!0,publications:"alltables",target_session_attrs:null};return{host:Array.isArray(host)?host:host.split(",").map((x)=>x.split(":")[0]),port:Array.isArray(port)?port:host.split(",").map((x)=>parseInt(x.split(":")[1]||port)),path:o.path||host.indexOf("/")>-1&&host+"/.s.PGSQL."+port,database:o.database||o.db||(url.pathname||"").slice(1)||env.PGDATABASE||user,user,pass:o.pass||o.password||url.password||env.PGPASSWORD||"",...Object.entries(defaults).reduce((acc,[k,d])=>{let value=k in o?o[k]:(k in query)?query[k]==="disable"||query[k]==="false"?!1:query[k]:env["PG"+k.toUpperCase()]||d;return acc[k]=typeof value==="string"&&ints.includes(k)?+value:value,acc},{}),connection:{application_name:env.PGAPPNAME||"postgres.js",...o.connection,...Object.entries(query).reduce((acc,[k,v])=>((k in defaults)||(acc[k]=v),acc),{})},types:o.types||{},target_session_attrs:tsa(o,url,env),onnotice:o.onnotice,onnotify:o.onnotify,onclose:o.onclose,onparameter:o.onparameter,socket:o.socket,transform:parseTransform(o.transform||{undefined:void 0}),parameters:{},shared:{retries:0,typeArrayMap:{}},...mergeUserTypes(o.types)}}function tsa(o,url,env){let x=o.target_session_attrs||url.searchParams.get("target_session_attrs")||env.PGTARGETSESSIONATTRS;if(!x||["read-write","read-only","primary","standby","prefer-standby"].includes(x))return x;throw Error("target_session_attrs "+x+" is not supported")}function backoff(retries){return(0.5+Math.random()/2)*Math.min(3**retries/100,20)}function max_lifetime(){return 60*(30+Math.random()*30)}function parseTransform(x){return{undefined:x.undefined,column:{from:typeof x.column==="function"?x.column:x.column&&x.column.from,to:x.column&&x.column.to},value:{from:typeof x.value==="function"?x.value:x.value&&x.value.from,to:x.value&&x.value.to},row:{from:typeof x.row==="function"?x.row:x.row&&x.row.from,to:x.row&&x.row.to}}}function parseUrl(url){if(!url||typeof url!=="string")return{url:{searchParams:new Map}};let host=url;host=host.slice(host.indexOf("://")+3).split(/[?/]/)[0],host=decodeURIComponent(host.slice(host.indexOf("@")+1));let urlObj=new URL(url.replace(host,host.split(",")[0]));return{url:{username:decodeURIComponent(urlObj.username),password:decodeURIComponent(urlObj.password),host:urlObj.host,hostname:urlObj.hostname,port:urlObj.port,pathname:urlObj.pathname,searchParams:urlObj.searchParams},multihost:host.indexOf(",")>-1&&host}}function osUsername(){try{return os.userInfo().username}catch(_){return process.env.USERNAME||process.env.USER||process.env.LOGNAME}}var src_default;var init_src=__esm(()=>{init_types3();init_connection();init_query();init_queue();init_errors3();init_large();Object.assign(Postgres,{PostgresError,toPascal,pascal,toCamel,camel,toKebab,kebab,fromPascal,fromCamel,fromKebab,BigInt:{to:20,from:[20],parse:(x)=>BigInt(x),serialize:(x)=>x.toString()}});src_default=Postgres});var exports_db={};__export(exports_db,{shutdown:()=>shutdown,isAvailable:()=>isAvailable2,getLockfilePath:()=>getLockfilePath,getDataDir:()=>getDataDir,getConnection:()=>getConnection,getActivePort:()=>getActivePort,ensurePgserve:()=>ensurePgserve});import{execSync as execSync3}from"child_process";import{existsSync as existsSync16,mkdirSync as mkdirSync6,readFileSync as readFileSync8,renameSync,unlinkSync as unlinkSync3,writeFileSync as writeFileSync5}from"fs";import{createConnection}from"net";import{homedir as homedir15}from"os";import{join as join18}from"path";function maskCredentials(url){return url.replace(/\/\/.*@/,"//***@")}function killOrphanedPostgres(dataDir){let pidFile=join18(dataDir,"postmaster.pid");if(!existsSync16(pidFile))return;try{let content=readFileSync8(pidFile,"utf-8"),pid=Number.parseInt(content.split(`
|
|
165
|
-
`)[0],10);if(Number.isNaN(pid)||pid<=0)return;let cmdline;try{cmdline=execSync3(`ps -o command= -p ${pid} 2>/dev/null`,{encoding:"utf-8"}).trim()}catch{return}if(!cmdline.includes("postgres"))return;try{process.kill(pid,"SIGTERM")}catch{return}let deadline=Date.now()+5000;while(Date.now()<deadline)try{process.kill(pid,0),execSync3("sleep 0.2",{stdio:"ignore"})}catch{return}try{process.kill(pid,"SIGKILL")}catch{}}catch{}}function getPort(){let envPort=process.env.GENIE_PG_PORT;if(envPort){let parsed=Number.parseInt(envPort,10);if(!Number.isNaN(parsed)&&parsed>0&&parsed<65536)return parsed}return DEFAULT_PORT}function isPortListening(port,host){return new Promise((resolve4)=>{let socket=createConnection({port,host},()=>{socket.destroy(),resolve4(!0)});socket.on("error",()=>{socket.destroy(),resolve4(!1)}),socket.setTimeout(1000,()=>{socket.destroy(),resolve4(!1)})})}function readLockfile(){try{let content=readFileSync8(LOCKFILE_PATH,"utf-8").trim(),port=Number.parseInt(content,10);if(!Number.isNaN(port)&&port>0&&port<65536)return port}catch{}return null}function writeLockfile(port){try{mkdirSync6(GENIE_HOME2,{recursive:!0});let tmpPath=`${LOCKFILE_PATH}.tmp.${process.pid}`;writeFileSync5(tmpPath,String(port),"utf-8"),renameSync(tmpPath,LOCKFILE_PATH)}catch{}}function removeLockfile(){try{unlinkSync3(LOCKFILE_PATH)}catch{}}async function ensurePgserve(){if(ensurePromise)return ensurePromise;ensurePromise=_ensurePgserve();try{return await ensurePromise}finally{ensurePromise=null}}async function _ensurePgserve(){if(activePort!==null&&pgserveServer)return activePort;if(activePort!==null)return activePort;let port=getPort(),reusedPort=await tryReuseLockfile();if(reusedPort!==null)return reusedPort;if(await isPortListening(port,DEFAULT_HOST))return markPortActive(port,!0);mkdirSync6(DATA_DIR,{recursive:!0}),killOrphanedPostgres(DATA_DIR);try{let startedPort=await startPgserveOnPort(port);return registerExitHandler(),startedPort}catch(err){return tryFallbackPorts(port,err)}}async function tryReuseLockfile(){let lockfilePort=readLockfile();if(lockfilePort===null)return null;if(await isPortListening(lockfilePort,DEFAULT_HOST))return markPortActive(lockfilePort,!1);return removeLockfile(),null}function markPortActive(port,writeLock){if(activePort=port,process.env.GENIE_PG_AVAILABLE="true",writeLock)writeLockfile(port);return port}async function tryFallbackPorts(basePort,originalErr){for(let offset=1;offset<=MAX_PORT_RETRIES;offset++){let fallbackPort=basePort+offset;if(await isPortListening(fallbackPort,DEFAULT_HOST))return markPortActive(fallbackPort,!0);try{let startedPort=await startPgserveOnPort(fallbackPort);return registerExitHandler(),startedPort}catch{}}process.env.GENIE_PG_AVAILABLE="false";let message=originalErr instanceof Error?originalErr.message:String(originalErr);throw console.warn(`Warning: pgserve failed to start: ${maskCredentials(message)}`),Error(`pgserve failed to start on port ${basePort} (and fallbacks ${basePort+1}-${basePort+MAX_PORT_RETRIES}): ${maskCredentials(message)}`)}async function startPgserveOnPort(port){let{startMultiTenantServer}=await import("pgserve");return pgserveServer=await startMultiTenantServer({port,host:DEFAULT_HOST,baseDir:DATA_DIR,logLevel:"warn",autoProvision:!0}),activePort=port,ownsLockfile=!0,process.env.GENIE_PG_AVAILABLE="true",writeLockfile(port),port}function registerExitHandler(){if(exitHandlerRegistered)return;exitHandlerRegistered=!0;let cleanup=()=>{if(ownsLockfile)removeLockfile(),ownsLockfile=!1};process.on("exit",cleanup),process.on("SIGINT",()=>{cleanup(),process.exit(130)}),process.on("SIGTERM",()=>{cleanup(),process.exit(143)})}function migrationsDone(){try{let marker=readFileSync8(MIGRATION_MARKER,"utf-8").trim(),currentVersion=process.env.npm_package_version??"";return marker===currentVersion||currentVersion===""&&marker.length>0}catch{return!1}}function markMigrationsDone(){try{let version=process.env.npm_package_version??Date.now().toString();writeFileSync5(MIGRATION_MARKER,version,"utf-8")}catch{}}async function getConnection(){if(sqlClient)return sqlClient;let port=await ensurePgserve(),postgres2=(await Promise.resolve().then(() => (init_src(),exports_src))).default;if(sqlClient=postgres2({host:DEFAULT_HOST,port,database:DB_NAME,username:"postgres",password:"postgres",max:10,idle_timeout:1,connect_timeout:5}),!migrationsDone())await runMigrations(sqlClient),markMigrationsDone();return sqlClient}async function isAvailable2(){try{return await(await getConnection())`SELECT 1`,!0}catch{return!1}}async function shutdown(){if(sqlClient)await sqlClient.end({timeout:5}),sqlClient=null;if(ownsLockfile)removeLockfile(),ownsLockfile=!1}function getDataDir(){return DATA_DIR}function getActivePort(){return activePort??getPort()}function getLockfilePath(){return LOCKFILE_PATH}var DEFAULT_PORT=19642,DEFAULT_HOST="127.0.0.1",MAX_PORT_RETRIES=3,GENIE_HOME2,DATA_DIR,LOCKFILE_PATH,MIGRATION_MARKER,DB_NAME="genie",pgserveServer=null,sqlClient=null,activePort=null,ensurePromise=null,ownsLockfile=!1,exitHandlerRegistered=!1;var init_db=__esm(()=>{init_db_migrations();GENIE_HOME2=process.env.GENIE_HOME??join18(
|
|
162
|
+
`};return resolve4(lo),new Promise(async(r)=>finish=r);async function readable({highWaterMark=16384,start=0,end=1/0}={}){let max=end-start;return start&&await lo.seek(start),new Stream2.Readable({highWaterMark,async read(size){let l=size>max?size-max:size;max-=size;let[{data}]=await lo.read(l);if(this.push(data),data.length<size)this.push(null)}})}async function writable({highWaterMark=16384,start=0}={}){return start&&await lo.seek(start),new Stream2.Writable({highWaterMark,write(chunk,encoding,callback){lo.write(chunk).then(()=>callback(),callback)}})}}).catch(reject)})}var init_large=()=>{};var exports_src={};__export(exports_src,{default:()=>src_default});import os from"os";import fs from"fs";function Postgres(a,b2){let options=parseOptions(a,b2),subscribe2=options.no_subscribe||Subscribe(Postgres,{...options}),ending=!1,queries=queue_default(),connecting=queue_default(),reserved=queue_default(),closed=queue_default(),ended=queue_default(),open2=queue_default(),busy=queue_default(),full=queue_default(),queues={connecting,reserved,closed,ended,open:open2,busy,full},connections=[...Array(options.max)].map(()=>connection_default(options,queues,{onopen,onend,onclose})),sql=Sql(handler);return Object.assign(sql,{get parameters(){return options.parameters},largeObject:largeObject.bind(null,sql),subscribe:subscribe2,CLOSE,END:CLOSE,PostgresError,options,reserve,listen,begin,close:close2,end}),sql;function Sql(handler2){return handler2.debug=options.debug,Object.entries(options.types).reduce((acc,[name,type2])=>{return acc[name]=(x)=>new Parameter(x,type2.to),acc},typed),Object.assign(sql2,{types:typed,typed,unsafe,notify,array,json:json2,file}),sql2;function typed(value,type2){return new Parameter(value,type2)}function sql2(strings,...args){return strings&&Array.isArray(strings.raw)?new Query(strings,args,handler2,cancel):typeof strings==="string"&&!args.length?new Identifier(options.transform.column.to?options.transform.column.to(strings):strings):new Builder(strings,args)}function unsafe(string,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([string],args,handler2,cancel,{prepare:!1,...options2,simple:"simple"in options2?options2.simple:args.length===0})}function file(path3,args=[],options2={}){return arguments.length===2&&!Array.isArray(args)&&(options2=args,args=[]),new Query([],args,(query2)=>{fs.readFile(path3,"utf8",(err,string)=>{if(err)return query2.reject(err);query2.strings=[string],handler2(query2)})},cancel,{...options2,simple:"simple"in options2?options2.simple:args.length===0})}}async function listen(name,fn,onlisten){let listener={fn,onlisten},sql2=listen.sql||(listen.sql=Postgres({...options,max:1,idle_timeout:null,max_lifetime:null,fetch_types:!1,onclose(){Object.entries(listen.channels).forEach(([name2,{listeners}])=>{delete listen.channels[name2],Promise.all(listeners.map((l)=>listen(name2,l.fn,l.onlisten).catch(()=>{})))})},onnotify(c,x){c in listen.channels&&listen.channels[c].listeners.forEach((l)=>l.fn(x))}})),channels=listen.channels||(listen.channels={});if(name in channels){channels[name].listeners.push(listener);let result2=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result2.state,unlisten}}channels[name]={result:sql2`listen ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`,listeners:[listener]};let result=await channels[name].result;return listener.onlisten&&listener.onlisten(),{state:result.state,unlisten};async function unlisten(){if(name in channels===!1)return;if(channels[name].listeners=channels[name].listeners.filter((x)=>x!==listener),channels[name].listeners.length)return;return delete channels[name],sql2`unlisten ${sql2.unsafe('"'+name.replace(/"/g,'""')+'"')}`}}async function notify(channel,payload){return await sql`select pg_notify(${channel}, ${""+payload})`}async function reserve(){let queue=queue_default(),c=open2.length?open2.shift():await new Promise((resolve4,reject)=>{let query={reserve:resolve4,reject};queries.push(query),closed.length&&connect(closed.shift(),query)});move(c,reserved),c.reserved=()=>queue.length?c.execute(queue.shift()):move(c,reserved),c.reserved.release=!0;let sql2=Sql(handler2);return sql2.release=()=>{c.reserved=null,onopen(c)},sql2;function handler2(q){c.queue===full?queue.push(q):c.execute(q)||move(c,full)}}async function begin(options2,fn){!fn&&(fn=options2,options2="");let queries2=queue_default(),savepoints=0,connection2,prepare=null;try{return await sql.unsafe("begin "+options2.replace(/[^a-z ]/ig,""),[],{onexecute}).execute(),await Promise.race([scope(connection2,fn),new Promise((_,reject)=>connection2.onclose=reject)])}catch(error2){throw error2}async function scope(c,fn2,name){let sql2=Sql(handler2);sql2.savepoint=savepoint,sql2.prepare=(x)=>prepare=x.replace(/[^a-z0-9$-_. ]/gi);let uncaughtError,result;name&&await sql2`savepoint ${sql2(name)}`;try{if(result=await new Promise((resolve4,reject)=>{let x=fn2(sql2);Promise.resolve(Array.isArray(x)?Promise.all(x):x).then(resolve4,reject)}),uncaughtError)throw uncaughtError}catch(e){throw await(name?sql2`rollback to ${sql2(name)}`:sql2`rollback`),e instanceof PostgresError&&e.code==="25P02"&&uncaughtError||e}if(!name)prepare?await sql2`prepare transaction '${sql2.unsafe(prepare)}'`:await sql2`commit`;return result;function savepoint(name2,fn3){if(name2&&Array.isArray(name2.raw))return savepoint((sql3)=>sql3.apply(sql3,arguments));return arguments.length===1&&(fn3=name2,name2=null),scope(c,fn3,"s"+savepoints+++(name2?"_"+name2:""))}function handler2(q){q.catch((e)=>uncaughtError||(uncaughtError=e)),c.queue===full?queries2.push(q):c.execute(q)||move(c,full)}}function onexecute(c){connection2=c,move(c,reserved),c.reserved=()=>queries2.length?c.execute(queries2.shift()):move(c,reserved)}}function move(c,queue){return c.queue.remove(c),queue.push(c),c.queue=queue,queue===open2?c.idleTimer.start():c.idleTimer.cancel(),c}function json2(x){return new Parameter(x,3802)}function array(x,type2){if(!Array.isArray(x))return array(Array.from(arguments));return new Parameter(x,type2||(x.length?inferType(x)||25:0),options.shared.typeArrayMap)}function handler(query){if(ending)return query.reject(Errors.connection("CONNECTION_ENDED",options,options));if(open2.length)return go(open2.shift(),query);if(closed.length)return connect(closed.shift(),query);busy.length?go(busy.shift(),query):queries.push(query)}function go(c,query){return c.execute(query)?move(c,busy):move(c,full)}function cancel(query){return new Promise((resolve4,reject)=>{query.state?query.active?connection_default(options).cancel(query.state,resolve4,reject):query.cancelled={resolve:resolve4,reject}:(queries.remove(query),query.cancelled=!0,query.reject(Errors.generic("57014","canceling statement due to user request")),resolve4())})}async function end({timeout=null}={}){if(ending)return ending;await 1;let timer2;return ending=Promise.race([new Promise((r)=>timeout!==null&&(timer2=setTimeout(destroy,timeout*1000,r))),Promise.all(connections.map((c)=>c.end()).concat(listen.sql?listen.sql.end({timeout:0}):[],subscribe2.sql?subscribe2.sql.end({timeout:0}):[]))]).then(()=>clearTimeout(timer2))}async function close2(){await Promise.all(connections.map((c)=>c.end()))}async function destroy(resolve4){await Promise.all(connections.map((c)=>c.terminate()));while(queries.length)queries.shift().reject(Errors.connection("CONNECTION_DESTROYED",options));resolve4()}function connect(c,query){return move(c,connecting),c.connect(query),c}function onend(c){move(c,ended)}function onopen(c){if(queries.length===0)return move(c,open2);let max=Math.ceil(queries.length/(connecting.length+1)),ready=!0;while(ready&&queries.length&&max-- >0){let query=queries.shift();if(query.reserve)return query.reserve(c);ready=c.execute(query)}ready?move(c,busy):move(c,full)}function onclose(c,e){move(c,closed),c.reserved=null,c.onclose&&(c.onclose(e),c.onclose=null),options.onclose&&options.onclose(c.id),queries.length&&connect(c,queries.shift())}}function parseOptions(a,b2){if(a&&a.shared)return a;let env=process.env,o=(!a||typeof a==="string"?b2:a)||{},{url,multihost}=parseUrl(a),query=[...url.searchParams].reduce((a2,[b3,c])=>(a2[b3]=c,a2),{}),host=o.hostname||o.host||multihost||url.hostname||env.PGHOST||"localhost",port=o.port||url.port||env.PGPORT||5432,user=o.user||o.username||url.username||env.PGUSERNAME||env.PGUSER||osUsername();o.no_prepare&&(o.prepare=!1),query.sslmode&&(query.ssl=query.sslmode,delete query.sslmode),"timeout"in o&&(console.log("The timeout option is deprecated, use idle_timeout instead"),o.idle_timeout=o.timeout),query.sslrootcert==="system"&&(query.ssl="verify-full");let ints=["idle_timeout","connect_timeout","max_lifetime","max_pipeline","backoff","keep_alive"],defaults={max:globalThis.Cloudflare?3:10,ssl:!1,sslnegotiation:null,idle_timeout:null,connect_timeout:30,max_lifetime,max_pipeline:100,backoff,keep_alive:60,prepare:!0,debug:!1,fetch_types:!0,publications:"alltables",target_session_attrs:null};return{host:Array.isArray(host)?host:host.split(",").map((x)=>x.split(":")[0]),port:Array.isArray(port)?port:host.split(",").map((x)=>parseInt(x.split(":")[1]||port)),path:o.path||host.indexOf("/")>-1&&host+"/.s.PGSQL."+port,database:o.database||o.db||(url.pathname||"").slice(1)||env.PGDATABASE||user,user,pass:o.pass||o.password||url.password||env.PGPASSWORD||"",...Object.entries(defaults).reduce((acc,[k,d])=>{let value=k in o?o[k]:(k in query)?query[k]==="disable"||query[k]==="false"?!1:query[k]:env["PG"+k.toUpperCase()]||d;return acc[k]=typeof value==="string"&&ints.includes(k)?+value:value,acc},{}),connection:{application_name:env.PGAPPNAME||"postgres.js",...o.connection,...Object.entries(query).reduce((acc,[k,v])=>((k in defaults)||(acc[k]=v),acc),{})},types:o.types||{},target_session_attrs:tsa(o,url,env),onnotice:o.onnotice,onnotify:o.onnotify,onclose:o.onclose,onparameter:o.onparameter,socket:o.socket,transform:parseTransform(o.transform||{undefined:void 0}),parameters:{},shared:{retries:0,typeArrayMap:{}},...mergeUserTypes(o.types)}}function tsa(o,url,env){let x=o.target_session_attrs||url.searchParams.get("target_session_attrs")||env.PGTARGETSESSIONATTRS;if(!x||["read-write","read-only","primary","standby","prefer-standby"].includes(x))return x;throw Error("target_session_attrs "+x+" is not supported")}function backoff(retries){return(0.5+Math.random()/2)*Math.min(3**retries/100,20)}function max_lifetime(){return 60*(30+Math.random()*30)}function parseTransform(x){return{undefined:x.undefined,column:{from:typeof x.column==="function"?x.column:x.column&&x.column.from,to:x.column&&x.column.to},value:{from:typeof x.value==="function"?x.value:x.value&&x.value.from,to:x.value&&x.value.to},row:{from:typeof x.row==="function"?x.row:x.row&&x.row.from,to:x.row&&x.row.to}}}function parseUrl(url){if(!url||typeof url!=="string")return{url:{searchParams:new Map}};let host=url;host=host.slice(host.indexOf("://")+3).split(/[?/]/)[0],host=decodeURIComponent(host.slice(host.indexOf("@")+1));let urlObj=new URL(url.replace(host,host.split(",")[0]));return{url:{username:decodeURIComponent(urlObj.username),password:decodeURIComponent(urlObj.password),host:urlObj.host,hostname:urlObj.hostname,port:urlObj.port,pathname:urlObj.pathname,searchParams:urlObj.searchParams},multihost:host.indexOf(",")>-1&&host}}function osUsername(){try{return os.userInfo().username}catch(_){return process.env.USERNAME||process.env.USER||process.env.LOGNAME}}var src_default;var init_src=__esm(()=>{init_types3();init_connection();init_query();init_queue();init_errors3();init_large();Object.assign(Postgres,{PostgresError,toPascal,pascal,toCamel,camel,toKebab,kebab,fromPascal,fromCamel,fromKebab,BigInt:{to:20,from:[20],parse:(x)=>BigInt(x),serialize:(x)=>x.toString()}});src_default=Postgres});var exports_db={};__export(exports_db,{shutdown:()=>shutdown,isAvailable:()=>isAvailable2,getLockfilePath:()=>getLockfilePath,getDataDir:()=>getDataDir,getConnection:()=>getConnection,getActivePort:()=>getActivePort,ensurePgserve:()=>ensurePgserve});import{execSync as execSync3}from"child_process";import{existsSync as existsSync15,mkdirSync as mkdirSync6,readFileSync as readFileSync8,renameSync,unlinkSync as unlinkSync3,writeFileSync as writeFileSync5}from"fs";import{createConnection}from"net";import{homedir as homedir14}from"os";import{join as join18}from"path";function maskCredentials(url){return url.replace(/\/\/.*@/,"//***@")}function killOrphanedPostgres(dataDir){let pidFile=join18(dataDir,"postmaster.pid");if(!existsSync15(pidFile))return;try{let content=readFileSync8(pidFile,"utf-8"),pid=Number.parseInt(content.split(`
|
|
163
|
+
`)[0],10);if(Number.isNaN(pid)||pid<=0)return;let cmdline;try{cmdline=execSync3(`ps -o command= -p ${pid} 2>/dev/null`,{encoding:"utf-8"}).trim()}catch{return}if(!cmdline.includes("postgres"))return;try{process.kill(pid,"SIGTERM")}catch{return}let deadline=Date.now()+5000;while(Date.now()<deadline)try{process.kill(pid,0),execSync3("sleep 0.2",{stdio:"ignore"})}catch{return}try{process.kill(pid,"SIGKILL")}catch{}}catch{}}function getPort(){let envPort=process.env.GENIE_PG_PORT;if(envPort){let parsed=Number.parseInt(envPort,10);if(!Number.isNaN(parsed)&&parsed>0&&parsed<65536)return parsed}return DEFAULT_PORT}function isPortListening(port,host){return new Promise((resolve4)=>{let socket=createConnection({port,host},()=>{socket.destroy(),resolve4(!0)});socket.on("error",()=>{socket.destroy(),resolve4(!1)}),socket.setTimeout(1000,()=>{socket.destroy(),resolve4(!1)})})}function readLockfile(){try{let content=readFileSync8(LOCKFILE_PATH,"utf-8").trim(),port=Number.parseInt(content,10);if(!Number.isNaN(port)&&port>0&&port<65536)return port}catch{}return null}function writeLockfile(port){try{mkdirSync6(GENIE_HOME2,{recursive:!0});let tmpPath=`${LOCKFILE_PATH}.tmp.${process.pid}`;writeFileSync5(tmpPath,String(port),"utf-8"),renameSync(tmpPath,LOCKFILE_PATH)}catch{}}function removeLockfile(){try{unlinkSync3(LOCKFILE_PATH)}catch{}}async function ensurePgserve(){if(ensurePromise)return ensurePromise;ensurePromise=_ensurePgserve();try{return await ensurePromise}finally{ensurePromise=null}}async function _ensurePgserve(){if(activePort!==null&&pgserveServer)return activePort;if(activePort!==null)return activePort;let port=getPort(),reusedPort=await tryReuseLockfile();if(reusedPort!==null)return reusedPort;if(await isPortListening(port,DEFAULT_HOST))return markPortActive(port,!0);mkdirSync6(DATA_DIR,{recursive:!0}),killOrphanedPostgres(DATA_DIR);try{let startedPort=await startPgserveOnPort(port);return registerExitHandler(),startedPort}catch(err){return tryFallbackPorts(port,err)}}async function tryReuseLockfile(){let lockfilePort=readLockfile();if(lockfilePort===null)return null;if(await isPortListening(lockfilePort,DEFAULT_HOST))return markPortActive(lockfilePort,!1);return removeLockfile(),null}function markPortActive(port,writeLock){if(activePort=port,process.env.GENIE_PG_AVAILABLE="true",writeLock)writeLockfile(port);return port}async function tryFallbackPorts(basePort,originalErr){for(let offset=1;offset<=MAX_PORT_RETRIES;offset++){let fallbackPort=basePort+offset;if(await isPortListening(fallbackPort,DEFAULT_HOST))return markPortActive(fallbackPort,!0);try{let startedPort=await startPgserveOnPort(fallbackPort);return registerExitHandler(),startedPort}catch{}}process.env.GENIE_PG_AVAILABLE="false";let message=originalErr instanceof Error?originalErr.message:String(originalErr);throw console.warn(`Warning: pgserve failed to start: ${maskCredentials(message)}`),Error(`pgserve failed to start on port ${basePort} (and fallbacks ${basePort+1}-${basePort+MAX_PORT_RETRIES}): ${maskCredentials(message)}`)}async function startPgserveOnPort(port){let{startMultiTenantServer}=await import("pgserve");return pgserveServer=await startMultiTenantServer({port,host:DEFAULT_HOST,baseDir:DATA_DIR,logLevel:"warn",autoProvision:!0}),activePort=port,ownsLockfile=!0,process.env.GENIE_PG_AVAILABLE="true",writeLockfile(port),port}function registerExitHandler(){if(exitHandlerRegistered)return;exitHandlerRegistered=!0;let cleanup=()=>{if(ownsLockfile)removeLockfile(),ownsLockfile=!1};process.on("exit",cleanup),process.on("SIGINT",()=>{cleanup(),process.exit(130)}),process.on("SIGTERM",()=>{cleanup(),process.exit(143)})}function migrationsDone(){try{let marker=readFileSync8(MIGRATION_MARKER,"utf-8").trim(),currentVersion=process.env.npm_package_version??"";return marker===currentVersion||currentVersion===""&&marker.length>0}catch{return!1}}function markMigrationsDone(){try{let version=process.env.npm_package_version??Date.now().toString();writeFileSync5(MIGRATION_MARKER,version,"utf-8")}catch{}}async function getConnection(){if(sqlClient)return sqlClient;let port=await ensurePgserve(),postgres2=(await Promise.resolve().then(() => (init_src(),exports_src))).default;if(sqlClient=postgres2({host:DEFAULT_HOST,port,database:DB_NAME,username:"postgres",password:"postgres",max:10,idle_timeout:1,connect_timeout:5}),!migrationsDone())await runMigrations(sqlClient),markMigrationsDone();return sqlClient}async function isAvailable2(){try{return await(await getConnection())`SELECT 1`,!0}catch{return!1}}async function shutdown(){if(sqlClient)await sqlClient.end({timeout:5}),sqlClient=null;if(ownsLockfile)removeLockfile(),ownsLockfile=!1}function getDataDir(){return DATA_DIR}function getActivePort(){return activePort??getPort()}function getLockfilePath(){return LOCKFILE_PATH}var DEFAULT_PORT=19642,DEFAULT_HOST="127.0.0.1",MAX_PORT_RETRIES=3,GENIE_HOME2,DATA_DIR,LOCKFILE_PATH,MIGRATION_MARKER,DB_NAME="genie",pgserveServer=null,sqlClient=null,activePort=null,ensurePromise=null,ownsLockfile=!1,exitHandlerRegistered=!1;var init_db=__esm(()=>{init_db_migrations();GENIE_HOME2=process.env.GENIE_HOME??join18(homedir14(),".genie"),DATA_DIR=join18(GENIE_HOME2,"data","pgserve"),LOCKFILE_PATH=join18(GENIE_HOME2,"pgserve.port"),MIGRATION_MARKER=join18(GENIE_HOME2,"pgserve.migrated")});var exports_wish_state={};__export(exports_wish_state,{startGroup:()=>startGroup,resolveRepoPath:()=>resolveRepoPath,resetGroup:()=>resetGroup,getState:()=>getState,getOrCreateState:()=>getOrCreateState,getGroupState:()=>getGroupState,findGroupByAssignee:()=>findGroupByAssignee,findAnyGroupByAssignee:()=>findAnyGroupByAssignee,createState:()=>createState,completeGroup:()=>completeGroup,WishStateSchema:()=>WishStateSchema,GroupStatusSchema:()=>GroupStatusSchema,GroupStateSchema:()=>GroupStateSchema});import{execSync as execSync4}from"child_process";import{dirname as dirname5}from"path";function resolveRepoPath(cwd){if(cwd)return cwd;try{let commonDir=execSync4("git rev-parse --path-format=absolute --git-common-dir",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return dirname5(commonDir)}catch{return process.cwd()}}function wishFilePath(slug){return`.genie/wishes/${slug}/WISH.md`}function toISO(v){if(v==null)return;if(v instanceof Date)return v.toISOString();return String(v)}async function findParent(sql,slug,repoPath){let wishFile=wishFilePath(slug),rows=await sql`
|
|
166
164
|
SELECT * FROM tasks
|
|
167
165
|
WHERE wish_file = ${wishFile} AND repo_path = ${repoPath} AND parent_id IS NULL
|
|
168
166
|
LIMIT 1
|
|
@@ -239,7 +237,15 @@ ${errCtx.stack}`;d.reject(err)}else d.resolve(msg)}});return sub.requestSubject=
|
|
|
239
237
|
`,depsMap={};for(let dep of deps){let taskId=dep.task_id;if(!depsMap[taskId])depsMap[taskId]=[];depsMap[taskId].push(dep.dep_group)}let actors=await sql`
|
|
240
238
|
SELECT task_id, actor_id FROM task_actors
|
|
241
239
|
WHERE task_id = ANY(${childIds}) AND role = 'assignee'
|
|
242
|
-
`,assigneeMap={};for(let actor of actors)assigneeMap[actor.task_id]=actor.actor_id;let groups={};for(let child of children){let{id,group_name:groupName}=child;groups[groupName]={status:child.status,assignee:assigneeMap[id],dependsOn:depsMap[id]??[],startedAt:toISO(child.started_at),completedAt:toISO(child.ended_at)}}return{wish:slug,groups,createdAt:toISO(parent.created_at)??"",updatedAt:toISO(parent.updated_at)??""}}async function getGroupState(slug,groupName,cwd){let state2=await getState(slug,cwd);if(!state2)return null;return state2.groups[groupName]??null}var GroupStatusSchema,GroupStateSchema,WishStateSchema;var init_wish_state=__esm(()=>{init_zod();init_db();GroupStatusSchema=exports_external.enum(["blocked","ready","in_progress","done"]),GroupStateSchema=exports_external.object({status:GroupStatusSchema,assignee:exports_external.string().optional(),dependsOn:exports_external.array(exports_external.string()).default([]),startedAt:exports_external.string().optional(),completedAt:exports_external.string().optional()}),WishStateSchema=exports_external.object({wish:exports_external.string(),groups:exports_external.record(exports_external.string(),GroupStateSchema),createdAt:exports_external.string(),updatedAt:exports_external.string()})});var
|
|
240
|
+
`,assigneeMap={};for(let actor of actors)assigneeMap[actor.task_id]=actor.actor_id;let groups={};for(let child of children){let{id,group_name:groupName}=child;groups[groupName]={status:child.status,assignee:assigneeMap[id],dependsOn:depsMap[id]??[],startedAt:toISO(child.started_at),completedAt:toISO(child.ended_at)}}return{wish:slug,groups,createdAt:toISO(parent.created_at)??"",updatedAt:toISO(parent.updated_at)??""}}async function getGroupState(slug,groupName,cwd){let state2=await getState(slug,cwd);if(!state2)return null;return state2.groups[groupName]??null}var GroupStatusSchema,GroupStateSchema,WishStateSchema;var init_wish_state=__esm(()=>{init_zod();init_db();GroupStatusSchema=exports_external.enum(["blocked","ready","in_progress","done"]),GroupStateSchema=exports_external.object({status:GroupStatusSchema,assignee:exports_external.string().optional(),dependsOn:exports_external.array(exports_external.string()).default([]),startedAt:exports_external.string().optional(),completedAt:exports_external.string().optional()}),WishStateSchema=exports_external.object({wish:exports_external.string(),groups:exports_external.record(exports_external.string(),GroupStateSchema),createdAt:exports_external.string(),updatedAt:exports_external.string()})});var exports_protocol_router_spawn={};__export(exports_protocol_router_spawn,{spawnWorkerFromTemplate:()=>spawnWorkerFromTemplate,injectResumeContext:()=>injectResumeContext});import{exec as exec2}from"child_process";import{readFile as readFile6}from"fs/promises";import{join as join19}from"path";import{promisify as promisify2}from"util";async function resolveParentSession(_repoPath,team){let teamConfig=await getTeam2(team);if(teamConfig?.nativeTeamParentSessionId)return teamConfig.nativeTeamParentSessionId;return await discoverClaudeSessionId()??`genie-${team}`}function buildSpawnParams(template,parentSessionId,spawnColor,resumeSessionId){let isClaude=template.provider==="claude",sessionName=template.role?`${template.team}-${template.role}`:void 0,newSessionId=isClaude&&!resumeSessionId?crypto.randomUUID():void 0,params={provider:template.provider,team:template.team,role:template.role,skill:template.skill,extraArgs:template.extraArgs,sessionId:newSessionId,resume:isClaude?resumeSessionId:void 0,name:sessionName};if(isClaude)params.nativeTeam={enabled:!0,parentSessionId,color:spawnColor,agentType:template.role??"general-purpose",agentName:template.role};return params}function buildFullCommand(launch){if(launch.env&&Object.keys(launch.env).length>0)return`env ${Object.entries(launch.env).map(([k,v])=>`${k}=${v}`).join(" ")} ${launch.command}`;return launch.command}async function generateWorkerId(team,role){let base=role?`${team}-${role}`:team;return(await list()).some((w)=>w.id===base)?`${base}-${crypto.randomUUID().slice(0,8)}`:base}async function spawnPaneInSession(session,team,repoPath,fullCommand){let teamWindow=null;try{teamWindow=await ensureTeamWindow(session,team,repoPath)}catch{}let splitTarget=teamWindow?`-t '${teamWindow.windowId}'`:"",{stdout}=await execAsync(`tmux split-window -d ${splitTarget} -P -F '#{pane_id}' ${fullCommand}`),paneId=stdout.trim(),layoutTarget=`${session}:${teamWindow?.windowName??""}`;if(!teamWindow){let wins=await listWindows(session);layoutTarget=wins[0]?wins[0].id:`${session}:`}try{await execAsync(`tmux ${buildLayoutCommand(layoutTarget,resolveLayoutMode())}`)}catch{}return{paneId,teamWindow}}async function spawnWorkerFromTemplate(template,resumeSessionId){let repoPath=template.cwd??process.cwd(),team=template.team,parentSessionId=await resolveParentSession(repoPath,team);await ensureNativeTeam(team,`Genie team: ${team}`,parentSessionId);let spawnColor=await assignColor(team),params=buildSpawnParams(template,parentSessionId,spawnColor,resumeSessionId),launch=buildLaunchCommand(validateSpawnParams(params)),fullCommand=buildFullCommand(launch),workerId=await generateWorkerId(team,template.role),session=await getCurrentSessionName()??team,{paneId,teamWindow}=await spawnPaneInSession(session,team,repoPath,fullCommand),now=new Date().toISOString(),agentName=template.role??"worker",isClaude=template.provider==="claude",effectiveSessionId=resumeSessionId??params.sessionId,workerEntry={id:workerId,paneId,session,provider:template.provider,transport:"tmux",role:template.role,skill:template.skill,team,worktree:null,startedAt:now,state:"spawning",lastStateChange:now,repoPath,claudeSessionId:effectiveSessionId,nativeTeamEnabled:isClaude,nativeAgentId:`${agentName}@${team}`,nativeColor:spawnColor,parentSessionId,window:teamWindow?.windowName,windowName:teamWindow?.windowName,windowId:teamWindow?.windowId};if(await register(workerEntry),await registerNativeMember(team,{agentName,agentType:template.role??"general-purpose",color:spawnColor??"blue",tmuxPaneId:paneId,cwd:repoPath}),await writeNativeInbox(team,"team-lead",{from:agentName,text:`Worker ${agentName} (${template.provider}) auto-spawned${resumeSessionId?" with --resume":""}. Ready for tasks.`,summary:`${agentName} auto-spawned`,timestamp:now,color:spawnColor??"blue",read:!1}),spawnColor)await applyPaneColor(paneId,spawnColor,teamWindow?.windowId);return await injectResumeContext(repoPath,workerId,agentName,team),{worker:workerEntry,paneId,workerId}}function extractGroupSection(content,groupName){let escaped=groupName.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),pattern=new RegExp(`^### Group ${escaped}:`,"m"),match=content.match(pattern);if(!match||match.index===void 0)return null;let start=match.index,nextBoundary=content.slice(start).slice(1).search(/^### Group \d|^---$/m),end=nextBoundary!==-1?start+1+nextBoundary:content.length;return content.slice(start,end).trim()}async function getRecentGitLog(repoPath,count=3){try{let{stdout}=await execAsync(`git -C '${repoPath}' log --oneline -${count} 2>/dev/null`);return stdout.trim()}catch{return""}}async function getGitStatus(repoPath){try{let{stdout}=await execAsync(`git -C '${repoPath}' status --short 2>/dev/null`);return stdout.trim()}catch{return""}}async function injectResumeContext(repoPath,workerId,agentName,_team){try{let match=await findAnyGroupByAssignee(workerId,repoPath)??await findAnyGroupByAssignee(agentName,repoPath);if(!match)return;let{slug,groupName,group}=match,wishPath=join19(repoPath,".genie","wishes",slug,"WISH.md"),groupSection="";try{let wishContent=await readFile6(wishPath,"utf-8");groupSection=extractGroupSection(wishContent,groupName)??""}catch{}let gitLog=await getRecentGitLog(repoPath),gitStatus=await getGitStatus(repoPath),resumePrompt=[`RESUME CONTEXT: You were working on wish "${slug}", group "${groupName}".`,`Status: ${group.status}. Started at: ${group.startedAt??"unknown"}.`,`Wish file: .genie/wishes/${slug}/WISH.md`,"",groupSection?`Group section:
|
|
241
|
+
${groupSection}`:"","",gitLog?`Last git log:
|
|
242
|
+
${gitLog}`:"","",gitStatus?`Uncommitted changes:
|
|
243
|
+
${gitStatus}`:"","","Pick up where you left off. Read the wish file for full context."].filter(Boolean).join(`
|
|
244
|
+
`);await send(repoPath,"genie",workerId,resumePrompt)}catch{}}var execAsync;var init_protocol_router_spawn=__esm(()=>{init_agent_registry();init_claude_native_teams();init_mailbox();init_provider_adapters();init_team_manager();init_tmux();init_wish_state();execAsync=promisify2(exec2)});function stripAnsi(str2){return str2.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,"")}function matchPatterns(content,patterns){let cleanContent=stripAnsi(content),matches=[];for(let pattern of patterns){let regex=new RegExp(pattern.pattern.source,pattern.pattern.flags||"g"),match=regex.exec(cleanContent);while(match!==null){if(matches.push({type:pattern.type,match,extracted:pattern.extract?pattern.extract(match):void 0}),!pattern.pattern.flags?.includes("g"))break;match=regex.exec(cleanContent)}}return matches}function hasMatch(content,patterns){return matchPatterns(content,patterns).length>0}function getFirstMatch(content,patterns){let matches=matchPatterns(content,patterns);return matches.length>0?matches[0]:null}var permissionPatterns,questionPatterns,errorPatterns,completionPatterns,workingPatterns,idlePatterns,toolUsePatterns;var init_patterns=__esm(()=>{permissionPatterns=[{type:"bash_permission",pattern:/Allow (?:Bash|bash|command|shell).*\?\s*(?:\[([YyNn])\/([YyNn])\])?/i,extract:(match)=>({default:match[1]||"y"})},{type:"file_permission",pattern:/Allow (?:Edit|Write|Read|file|reading|writing|editing).*\?\s*(?:\[([YyNn])\/([YyNn])\])?/i,extract:(match)=>({default:match[1]||"y"})},{type:"mcp_permission",pattern:/Allow (?:MCP|mcp|tool).*\?\s*(?:\[([YyNn])\/([YyNn])\])?/i,extract:(match)=>({default:match[1]||"y"})},{type:"generic_permission",pattern:/^(?:Allow|Confirm|Approve)\s+(?:this|the|once|always)?\s*(?:\w+)?\s*\?\s*(?:\[([YyNn])\/([YyNn])\])?/im,extract:(match)=>({default:match[1]||"y"})},{type:"claude_code_yes_no",pattern:/(?:Yes|No)\s*$/m},{type:"claude_code_permission_block",pattern:/(?:Allow|Run|Execute)\s+(?:once|always)/i}],questionPatterns=[{type:"numbered_options",pattern:/\[(\d+)\]\s+(.+?)(?=\[(\d+)\]|$)/g,extract:(match)=>({number:match[1],option:match[2].trim()})},{type:"lettered_options",pattern:/\(([a-z])\)\s+(.+?)(?=\([a-z]\)|$)/gi,extract:(match)=>({letter:match[1],option:match[2].trim()})},{type:"yes_no_question",pattern:/\?\s*\[([YyNn])\/([YyNn])\]\s*$/,extract:(match)=>({default:match[1]})},{type:"claude_code_numbered_options",pattern:/(?:\u276F|>)?\s*(\d+)\.\s+(.+?)(?:\n|$)/g,extract:(match)=>({number:match[1],option:match[2].trim()})},{type:"claude_code_plan_approval",pattern:/Would you like to proceed\?/i}],errorPatterns=[{type:"error",pattern:/(?:^|\n)\s*(?:Error|ERROR|error):\s*(.+)/,extract:(match)=>({message:match[1]})},{type:"failed",pattern:/(?:^|\n)\s*(?:Failed|FAILED|failed):\s*(.+)/,extract:(match)=>({message:match[1]})},{type:"exception",pattern:/(?:^|\n)\s*(?:Exception|EXCEPTION|Uncaught|Unhandled):\s*(.+)/,extract:(match)=>({message:match[1]})},{type:"api_error",pattern:/(?:API|api)\s+(?:error|Error|ERROR):\s*(.+)/,extract:(match)=>({message:match[1]})}],completionPatterns=[{type:"checkmark",pattern:/(?:\u2713|\u2714|\u2611\uFE0E)/},{type:"success_message",pattern:/(?:Successfully|Completed|Done|Finished|Created|Updated|Saved)/i},{type:"task_complete",pattern:/(?:task|operation|process)\s+(?:complete|completed|finished|done)/i}],workingPatterns=[{type:"thinking",pattern:/(?:Thinking|thinking|Processing|processing)\.\.\./},{type:"spinner",pattern:/[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F\u28FE\u28FD\u28FB\u28BF\u287F\u28DF\u28EF\u28F7]/},{type:"loading",pattern:/(?:Loading|loading|Working|working)\.\.\./},{type:"claude_code_working",pattern:/(?:\uD83D\uDEE0\uFE0F|\uD83D\uDD27|\u2699\uFE0F)\s*(?:Read|Edit|Write|Bash|Glob|Grep|Task)/u},{type:"claude_code_streaming",pattern:/\u258C$/},{type:"claude_code_propagating",pattern:/Propagating\u2026/}],idlePatterns=[{type:"claude_prompt",pattern:/(?:^|\n)\s*>\s*$/},{type:"claude_code_prompt",pattern:/\u276F\s*(?!\d\.)/},{type:"claude_code_input_line",pattern:/\u276F\s*.+\n\u2500+\n/},{type:"idle_indicator",pattern:/\|\s*idle\s*$/i},{type:"input_prompt",pattern:/(?:^|\n)(?:Enter|Input|Type|Provide).*:\s*$/i}],toolUsePatterns=[{type:"run_command",pattern:/(?:Run|Running|Executing)\s+(?:command|bash):\s*(.+)/i,extract:(match)=>({command:match[1]})},{type:"read_file",pattern:/(?:Read|Reading)\s+(?:file):\s*(.+)/i,extract:(match)=>({file:match[1]})},{type:"write_file",pattern:/(?:Write|Writing|Edit|Editing)\s+(?:file|to):\s*(.+)/i,extract:(match)=>({file:match[1]})},{type:"search",pattern:/(?:Search|Searching|Grep|Glob)(?:ing)?:\s*(.+)/i,extract:(match)=>({query:match[1]})}]});function detectQuestionState(questionMatches,hasPlanApproval,baseState){if(questionMatches.length===0&&!hasPlanApproval)return null;let menuOptions=questionMatches.filter((m)=>m.type==="claude_code_numbered_options"&&m.extracted?.option).map((m)=>m.extracted?.option).filter((o)=>o!==void 0);if(menuOptions.length>=2||hasPlanApproval)return{...baseState,type:"question",options:menuOptions.length>0?menuOptions:void 0,detail:hasPlanApproval?"plan_approval":void 0,confidence:0.85};let otherOptions=questionMatches.filter((m)=>m.extracted?.option&&m.type!=="claude_code_numbered_options").map((m)=>m.extracted?.option).filter((o)=>o!==void 0);if(otherOptions.length>=2)return{...baseState,type:"question",options:otherOptions,confidence:0.85};return null}function detectState(output,options={}){let{linesToAnalyze=50,minConfidence=0.3}=options,lines=output.split(`
|
|
245
|
+
`),recentLines=lines.slice(-linesToAnalyze).join(`
|
|
246
|
+
`),cleanOutput=stripAnsi(recentLines),baseState={timestamp:Date.now(),rawOutput:recentLines},permissionMatch=getFirstMatch(cleanOutput,permissionPatterns);if(permissionMatch)return{...baseState,type:"permission",detail:permissionMatch.type.replace("_permission",""),confidence:0.9};let hasPlanApproval=hasMatch(cleanOutput,questionPatterns.filter((p)=>p.type==="claude_code_plan_approval")),cleanMenuLines=stripAnsi(lines.slice(-15).join(`
|
|
247
|
+
`)),questionMatches=matchPatterns(cleanMenuLines,questionPatterns),questionState=detectQuestionState(questionMatches,hasPlanApproval,baseState);if(questionState)return questionState;let ynMatch=questionMatches.find((m)=>m.type==="yes_no_question");if(ynMatch)return{...baseState,type:"question",options:["Yes","No"],detail:`default: ${ynMatch.extracted?.default||"y"}`,confidence:0.85};let errorMatch=getFirstMatch(cleanOutput,errorPatterns);if(errorMatch)return{...baseState,type:"error",detail:errorMatch.extracted?.message||errorMatch.match[0],confidence:0.8};let toolMatch=getFirstMatch(cleanOutput,toolUsePatterns);if(toolMatch)return{...baseState,type:"tool_use",detail:`${toolMatch.type}: ${toolMatch.extracted?.command||toolMatch.extracted?.file||toolMatch.extracted?.query||""}`,confidence:0.75};if(hasMatch(cleanOutput,workingPatterns))return{...baseState,type:"working",confidence:0.7};if(hasMatch(cleanOutput,completionPatterns))return{...baseState,type:"complete",confidence:0.6};let cleanLastLines=stripAnsi(lines.slice(-5).join(`
|
|
248
|
+
`));if(hasMatch(cleanLastLines,idlePatterns))return{...baseState,type:"idle",confidence:0.7};let trimmedLast=cleanLastLines.trim();if(trimmedLast.endsWith(">")||trimmedLast.match(/>\s*$/))return{...baseState,type:"idle",detail:"prompt detected",confidence:0.65};return{...baseState,type:"unknown",confidence:minConfidence}}var init_state_detector=__esm(()=>{init_patterns()});var init_orchestrator=__esm(()=>{init_patterns();init_state_detector()});async function waitForAgentReady(paneId,opts){let timeoutMs=opts?.timeoutMs??(process.env.GENIE_SPAWN_TIMEOUT_MS?Number(process.env.GENIE_SPAWN_TIMEOUT_MS):DEFAULT_SPAWN_TIMEOUT_MS),pollIntervalMs=opts?.pollIntervalMs??READINESS_POLL_INTERVAL_MS,start=Date.now();while(Date.now()-start<timeoutMs){try{let content=await capturePaneContent(paneId,50);if(content){let state2=detectState(content);if(state2.type==="idle"||state2.type==="tool_use")return{ready:!0,elapsedMs:Date.now()-start}}}catch{}await new Promise((r)=>setTimeout(r,pollIntervalMs))}return{ready:!1,elapsedMs:Date.now()-start}}var DEFAULT_SPAWN_TIMEOUT_MS=30000,READINESS_POLL_INTERVAL_MS=2000;var init_spawn_command=__esm(()=>{init_orchestrator();init_tmux()});var exports_inject={};__export(exports_inject,{isTeamHooked:()=>isTeamHooked,injectTeamHooks:()=>injectTeamHooks});import{existsSync as existsSync16}from"fs";import{mkdir as mkdir7,readFile as readFile7,writeFile as writeFile6}from"fs/promises";import{homedir as homedir15}from"os";import{join as join20}from"path";function claudeConfigDir2(){return process.env.CLAUDE_CONFIG_DIR??join20(homedir15(),".claude")}function teamSettingsPath(teamName){let sanitized=teamName.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase();return join20(claudeConfigDir2(),"teams",sanitized,"settings.json")}function buildHooksConfig(){let hooks={};for(let event of DISPATCHED_EVENTS)hooks[event]=[{hooks:[{type:"command",command:DISPATCH_COMMAND,timeout:DISPATCH_TIMEOUT}]}];return hooks}async function injectIntoFile(settingsPath){let settings={};if(existsSync16(settingsPath))try{let content=await readFile7(settingsPath,"utf-8");settings=JSON.parse(content)}catch{}let hooksConfig=buildHooksConfig(),existingHooks=settings.hooks;if(existingHooks){if(DISPATCHED_EVENTS.every((event)=>{return existingHooks[event]?.some((m)=>m.hooks?.some((h)=>h.command===DISPATCH_COMMAND))}))return!1}let mergedHooks=existingHooks?{...existingHooks}:{};for(let event of DISPATCHED_EVENTS){let genieEntry=hooksConfig[event][0],existingEntries=mergedHooks[event]??[];if(!existingEntries.some((m)=>m.hooks?.some((h)=>h.command===DISPATCH_COMMAND)))mergedHooks[event]=[...existingEntries,genieEntry]}settings.hooks=mergedHooks;let dir=join20(settingsPath,"..");return await mkdir7(dir,{recursive:!0}),await writeFile6(settingsPath,JSON.stringify(settings,null,2)),!0}async function injectTeamHooks(teamName){let path3=teamSettingsPath(teamName);return injectIntoFile(path3)}async function isTeamHooked(teamName){let path3=teamSettingsPath(teamName);if(!existsSync16(path3))return!1;try{let content=await readFile7(path3,"utf-8"),hooks=JSON.parse(content).hooks;if(!hooks)return!1;return DISPATCHED_EVENTS.every((event)=>{return hooks[event]?.some((m)=>m.hooks?.some((h)=>h.command===DISPATCH_COMMAND))})}catch{return!1}}var DISPATCH_COMMAND="genie hook dispatch",DISPATCH_TIMEOUT=15;var init_inject=__esm(()=>{init_types2()});var exports_idle_timeout={};__export(exports_idle_timeout,{suspendWorker:()=>suspendWorker,getIdleTimeoutMs:()=>getIdleTimeoutMs,checkIdleWorkers:()=>checkIdleWorkers,WATCHDOG_POLL_INTERVAL_MS:()=>WATCHDOG_POLL_INTERVAL_MS});function getIdleTimeoutMs(){let env=process.env.GENIE_IDLE_TIMEOUT_MS;if(env!==void 0){if(env==="")return DEFAULT_IDLE_TIMEOUT_MS;let parsed=Number(env);if(!Number.isNaN(parsed)&&parsed>=0)return parsed}return DEFAULT_IDLE_TIMEOUT_MS}async function suspendWorker(workerId,deps=defaultDeps){let worker=await deps.registryGet(workerId);if(!worker)return!1;if(worker.state==="suspended")return!0;if(worker.paneId&&worker.paneId!=="inline")try{await deps.executeTmux(`kill-pane -t '${worker.paneId}'`)}catch{}return await deps.registryUpdate(workerId,{state:"suspended",suspendedAt:new Date().toISOString()}),!0}async function checkIdleWorkers(deps=defaultDeps){let timeoutMs=getIdleTimeoutMs();if(timeoutMs===0)return[];let workers=await deps.registryList(),suspended=[];for(let w of workers){if(w.state!=="idle")continue;if(Date.now()-new Date(w.lastStateChange).getTime()<timeoutMs)continue;if(!await deps.isPaneAlive(w.paneId)){await deps.registryUpdate(w.id,{state:"suspended",suspendedAt:new Date().toISOString()}),suspended.push(w.id);continue}if(await suspendWorker(w.id,deps))suspended.push(w.id)}return suspended}var defaultDeps,DEFAULT_IDLE_TIMEOUT_MS=1800000,WATCHDOG_POLL_INTERVAL_MS=60000;var init_idle_timeout=__esm(()=>{init_agent_registry();init_tmux();defaultDeps={registryGet:get,registryList:list,registryUpdate:update,executeTmux:executeTmux2,isPaneAlive}});var exports_agents={};__export(exports_agents,{handleWorkerStop:()=>handleWorkerStop,handleWorkerSpawn:()=>handleWorkerSpawn,handleWorkerResume:()=>handleWorkerResume,handleWorkerKill:()=>handleWorkerKill,handleLsCommand:()=>handleLsCommand,buildResumeContext:()=>buildResumeContext});function isRelayAlive(pidFile){let{readFileSync:readFileSync9,existsSync:existsSync17}=__require("fs");if(!existsSync17(pidFile))return!1;try{let pid=Number.parseInt(readFileSync9(pidFile,"utf-8").trim());if(pid>0)return process.kill(pid,0),!0}catch{}return!1}async function ensureOtelRelay(team){let{writeFileSync:writeFileSync6,mkdirSync:mkdirSync7}=__require("fs"),{join:join21}=__require("path"),{homedir:homedir16}=__require("os"),relayDir=join21(homedir16(),".genie","relay");mkdirSync7(relayDir,{recursive:!0});let pidFile=join21(relayDir,"otel-relay.pid"),scriptFile=join21(relayDir,"otel-relay.mjs");if(isRelayAlive(pidFile))return!0;let inboxDir=join21(process.env.CLAUDE_CONFIG_DIR??join21(homedir16(),".claude"),"teams",team,"inboxes"),escapedRelayDir=relayDir.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),escapedInboxDir=inboxDir.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),escapedPidFile=pidFile.replace(/\\/g,"\\\\").replace(/'/g,"\\'");try{writeFileSync6(scriptFile,`import { createServer } from 'http';
|
|
243
249
|
import { execSync } from 'child_process';
|
|
244
250
|
import { readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync, statSync } from 'fs';
|
|
245
251
|
import { createHash } from 'crypto';
|
|
@@ -513,13 +519,13 @@ server.listen(PORT, '127.0.0.1', () => {
|
|
|
513
519
|
|
|
514
520
|
process.on('SIGTERM', () => { server.close(); process.exit(0); });
|
|
515
521
|
process.on('SIGINT', () => { server.close(); process.exit(0); });
|
|
516
|
-
`,{mode:420});let{spawn:spawnChild}=__require("child_process");spawnChild("node",[scriptFile],{detached:!0,stdio:"ignore"}).unref();for(let i2=0;i2<30;i2++)if(await new Promise((r)=>setTimeout(r,100)),isRelayAlive(pidFile))return!0;return!1}catch{return!1}}async function
|
|
522
|
+
`,{mode:420});let{spawn:spawnChild}=__require("child_process");spawnChild("node",[scriptFile],{detached:!0,stdio:"ignore"}).unref();for(let i2=0;i2<30;i2++)if(await new Promise((r)=>setTimeout(r,100)),isRelayAlive(pidFile))return!0;return!1}catch{return!1}}async function generateWorkerId2(team,role){let base=role?`${team}-${role}`:team;if(!(await list()).some((w)=>w.id===base))return base;let suffix=crypto.randomUUID().slice(0,8);return`${base}-${suffix}`}async function registerSpawnWorker(ctx,paneId,windowInfo){let nt=ctx.validated.nativeTeam,workerEntry={id:ctx.workerId,paneId,session:ctx.validated.team,provider:ctx.validated.provider,transport:ctx.transport,role:ctx.validated.role,skill:ctx.validated.skill,team:ctx.validated.team,worktree:null,startedAt:ctx.now,state:"spawning",lastStateChange:ctx.now,repoPath:ctx.cwd,claudeSessionId:ctx.claudeSessionId,nativeTeamEnabled:nt?.enabled??!1,nativeAgentId:`${ctx.agentName}@${ctx.validated.team}`,nativeColor:nt?.color??ctx.spawnColor,parentSessionId:nt?.parentSessionId??ctx.parentSessionId,window:windowInfo?.windowName,windowName:windowInfo?.windowName,windowId:windowInfo?.windowId,autoResume:ctx.autoResume===!1?!1:void 0,resumeAttempts:0};await register(workerEntry);let role=ctx.validated.role??ctx.agentName;if(role!=="council")try{await hireAgent(ctx.validated.team,role)}catch{}return workerEntry}async function notifySpawnJoin(ctx,paneId){let nt=ctx.validated.nativeTeam;await registerNativeMember(ctx.validated.team,{agentName:ctx.agentName,agentType:nt?.agentType??ctx.validated.role??"general-purpose",color:nt?.color??ctx.spawnColor??"blue",tmuxPaneId:paneId,cwd:ctx.cwd,planModeRequired:nt?.planModeRequired}),await writeNativeInbox(ctx.validated.team,"team-lead",{from:ctx.agentName,text:`Worker ${ctx.agentName} (${ctx.validated.provider}) joined team ${ctx.validated.team}. cwd: ${ctx.cwd}. Ready for tasks.`,summary:`${ctx.agentName} (${ctx.validated.provider}) joined`,timestamp:new Date().toISOString(),color:nt?.color??ctx.spawnColor??"blue",read:!1})}function registerOtelRelayPane(workerId,paneId,agentName,spawnColor,repoPath){let{writeFileSync:wfs}=__require("fs"),{join:pjoin}=__require("path"),{homedir:hdir}=__require("os"),rd=pjoin(hdir(),".genie","relay");wfs(pjoin(rd,`${workerId}-pane`),paneId),wfs(pjoin(rd,`${workerId}-meta`),JSON.stringify({agent:agentName,color:spawnColor,repoPath}))}function printSpawnInfo(ctx,paneId,workerEntry){let nt=ctx.validated.nativeTeam;if(console.log(`Agent "${ctx.workerId}" spawned.`),console.log(` Provider: ${ctx.launch.provider}`),console.log(` Command: ${ctx.fullCommand}`),console.log(` Team: ${ctx.validated.team}`),console.log(` Pane: ${paneId}`),ctx.validated.role)console.log(` Role: ${ctx.validated.role}`);if(ctx.validated.skill)console.log(` Skill: ${ctx.validated.skill}`);if(workerEntry.claudeSessionId)console.log(` Session: ${workerEntry.claudeSessionId}`);if(console.log(` Layout: ${ctx.layoutMode}`),nt?.enabled)console.log(" Native: enabled"),console.log(` AgentID: ${workerEntry.nativeAgentId}`),console.log(` Color: ${nt.color}`);if(ctx.otelRelayActive)console.log(` OTel: relay on port ${OTEL_RELAY_PORT}`)}async function resolveSpawnTeamWindow(team,cwd,sessionOverride){if(!team)return null;try{let sessionName=sessionOverride??await getCurrentSessionName(team);if(!sessionName)sessionName=(await getTeam2(team))?.tmuxSessionName??team;return await ensureTeamWindow(sessionName,team,cwd)}catch(err){return console.warn(`Warning: could not ensure team window for "${team}": ${err instanceof Error?err.message:err}`),null}}async function autoConfirmTrustPrompt(paneId){let{execSync:execSync5}=__require("child_process"),maxWaitMs=15000,pollMs=500,start=Date.now();while(Date.now()-start<15000){await new Promise((r)=>setTimeout(r,500));let content;try{content=execSync5(`tmux capture-pane -t '${paneId}' -p`,{encoding:"utf-8"})}catch{return}if(content.includes("trust this folder")||content.includes("Quick safety check")){try{execSync5(`tmux send-keys -t '${paneId}' Enter`,{encoding:"utf-8"})}catch{}return}if(content.includes("Claude Code")||content.includes("\u276F")||content.includes("Churning"))return}}function createTmuxPane(ctx,teamWindow){let{execSync:execSync5}=__require("child_process");if(teamWindow?.created){let paneId=execSync5(`tmux list-panes -t '${teamWindow.windowId}' -F '#{pane_id}'`,{encoding:"utf-8"}).trim().split(`
|
|
517
523
|
`)[0];if(ctx.cwd)execSync5(`tmux send-keys -t '${paneId}' 'cd ${ctx.cwd.replace(/'/g,"'\\''")}' Enter`,{encoding:"utf-8"});return execSync5(`tmux send-keys -t '${paneId}' '${ctx.fullCommand.replace(/'/g,"'\\''")}' Enter`,{encoding:"utf-8"}),paneId}let splitTarget=teamWindow?`-t '${teamWindow.windowId}'`:"",cwdFlag=ctx.cwd?`-c '${ctx.cwd}'`:"",splitCmd=`tmux split-window -d ${splitTarget} ${cwdFlag} -P -F '#{pane_id}' ${ctx.fullCommand}`;return execSync5(splitCmd,{encoding:"utf-8"}).trim()}async function applySpawnLayout(ctx,teamWindow){let{execSync:execSync5}=__require("child_process"),session=await getCurrentSessionName()??ctx.validated.team,layoutTarget=`${session}:${teamWindow?.windowName??""}`;if(!teamWindow){let wins=await listWindows(session);layoutTarget=wins[0]?wins[0].id:`${session}:`}try{execSync5(`tmux ${buildLayoutCommand(layoutTarget,ctx.layoutMode)}`,{stdio:"ignore"})}catch{}}async function launchTmuxSpawn(ctx){let teamWindow=ctx.spawnIntoCurrentWindow?null:await resolveSpawnTeamWindow(ctx.validated.team,ctx.cwd,ctx.sessionOverride),paneId;try{paneId=createTmuxPane(ctx,teamWindow)}catch(err){console.error(`Failed to create tmux pane: ${err instanceof Error?err.message:"unknown error"}`),process.exit(1)}if(await applySpawnLayout(ctx,teamWindow),ctx.validated.provider==="claude")await autoConfirmTrustPrompt(paneId);let workerEntry=await registerSpawnWorker(ctx,paneId,teamWindow);if(await notifySpawnJoin(ctx,paneId),ctx.spawnColor&&paneId!=="inline")await applyPaneColor(paneId,ctx.spawnColor,teamWindow?.windowId);if(await saveTemplate({id:ctx.validated.role??ctx.workerId,provider:ctx.validated.provider,team:ctx.validated.team,role:ctx.validated.role,skill:ctx.validated.skill,cwd:ctx.cwd,extraArgs:ctx.extraArgs,nativeTeamEnabled:workerEntry.nativeTeamEnabled,lastSpawnedAt:new Date().toISOString()}),ctx.otelRelayActive&&paneId!=="%0")registerOtelRelayPane(ctx.workerId,paneId,ctx.agentName,ctx.spawnColor,ctx.cwd);if(teamWindow)console.log(` Window: ${teamWindow.windowName} (${teamWindow.windowId})`);if(printSpawnInfo(ctx,paneId,workerEntry),paneId!=="inline"){let result=await waitForAgentReady(paneId);if(result.ready)console.log(` \u2713 Agent ready (${(result.elapsedMs/1000).toFixed(1)}s)`);else console.log(` \u26A0 Agent readiness timeout (${Math.round(result.elapsedMs/1000)}s) \u2014 proceeding anyway`)}}async function launchInlineSpawn(ctx){let nt=ctx.validated.nativeTeam,paneId="inline",workerEntry=await registerSpawnWorker(ctx,"inline");if(await notifySpawnJoin(ctx,"inline"),console.log(`Agent "${ctx.workerId}" starting inline...`),console.log(` Provider: ${ctx.launch.provider} | Team: ${ctx.validated.team} | Role: ${ctx.validated.role??"-"}`),nt?.enabled)console.log(` Native: enabled | AgentID: ${workerEntry.nativeAgentId}`);console.log("");let{spawnSync}=__require("child_process"),envVars={...process.env,...ctx.launch.env??{}},result=spawnSync("sh",["-c",ctx.launch.command],{env:envVars,stdio:"inherit"});if(await unregister(ctx.workerId),nt?.enabled&&ctx.agentName)await clearNativeInbox(ctx.validated.team,ctx.agentName).catch(()=>{}),await unregisterNativeMember(ctx.validated.team,ctx.agentName).catch(()=>{});console.log(`
|
|
518
524
|
Agent "${ctx.workerId}" session ended.`),process.exit(result.status??0)}function prependEnvVars(command,env){if(!env||Object.keys(env).length===0)return command;return`env ${Object.entries(env).map(([k,v])=>`${k}=${v}`).join(" ")} ${command}`}async function rejectDuplicateRole(team,role){let existing=await list();for(let w of existing)if(w.role===role&&w.team===team){if(await isPaneAlive(w.paneId))console.error(`Error: Worker with role "${role}" already exists in team "${team}" (state: ${w.state}, pane: ${w.paneId})
|
|
519
|
-
Use a different --role name for a second worker, e.g.: --role ${role}-2`),process.exit(1);await unregister(w.id)}}async function resolveNativeTeam(team,_repoPath,options){let parentSessionId=(await getTeam2(team))?.nativeTeamParentSessionId;if(!parentSessionId)parentSessionId=await discoverClaudeSessionId()??`genie-${team}`;await ensureNativeTeam(team,`Genie team: ${team}`,parentSessionId);let spawnColor=options.color??await assignColor(team),nativeTeam;if(options.provider==="claude")nativeTeam={enabled:!0,parentSessionId,color:spawnColor,agentType:options.role??"general-purpose",planModeRequired:options.planMode,permissionMode:options.permissionMode,agentName:options.role};return{parentSessionId,spawnColor,nativeTeam}}async function resolveAgentForSpawn(name,options){let resolved=await resolve3(name);if(!resolved)console.error(`Error: Agent "${name}" not found in directory or built-ins.`),console.error(` Register with: genie dir add ${name} --dir <path>`),console.error(" Or use a built-in: engineer, reviewer, qa, fix, ..."),process.exit(1);let entry=resolved.entry,identityPath=null;if(resolved.builtin)identityPath=resolveBuiltinAgentPath(name);else if(entry.dir)identityPath=loadIdentity(entry);return{entry,repoPath:options.cwd??(entry.dir||void 0)??process.cwd(),identityPath,model:options.model??entry.model}}async function
|
|
520
|
-
`)}}catch{}if(agent.team)return"You were resumed. Check your team's current state with `genie status`.";return}async function resumeAgent(agent){let template=(await listTemplates()).find((t)=>t.id===(agent.role??agent.id));await update(agent.id,{resumeAttempts:0});let params=buildResumeParams(agent,template),resumeContext=await buildResumeContext(agent);if(resumeContext)params.initialPrompt=resumeContext;if(agent.nativeTeamEnabled){let nativeResult=await resolveNativeTeam(params.team,agent.repoPath,{provider:params.provider,role:params.role,color:agent.nativeColor});if(nativeResult.nativeTeam)params.nativeTeam=nativeResult.nativeTeam}let validated=validateSpawnParams(params),launch=buildLaunchCommand(validated),fullCommand=prependEnvVars(launch.command,launch.env),now=new Date().toISOString();if(!process.env.TMUX)console.error("Error: resume requires tmux. Start a tmux session first."),process.exit(1);let ctx={workerId:agent.id,validated,launch,layoutMode:resolveLayoutMode(void 0),fullCommand,agentName:agent.role??agent.id,spawnColor:agent.nativeColor??"blue",parentSessionId:agent.parentSessionId??`genie-${params.team}`,claudeSessionId:agent.claudeSessionId,otelRelayActive:!1,now,transport:"tmux",extraArgs:template?.extraArgs,cwd:template?.cwd??agent.repoPath,spawnIntoCurrentWindow:!1,autoResume:agent.autoResume},teamWindow=await resolveSpawnTeamWindow(validated.team,ctx.cwd),paneId;try{paneId=createTmuxPane(ctx,teamWindow)}catch(err){console.error(`Failed to create tmux pane: ${err instanceof Error?err.message:"unknown error"}`),process.exit(1)}if(await applySpawnLayout(ctx,teamWindow),await update(agent.id,{paneId,state:"spawning",startedAt:now,lastStateChange:now,suspendedAt:void 0,windowName:teamWindow?.windowName,windowId:teamWindow?.windowId,window:teamWindow?.windowName}),await notifySpawnJoin(ctx,paneId),ctx.spawnColor&&paneId!=="inline")await applyPaneColor(paneId,ctx.spawnColor,teamWindow?.windowId);if(console.log(`Agent "${agent.id}" resumed.`),console.log(` Session: ${agent.claudeSessionId}`),console.log(` Pane: ${paneId}`),teamWindow)console.log(` Window: ${teamWindow.windowName} (${teamWindow.windowId})`)}async function buildWorkerStatusMap(workers){let statusMap=new Map;for(let w of workers){let name=w.role||w.id;if(await isPaneAlive(w.paneId))statusMap.set(name,{state:w.state,team:w.team||"-"});else if(w.state==="suspended"||w.state==="error"){let attempts=w.resumeAttempts??0,max=w.maxResumeAttempts??3,autoStr=w.autoResume===!1?"off":"on";statusMap.set(name,{state:`${w.state} (${attempts}/${max} resumes, auto-resume: ${autoStr})`,team:w.team||"-",resumeAttempts:attempts,maxResumeAttempts:max,autoResume:w.autoResume!==!1})}}return statusMap}async function handleLsCommand(options){let dirEntries=await ls(),workers=await list(),statusMap=await buildWorkerStatusMap(workers),entries=[];for(let entry of dirEntries){let running=statusMap.get(entry.name);entries.push({name:entry.name,dir:entry.dir||"-",status:running?running.state:"offline",team:running?.team||"-",model:entry.model||"-",resumeAttempts:running?.resumeAttempts,maxResumeAttempts:running?.maxResumeAttempts,autoResume:running?.autoResume}),statusMap.delete(entry.name)}for(let[name,info]of statusMap)entries.push({name,dir:"(built-in)",status:info.state,team:info.team,model:"-",resumeAttempts:info.resumeAttempts,maxResumeAttempts:info.maxResumeAttempts,autoResume:info.autoResume});if(options.json){console.log(JSON.stringify(entries,null,2));return}if(entries.length===0){console.log("No agents registered. Use `genie dir add <name> --dir <path>` to register one.");return}console.log(""),console.log(formatLsRow("NAME","DIR","STATUS","TEAM","MODEL")),console.log("-".repeat(106));for(let e of entries)console.log(formatLsRow(e.name,e.dir,e.status,e.team,e.model));console.log("")}function formatLsRow(name,dir,status,team,model){return`${name.padEnd(20).substring(0,20)}${dir.padEnd(30).substring(0,30)}${status.padEnd(44).substring(0,44)}${team.padEnd(12).substring(0,12)}${model}`}var init_agents=__esm(()=>{init_agent_directory();init_agent_registry();init_builtin_agents();init_claude_native_teams();init_codex_config();init_provider_adapters();init_spawn_command();init_team_manager();init_tmux();init_tmux()});function parseDuration(input){let match=input.trim().match(DURATION_RE);if(!match)throw Error(`Invalid duration: "${input}". Expected format: 10m, 2h, 24h, 1d`);let value=Number.parseFloat(match[1]),unit=match[2].toLowerCase(),ms=value*{s:1000,sec:1000,m:60000,min:60000,h:3600000,hr:3600000,d:86400000,day:86400000}[unit];if(ms<=0)throw Error(`Duration must be positive: "${input}"`);return ms}function expandRange(range,step,min,max){if(step===0)throw Error("Cron step value cannot be 0");if(range==="*"){let out=[];for(let i2=min;i2<=max;i2+=step)out.push(i2);return out}if(range.includes("-")){let[start,end]=range.split("-").map(Number),out=[];for(let i2=start;i2<=end;i2+=step)out.push(i2);return out}return[Number.parseInt(range,10)]}function parseCronField(field,min,max){let values2=new Set;for(let part of field.split(",")){let stepMatch=part.match(/^(.+)\/(\d+)$/),step=stepMatch?Number.parseInt(stepMatch[2],10):1,range=stepMatch?stepMatch[1]:part;for(let v of expandRange(range,step,min,max))values2.add(v)}return[...values2].sort((a,b2)=>a-b2)}function getTimeParts(date,tz){if(!tz)return{month:date.getMonth()+1,dom:date.getDate(),dow:date.getDay(),hour:date.getHours(),minute:date.getMinutes()};let parts=new Intl.DateTimeFormat("en-US",{timeZone:tz,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",weekday:"short",hour12:!1}).formatToParts(date),get3=(type2)=>Number(parts.find((p)=>p.type===type2)?.value??0),dayMap={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6},weekday=parts.find((p)=>p.type==="weekday")?.value??"Sun";return{month:get3("month"),dom:get3("day"),dow:dayMap[weekday]??0,hour:get3("hour")===24?0:get3("hour"),minute:get3("minute")}}function parseOpts(afterOrOpts){if(afterOrOpts instanceof Date)return{after:afterOrOpts};if(afterOrOpts)return{after:afterOrOpts.after,timezone:afterOrOpts.timezone};return{}}function advanceToNextDay(candidate,tz){candidate.setTime(candidate.getTime()+86400000);let tp=getTimeParts(candidate,tz);candidate.setTime(candidate.getTime()-tp.hour*3600000-tp.minute*60000)}function parseCronExpr(cronExpr){let parts=cronExpr.trim().split(/\s+/);if(parts.length<5)throw Error(`Invalid cron expression: "${cronExpr}"`);let[minField,hourField,domField,monthField,dowField]=parts;return{minutes:parseCronField(minField,0,59),hours:parseCronField(hourField,0,23),doms:parseCronField(domField,1,31),months:parseCronField(monthField,1,12),dows:parseCronField(dowField,0,6),domRestricted:domField!=="*",dowRestricted:dowField!=="*"}}function computeNextCronDue(cronExpr,afterOrOpts){let{after,timezone}=parseOpts(afterOrOpts),cron=parseCronExpr(cronExpr),candidate=new Date((after??new Date).getTime());candidate.setSeconds(0,0),candidate.setTime(candidate.getTime()+60000);let limit=new Date(candidate.getTime()+31622400000);while(candidate<=limit){let tp=getTimeParts(candidate,timezone);if(!cron.months.includes(tp.month)){advanceToNextDay(candidate,timezone);continue}if(!(cron.domRestricted&&cron.dowRestricted?cron.doms.includes(tp.dom)||cron.dows.includes(tp.dow):cron.doms.includes(tp.dom)&&cron.dows.includes(tp.dow))){advanceToNextDay(candidate,timezone);continue}if(!cron.hours.includes(tp.hour)){candidate.setTime(candidate.getTime()+3600000-tp.minute*60000);continue}if(cron.minutes.includes(tp.minute))return candidate;candidate.setTime(candidate.getTime()+60000)}throw Error(`No next cron occurrence found for "${cronExpr}" within 366 days`)}var DURATION_RE;var init_cron=__esm(()=>{DURATION_RE=/^(\d+(?:\.\d+)?)\s*(s|sec|m|min|h|hr|d|day)s?$/i});function validateRunSpec(input){if(!input.command||input.command.trim().length===0)throw Error("RunSpec.command is required and cannot be empty");if(input.lease_timeout_ms!==void 0&&input.lease_timeout_ms<1e4)throw Error(`RunSpec.lease_timeout_ms must be >= 10000ms, got ${input.lease_timeout_ms}`);if(input.lease_timeout_ms!==void 0&&input.lease_timeout_ms>3600000)throw Error(`RunSpec.lease_timeout_ms must be <= 3600000ms (1h), got ${input.lease_timeout_ms}`);if(input.provider&&!VALID_PROVIDERS.has(input.provider))throw Error(`RunSpec.provider must be 'claude' or 'codex', got '${input.provider}'`);if(input.ref_policy&&!VALID_REF_POLICIES.has(input.ref_policy))throw Error(`RunSpec.ref_policy must be 'current' or 'default', got '${input.ref_policy}'`);if(input.approval_policy&&!VALID_APPROVAL_POLICIES.has(input.approval_policy))throw Error(`RunSpec.approval_policy must be 'auto' or 'manual', got '${input.approval_policy}'`)}function resolveRunSpec(input){return validateRunSpec(input),{repo:input.repo??DEFAULTS.repo,ref_policy:input.ref_policy??DEFAULTS.ref_policy,provider:input.provider??DEFAULTS.provider,role:input.role??DEFAULTS.role,model:input.model??DEFAULTS.model,command:input.command.trim(),approval_policy:input.approval_policy??DEFAULTS.approval_policy,concurrency_class:input.concurrency_class??DEFAULTS.concurrency_class,lease_timeout_ms:input.lease_timeout_ms??DEFAULTS.lease_timeout_ms}}var DEFAULTS,VALID_PROVIDERS,VALID_REF_POLICIES,VALID_APPROVAL_POLICIES;var init_run_spec=__esm(()=>{DEFAULTS={repo:process.cwd(),ref_policy:"current",provider:"claude",role:"worker",model:"",approval_policy:"auto",concurrency_class:"default",lease_timeout_ms:300000},VALID_PROVIDERS=new Set(["claude","codex"]),VALID_REF_POLICIES=new Set(["current","default"]),VALID_APPROVAL_POLICIES=new Set(["auto","manual"])});var exports_scheduler_daemon={};__export(exports_scheduler_daemon,{startDaemon:()=>startDaemon,recoverOnStartup:()=>recoverOnStartup,reconcileOrphans:()=>reconcileOrphans,reconcileOrphanedRuns:()=>reconcileOrphanedRuns,reclaimExpiredLeases:()=>reclaimExpiredLeases,logToFile:()=>logToFile,fireTrigger:()=>fireTrigger,emitWorkerEvents:()=>emitWorkerEvents,collectMachineSnapshot:()=>collectMachineSnapshot,collectHeartbeats:()=>collectHeartbeats,claimDueTriggers:()=>claimDueTriggers,attemptAgentResume:()=>attemptAgentResume,_resetWorkerStatesForTesting:()=>_resetWorkerStatesForTesting});import{randomUUID}from"crypto";import{appendFileSync as appendFileSync2,mkdirSync as mkdirSync7}from"fs";import{homedir as homedir16}from"os";import{join as join19}from"path";function getLogDir2(){return join19(process.env.GENIE_HOME??join19(homedir16(),".genie"),"logs")}function getLogFile(){return join19(getLogDir2(),"scheduler.log")}function logToFile(entry){let logDir=getLogDir2();mkdirSync7(logDir,{recursive:!0}),appendFileSync2(getLogFile(),`${JSON.stringify(entry)}
|
|
525
|
+
Use a different --role name for a second worker, e.g.: --role ${role}-2`),process.exit(1);await unregister(w.id)}}async function resolveNativeTeam(team,_repoPath,options){let parentSessionId=(await getTeam2(team))?.nativeTeamParentSessionId;if(!parentSessionId)parentSessionId=await discoverClaudeSessionId()??`genie-${team}`;await ensureNativeTeam(team,`Genie team: ${team}`,parentSessionId);let spawnColor=options.color??await assignColor(team),nativeTeam;if(options.provider==="claude")nativeTeam={enabled:!0,parentSessionId,color:spawnColor,agentType:options.role??"general-purpose",planModeRequired:options.planMode,permissionMode:options.permissionMode,agentName:options.role};return{parentSessionId,spawnColor,nativeTeam}}async function resolveAgentForSpawn(name,options){let resolved=await resolve3(name);if(!resolved)console.error(`Error: Agent "${name}" not found in directory or built-ins.`),console.error(` Register with: genie dir add ${name} --dir <path>`),console.error(" Or use a built-in: engineer, reviewer, qa, fix, ..."),process.exit(1);let entry=resolved.entry,identityPath=null;if(resolved.builtin)identityPath=resolveBuiltinAgentPath(name);else if(entry.dir)identityPath=loadIdentity(entry);return{entry,repoPath:options.cwd??(entry.dir||void 0)??process.cwd(),identityPath,model:options.model??entry.model}}async function buildSpawnParams2(name,team,options,agent){let params={provider:options.provider,team,role:name,skill:options.skill,extraArgs:options.extraArgs,model:agent.model,systemPromptFile:agent.identityPath??void 0,promptMode:agent.entry.promptMode,initialPrompt:options.initialPrompt},{parentSessionId,spawnColor,nativeTeam}=await resolveNativeTeam(team,agent.repoPath,{...options,role:name});if(nativeTeam)params.nativeTeam=nativeTeam;try{let{injectTeamHooks:injectTeamHooks2}=await Promise.resolve().then(() => (init_inject(),exports_inject));if(await injectTeamHooks2(team))console.log(` Hooks: injected genie hook dispatch into team "${team}"`)}catch(err){console.warn(`Warning: could not inject hooks for team "${team}": ${err instanceof Error?err.message:err}`)}if(params.provider==="claude")params.sessionId=crypto.randomUUID();return{params,parentSessionId,spawnColor}}async function handleWorkerSpawn(name,options){let effectiveRole=options.role??name,agent=await resolveAgentForSpawn(name,options),teamWasExplicit=Boolean(options.team),team=options.team||await discoverTeamName();if(!team)console.error("Error: --team is required (or set GENIE_TEAM, or run inside a genie session)"),process.exit(1);await rejectDuplicateRole(team,effectiveRole);let teamConfig=await getTeam2(team);if(teamConfig?.worktreePath)agent={...agent,repoPath:teamConfig.worktreePath};let{params,parentSessionId,spawnColor}=await buildSpawnParams2(effectiveRole,team,options,agent);if(!params.name)params.name=`${params.team}-${effectiveRole}`;let validated=validateSpawnParams(params),launch=buildLaunchCommand(validated),layoutMode=resolveLayoutMode(options.layout),workerId=await generateWorkerId2(validated.team,effectiveRole),insideTmux=Boolean(process.env.TMUX),nt=validated.nativeTeam,now=new Date().toISOString(),agentName=nt?.agentName??effectiveRole,otelRelayActive=!1;if(!nt?.enabled&&validated.provider==="codex"&&insideTmux)ensureCodexOtelConfig(),otelRelayActive=await ensureOtelRelay(validated.team);let fullCommand=prependEnvVars(launch.command,launch.env),ctx={workerId,validated,launch,layoutMode,fullCommand,agentName,spawnColor,parentSessionId,claudeSessionId:validated.sessionId,otelRelayActive,now,transport:insideTmux?"tmux":"inline",extraArgs:options.extraArgs,cwd:agent.repoPath,spawnIntoCurrentWindow:!teamWasExplicit&&insideTmux&&!options.session,sessionOverride:options.session,autoResume:options.autoResume};if(insideTmux)await launchTmuxSpawn(ctx);else await launchInlineSpawn(ctx)}async function cleanupWorkerNativeTeam(w){if(!w.team||!w.nativeAgentId)return;let agentName=w.nativeAgentId.split("@")[0];await clearNativeInbox(w.team,agentName).catch(()=>{}),await unregisterNativeMember(w.team,agentName).catch(()=>{})}function killWorkerPane(w){try{let{execSync:execSync5}=__require("child_process"),currentPane=execSync5("tmux display-message -p '#{pane_id}'",{encoding:"utf-8"}).trim();if(w.paneId&&/^(%\d+|inline)$/.test(w.paneId)&&w.paneId!==currentPane)execSync5(`tmux kill-pane -t ${w.paneId}`,{stdio:"ignore"});else if(w.paneId===currentPane)console.log(" (skipped pane kill \u2014 would kill current session)")}catch{}}function cleanupRelayFiles(id){try{let{join:join21}=__require("path"),{homedir:homedir16}=__require("os"),{unlinkSync:unlinkSync4}=__require("fs"),relayDir=join21(homedir16(),".genie","relay");for(let suffix of["-pane","-meta"])try{unlinkSync4(join21(relayDir,`${id}${suffix}`))}catch{}}catch{}}async function resolveWorkerByName(name){let exact=await get(name);if(exact)return exact;let workers=await list(),byRole=workers.filter((w)=>w.role===name);if(byRole.length===1)return byRole[0];if(byRole.length>1){console.error(`Multiple agents with role "${name}". Specify full ID:`);for(let w of byRole)console.error(` ${w.id} (team: ${w.team})`);process.exit(1)}let bySuffix=workers.filter((w)=>w.id.endsWith(`-${name}`));if(bySuffix.length===1)return bySuffix[0];if(bySuffix.length>1){console.error(`Multiple agents matching "${name}". Specify full ID:`);for(let w of bySuffix)console.error(` ${w.id}`);process.exit(1)}console.error(`Agent "${name}" not found.`),console.error(" Run `genie ls` to see agents."),process.exit(1)}async function handleWorkerKill(name){let w=await resolveWorkerByName(name);killWorkerPane(w),cleanupRelayFiles(w.id),await cleanupWorkerNativeTeam(w),await unregister(w.id),console.log(`Agent "${w.id}" killed and unregistered (template preserved).`)}async function handleWorkerStop(name){let w=await resolveWorkerByName(name);if(w.state==="suspended"){console.log(`Agent "${w.id}" is already stopped.`);return}let{suspendWorker:suspendWorker2}=await Promise.resolve().then(() => (init_idle_timeout(),exports_idle_timeout));if(await suspendWorker2(w.id)){if(console.log(`Agent "${w.id}" stopped.`),w.claudeSessionId)console.log(` Session preserved: ${w.claudeSessionId}`);console.log(` Send a message to auto-resume: genie send '...' --to ${w.id}`)}else console.error(`Failed to stop agent "${w.id}".`),process.exit(1)}async function isResumeEligible(w){return(w.state==="suspended"||w.state==="error")&&Boolean(w.claudeSessionId)&&!await isPaneAlive(w.paneId)}async function resumeAllAgents(){let workers=await list(),toResume=[];for(let w of workers)if(await isResumeEligible(w))toResume.push(w);if(toResume.length===0){console.log("No eligible agents to resume.");return}console.log(`Resuming ${toResume.length} agent(s)...`);for(let w of toResume)try{await resumeAgent(w)}catch(err){console.error(` Failed to resume "${w.id}": ${err instanceof Error?err.message:err}`)}}async function handleWorkerResume(name,options){if(options.all)return resumeAllAgents();if(!name)console.error("Error: provide an agent name, or use --all to resume all eligible agents."),process.exit(1);let w=await resolveWorkerByName(name);if(!w.claudeSessionId)console.error(`Error: Agent "${w.id}" has no Claude session ID \u2014 cannot resume.`),console.error(" Only agents spawned with the Claude provider have resumable sessions."),process.exit(1);if(await isPaneAlive(w.paneId)){console.log(`Agent "${w.id}" is already running (pane ${w.paneId} is alive).`);return}await resumeAgent(w)}function buildResumeParams(agent,template){let agentName=agent.role??agent.id,provider=template?.provider??agent.provider??"claude",team=template?.team??agent.team??"genie";return{provider,team,role:agentName,skill:template?.skill??agent.skill,extraArgs:template?.extraArgs,resume:agent.claudeSessionId,name:`${team}-${agentName}`}}function formatGroupStatus(name,group,allGroups){let detail=group.status;if(group.completedAt)detail+=` (completed at ${group.completedAt})`;else if(group.startedAt)detail+=` (started at ${group.startedAt})`;if(group.status==="blocked"&&group.dependsOn.length>0){let pending=group.dependsOn.filter((dep)=>allGroups[dep]?.status!=="done");if(pending.length>0)detail+=` (depends on ${pending.join(", ")})`}return`Group ${name}: ${detail}`}async function buildResumeContext(agent){if(agent.role==="team-lead"&&agent.wishSlug)try{let state2=await(await Promise.resolve().then(() => (init_wish_state(),exports_wish_state))).getState(agent.wishSlug,agent.repoPath);if(state2){let groupLines=Object.entries(state2.groups).map(([name,group])=>formatGroupStatus(name,group,state2.groups));return["You were resumed after a crash. Here's where you left off:",`Wish: ${state2.wish}`,"",...groupLines,"",`Continue from where you left off. Run \`genie status ${state2.wish}\` to verify, then dispatch the next wave.`].join(`
|
|
526
|
+
`)}}catch{}if(agent.team)return"You were resumed. Check your team's current state with `genie status`.";return}async function buildFullResumeParams(agent,template){let params=buildResumeParams(agent,template),resumeContext=await buildResumeContext(agent);if(resumeContext)params.initialPrompt=resumeContext;if(agent.nativeTeamEnabled){let nativeResult=await resolveNativeTeam(params.team,agent.repoPath,{provider:params.provider,role:params.role,color:agent.nativeColor});if(nativeResult.nativeTeam)params.nativeTeam=nativeResult.nativeTeam}return params}async function resumeAgent(agent){let template=(await listTemplates()).find((t)=>t.id===(agent.role??agent.id));await update(agent.id,{resumeAttempts:0});let params=await buildFullResumeParams(agent,template),validated=validateSpawnParams(params),launch=buildLaunchCommand(validated),fullCommand=prependEnvVars(launch.command,launch.env),now=new Date().toISOString();if(!process.env.TMUX)console.error("Error: resume requires tmux. Start a tmux session first."),process.exit(1);let ctx={workerId:agent.id,validated,launch,layoutMode:resolveLayoutMode(void 0),fullCommand,agentName:agent.role??agent.id,spawnColor:agent.nativeColor??"blue",parentSessionId:agent.parentSessionId??`genie-${params.team}`,claudeSessionId:agent.claudeSessionId,otelRelayActive:!1,now,transport:"tmux",extraArgs:template?.extraArgs,cwd:template?.cwd??agent.repoPath,spawnIntoCurrentWindow:!1,autoResume:agent.autoResume},teamWindow=await resolveSpawnTeamWindow(validated.team,ctx.cwd),paneId;try{paneId=createTmuxPane(ctx,teamWindow)}catch(err){console.error(`Failed to create tmux pane: ${err instanceof Error?err.message:"unknown error"}`),process.exit(1)}if(await applySpawnLayout(ctx,teamWindow),await update(agent.id,{paneId,state:"spawning",startedAt:now,lastStateChange:now,suspendedAt:void 0,windowName:teamWindow?.windowName,windowId:teamWindow?.windowId,window:teamWindow?.windowName}),await notifySpawnJoin(ctx,paneId),await injectResumeContext(ctx.cwd??agent.repoPath??process.cwd(),agent.id,agent.role??agent.id,params.team),ctx.spawnColor&&paneId!=="inline")await applyPaneColor(paneId,ctx.spawnColor,teamWindow?.windowId);if(console.log(`Agent "${agent.id}" resumed.`),console.log(` Session: ${agent.claudeSessionId}`),console.log(` Pane: ${paneId}`),teamWindow)console.log(` Window: ${teamWindow.windowName} (${teamWindow.windowId})`)}async function buildWorkerStatusMap(workers){let statusMap=new Map;for(let w of workers){let name=w.role||w.id;if(await isPaneAlive(w.paneId))statusMap.set(name,{state:w.state,team:w.team||"-"});else if(w.state==="suspended"||w.state==="error"){let attempts=w.resumeAttempts??0,max=w.maxResumeAttempts??3,autoStr=w.autoResume===!1?"off":"on";statusMap.set(name,{state:`${w.state} (${attempts}/${max} resumes, auto-resume: ${autoStr})`,team:w.team||"-",resumeAttempts:attempts,maxResumeAttempts:max,autoResume:w.autoResume!==!1})}}return statusMap}async function handleLsCommand(options){let dirEntries=await ls(),workers=await list(),statusMap=await buildWorkerStatusMap(workers),entries=[];for(let entry of dirEntries){let running=statusMap.get(entry.name);entries.push({name:entry.name,dir:entry.dir||"-",status:running?running.state:"offline",team:running?.team||"-",model:entry.model||"-",resumeAttempts:running?.resumeAttempts,maxResumeAttempts:running?.maxResumeAttempts,autoResume:running?.autoResume}),statusMap.delete(entry.name)}for(let[name,info]of statusMap)entries.push({name,dir:"(built-in)",status:info.state,team:info.team,model:"-",resumeAttempts:info.resumeAttempts,maxResumeAttempts:info.maxResumeAttempts,autoResume:info.autoResume});if(options.json){console.log(JSON.stringify(entries,null,2));return}if(entries.length===0){console.log("No agents registered. Use `genie dir add <name> --dir <path>` to register one.");return}console.log(""),console.log(formatLsRow("NAME","DIR","STATUS","TEAM","MODEL")),console.log("-".repeat(106));for(let e of entries)console.log(formatLsRow(e.name,e.dir,e.status,e.team,e.model));console.log("")}function formatLsRow(name,dir,status,team,model){return`${name.padEnd(20).substring(0,20)}${dir.padEnd(30).substring(0,30)}${status.padEnd(44).substring(0,44)}${team.padEnd(12).substring(0,12)}${model}`}var init_agents=__esm(()=>{init_agent_directory();init_agent_registry();init_builtin_agents();init_claude_native_teams();init_codex_config();init_protocol_router_spawn();init_provider_adapters();init_spawn_command();init_team_manager();init_tmux();init_tmux()});function parseDuration(input){let match=input.trim().match(DURATION_RE);if(!match)throw Error(`Invalid duration: "${input}". Expected format: 10m, 2h, 24h, 1d`);let value=Number.parseFloat(match[1]),unit=match[2].toLowerCase(),ms=value*{s:1000,sec:1000,m:60000,min:60000,h:3600000,hr:3600000,d:86400000,day:86400000}[unit];if(ms<=0)throw Error(`Duration must be positive: "${input}"`);return ms}function expandRange(range,step,min,max){if(step===0)throw Error("Cron step value cannot be 0");if(range==="*"){let out=[];for(let i2=min;i2<=max;i2+=step)out.push(i2);return out}if(range.includes("-")){let[start,end]=range.split("-").map(Number),out=[];for(let i2=start;i2<=end;i2+=step)out.push(i2);return out}return[Number.parseInt(range,10)]}function parseCronField(field,min,max){let values2=new Set;for(let part of field.split(",")){let stepMatch=part.match(/^(.+)\/(\d+)$/),step=stepMatch?Number.parseInt(stepMatch[2],10):1,range=stepMatch?stepMatch[1]:part;for(let v of expandRange(range,step,min,max))values2.add(v)}return[...values2].sort((a,b2)=>a-b2)}function getTimeParts(date,tz){if(!tz)return{month:date.getMonth()+1,dom:date.getDate(),dow:date.getDay(),hour:date.getHours(),minute:date.getMinutes()};let parts=new Intl.DateTimeFormat("en-US",{timeZone:tz,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",weekday:"short",hour12:!1}).formatToParts(date),get3=(type2)=>Number(parts.find((p)=>p.type===type2)?.value??0),dayMap={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6},weekday=parts.find((p)=>p.type==="weekday")?.value??"Sun";return{month:get3("month"),dom:get3("day"),dow:dayMap[weekday]??0,hour:get3("hour")===24?0:get3("hour"),minute:get3("minute")}}function parseOpts(afterOrOpts){if(afterOrOpts instanceof Date)return{after:afterOrOpts};if(afterOrOpts)return{after:afterOrOpts.after,timezone:afterOrOpts.timezone};return{}}function advanceToNextDay(candidate,tz){candidate.setTime(candidate.getTime()+86400000);let tp=getTimeParts(candidate,tz);candidate.setTime(candidate.getTime()-tp.hour*3600000-tp.minute*60000)}function parseCronExpr(cronExpr){let parts=cronExpr.trim().split(/\s+/);if(parts.length<5)throw Error(`Invalid cron expression: "${cronExpr}"`);let[minField,hourField,domField,monthField,dowField]=parts;return{minutes:parseCronField(minField,0,59),hours:parseCronField(hourField,0,23),doms:parseCronField(domField,1,31),months:parseCronField(monthField,1,12),dows:parseCronField(dowField,0,6),domRestricted:domField!=="*",dowRestricted:dowField!=="*"}}function computeNextCronDue(cronExpr,afterOrOpts){let{after,timezone}=parseOpts(afterOrOpts),cron=parseCronExpr(cronExpr),candidate=new Date((after??new Date).getTime());candidate.setSeconds(0,0),candidate.setTime(candidate.getTime()+60000);let limit=new Date(candidate.getTime()+31622400000);while(candidate<=limit){let tp=getTimeParts(candidate,timezone);if(!cron.months.includes(tp.month)){advanceToNextDay(candidate,timezone);continue}if(!(cron.domRestricted&&cron.dowRestricted?cron.doms.includes(tp.dom)||cron.dows.includes(tp.dow):cron.doms.includes(tp.dom)&&cron.dows.includes(tp.dow))){advanceToNextDay(candidate,timezone);continue}if(!cron.hours.includes(tp.hour)){candidate.setTime(candidate.getTime()+3600000-tp.minute*60000);continue}if(cron.minutes.includes(tp.minute))return candidate;candidate.setTime(candidate.getTime()+60000)}throw Error(`No next cron occurrence found for "${cronExpr}" within 366 days`)}var DURATION_RE;var init_cron=__esm(()=>{DURATION_RE=/^(\d+(?:\.\d+)?)\s*(s|sec|m|min|h|hr|d|day)s?$/i});function validateRunSpec(input){if(!input.command||input.command.trim().length===0)throw Error("RunSpec.command is required and cannot be empty");if(input.lease_timeout_ms!==void 0&&input.lease_timeout_ms<1e4)throw Error(`RunSpec.lease_timeout_ms must be >= 10000ms, got ${input.lease_timeout_ms}`);if(input.lease_timeout_ms!==void 0&&input.lease_timeout_ms>3600000)throw Error(`RunSpec.lease_timeout_ms must be <= 3600000ms (1h), got ${input.lease_timeout_ms}`);if(input.provider&&!VALID_PROVIDERS.has(input.provider))throw Error(`RunSpec.provider must be 'claude' or 'codex', got '${input.provider}'`);if(input.ref_policy&&!VALID_REF_POLICIES.has(input.ref_policy))throw Error(`RunSpec.ref_policy must be 'current' or 'default', got '${input.ref_policy}'`);if(input.approval_policy&&!VALID_APPROVAL_POLICIES.has(input.approval_policy))throw Error(`RunSpec.approval_policy must be 'auto' or 'manual', got '${input.approval_policy}'`)}function resolveRunSpec(input){return validateRunSpec(input),{repo:input.repo??DEFAULTS.repo,ref_policy:input.ref_policy??DEFAULTS.ref_policy,provider:input.provider??DEFAULTS.provider,role:input.role??DEFAULTS.role,model:input.model??DEFAULTS.model,command:input.command.trim(),approval_policy:input.approval_policy??DEFAULTS.approval_policy,concurrency_class:input.concurrency_class??DEFAULTS.concurrency_class,lease_timeout_ms:input.lease_timeout_ms??DEFAULTS.lease_timeout_ms}}var DEFAULTS,VALID_PROVIDERS,VALID_REF_POLICIES,VALID_APPROVAL_POLICIES;var init_run_spec=__esm(()=>{DEFAULTS={repo:process.cwd(),ref_policy:"current",provider:"claude",role:"worker",model:"",approval_policy:"auto",concurrency_class:"default",lease_timeout_ms:300000},VALID_PROVIDERS=new Set(["claude","codex"]),VALID_REF_POLICIES=new Set(["current","default"]),VALID_APPROVAL_POLICIES=new Set(["auto","manual"])});var exports_scheduler_daemon={};__export(exports_scheduler_daemon,{startDaemon:()=>startDaemon,recoverOnStartup:()=>recoverOnStartup,reconcileOrphans:()=>reconcileOrphans,reconcileOrphanedRuns:()=>reconcileOrphanedRuns,reclaimExpiredLeases:()=>reclaimExpiredLeases,logToFile:()=>logToFile,fireTrigger:()=>fireTrigger,emitWorkerEvents:()=>emitWorkerEvents,collectMachineSnapshot:()=>collectMachineSnapshot,collectHeartbeats:()=>collectHeartbeats,claimDueTriggers:()=>claimDueTriggers,attemptAgentResume:()=>attemptAgentResume,_resetWorkerStatesForTesting:()=>_resetWorkerStatesForTesting});import{randomUUID as randomUUID2}from"crypto";import{appendFileSync as appendFileSync2,mkdirSync as mkdirSync7}from"fs";import{homedir as homedir16}from"os";import{join as join21}from"path";function getLogDir2(){return join21(process.env.GENIE_HOME??join21(homedir16(),".genie"),"logs")}function getLogFile(){return join21(getLogDir2(),"scheduler.log")}function logToFile(entry){let logDir=getLogDir2();mkdirSync7(logDir,{recursive:!0}),appendFileSync2(getLogFile(),`${JSON.stringify(entry)}
|
|
521
527
|
`)}async function defaultSpawnCommand(command,env){return{pid:Bun.spawn(["sh","-c",command],{env:{...process.env,...env},stdio:["ignore","ignore","ignore"]}).pid}}function defaultJitter(maxMs){return Math.floor(Math.random()*maxMs)}function defaultSleep(ms){return new Promise((resolve4)=>setTimeout(resolve4,ms))}async function defaultIsPaneAlive(paneId){let{isPaneAlive:isPaneAlive2}=await Promise.resolve().then(() => (init_tmux(),exports_tmux));return isPaneAlive2(paneId)}async function defaultListWorkers(){let{list:list2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));return(await list2()).map((a)=>({id:a.id,paneId:a.paneId,state:a.state,team:a.team,wishSlug:a.wishSlug,groupNumber:a.groupNumber,autoResume:a.autoResume,resumeAttempts:a.resumeAttempts,maxResumeAttempts:a.maxResumeAttempts,lastResumeAttempt:a.lastResumeAttempt,claudeSessionId:a.claudeSessionId}))}async function defaultPublishEvent(subject,data){try{let{publish:publish2}=await Promise.resolve().then(() => (init_nats_client(),exports_nats_client));await publish2(subject,data)}catch{}}async function defaultCountTmuxSessions(){try{let{execSync:execSync5}=await import("child_process");return execSync5("tmux list-sessions 2>/dev/null",{encoding:"utf-8"}).trim().split(`
|
|
522
|
-
`).filter(Boolean).length}catch{return 0}}async function defaultResumeAgent(agentId){try{let{execSync:execSync5}=await import("child_process");return execSync5(`genie resume ${agentId}`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}async function defaultUpdateAgent(agentId,updates){let{update:update2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));await update2(agentId,updates)}function createDefaultDeps(){return{getConnection:async()=>{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db));return getConnection2()},spawnCommand:defaultSpawnCommand,log:logToFile,generateId:
|
|
528
|
+
`).filter(Boolean).length}catch{return 0}}async function defaultResumeAgent(agentId){try{let{execSync:execSync5}=await import("child_process");return execSync5(`genie resume ${agentId}`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}async function defaultUpdateAgent(agentId,updates){let{update:update2}=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry));await update2(agentId,updates)}function createDefaultDeps(){return{getConnection:async()=>{let{getConnection:getConnection2}=await Promise.resolve().then(() => (init_db(),exports_db));return getConnection2()},spawnCommand:defaultSpawnCommand,log:logToFile,generateId:randomUUID2,now:()=>new Date,sleep:defaultSleep,jitter:defaultJitter,isPaneAlive:defaultIsPaneAlive,listWorkers:defaultListWorkers,countTmuxSessions:defaultCountTmuxSessions,publishEvent:defaultPublishEvent,resumeAgent:defaultResumeAgent,updateAgent:defaultUpdateAgent}}function resolveConfig(overrides){let envMax=process.env.GENIE_MAX_CONCURRENT,maxConcurrent=envMax?Number.parseInt(envMax,10):5;return{maxConcurrent:overrides?.maxConcurrent??(Number.isNaN(maxConcurrent)?5:maxConcurrent),pollIntervalMs:overrides?.pollIntervalMs??30000,maxJitterMs:overrides?.maxJitterMs??30000,jitterThreshold:overrides?.jitterThreshold??3,heartbeatIntervalMs:overrides?.heartbeatIntervalMs??60000,orphanCheckIntervalMs:overrides?.orphanCheckIntervalMs??300000,deadHeartbeatThreshold:overrides?.deadHeartbeatThreshold??2}}async function claimDueTriggers(deps,config,daemonId){let sql=await deps.getConnection(),now=deps.now(),leaseUntil=new Date(now.getTime()+300000),runningCount=(await sql`
|
|
523
529
|
SELECT count(*)::int AS cnt FROM runs
|
|
524
530
|
WHERE status IN ('leased', 'running')
|
|
525
531
|
`)[0]?.cnt??0,available=Math.max(0,config.maxConcurrent-runningCount);if(available===0)return deps.log({timestamp:now.toISOString(),level:"debug",event:"concurrency_cap_reached",running:runningCount,max:config.maxConcurrent}),[];let limit=Math.min(available,5),claimed=await sql.begin(async(tx)=>{let rows=await tx`
|
|
@@ -588,12 +594,7 @@ Use a different --role name for a second worker, e.g.: --role ${role}-2`),proces
|
|
|
588
594
|
`,failedCount++,deps.log({timestamp:now.toISOString(),level:"warn",event:"orphan_run_failed",run_id:run.id,worker_id:run.worker_id,dead_heartbeats:threshold})}if(failedCount>0)deps.log({timestamp:now.toISOString(),level:"info",event:"orphan_reconciliation_completed",failed_count:failedCount});return failedCount}async function collectMachineSnapshot(deps){let sql=await deps.getConnection(),now=deps.now(),snapshotId=deps.generateId(),workers=await deps.listWorkers(),activeWorkers=workers.filter((w)=>!["done","error","suspended"].includes(w.state)).length,teams=new Set(workers.filter((w)=>w.team).map((w)=>w.team)),tmuxSessions=await deps.countTmuxSessions(),cpuPercent=null,memoryMb=null;try{let mem=process.memoryUsage();memoryMb=Math.round(mem.rss/1024/1024)}catch{}try{let cpus=(await import("os")).cpus();if(cpus.length>0){let total=cpus.reduce((acc,cpu)=>{let t=Object.values(cpu.times).reduce((a,b2)=>a+b2,0);return acc+t-cpu.times.idle},0),totalAll=cpus.reduce((acc,cpu)=>acc+Object.values(cpu.times).reduce((a,b2)=>a+b2,0),0);cpuPercent=totalAll>0?Math.round(total/totalAll*100):null}}catch{}await sql`
|
|
589
595
|
INSERT INTO machine_snapshots (id, active_workers, active_teams, tmux_sessions, cpu_percent, memory_mb, created_at)
|
|
590
596
|
VALUES (${snapshotId}, ${activeWorkers}, ${teams.size}, ${tmuxSessions}, ${cpuPercent}, ${memoryMb}, ${now})
|
|
591
|
-
`,deps.log({timestamp:now.toISOString(),level:"debug",event:"machine_snapshot",active_workers:activeWorkers,active_teams:teams.size,tmux_sessions:tmuxSessions,cpu_percent:cpuPercent,memory_mb:memoryMb})}async function emitWorkerEvents(deps){let workers=await deps.listWorkers(),now=deps.now().toISOString(),currentIds=new Set;for(let worker of workers){currentIds.add(worker.id);let prev=previousWorkerStates.get(worker.id);if(!prev)await deps.publishEvent(`genie.agent.${worker.id}.spawned`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} spawned`,data:{state:worker.state},source:"registry"});else if(prev.state!==worker.state){if(await deps.publishEvent(`genie.agent.${worker.id}.state`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} state: ${prev.state} \u2192 ${worker.state}`,data:{previousState:prev.state,state:worker.state},source:"registry"}),worker.state==="done"&&worker.wishSlug&&worker.groupNumber!=null)await deps.publishEvent(`genie.wish.${worker.wishSlug}.group.${worker.groupNumber}.done`,{timestamp:now,kind:"system",agent:worker.id,team:worker.team,text:`Wish ${worker.wishSlug} group ${worker.groupNumber} completed by ${worker.id}`,data:{wishSlug:worker.wishSlug,groupNumber:worker.groupNumber},source:"registry"})}previousWorkerStates.set(worker.id,{...worker})}for(let[id,prev]of previousWorkerStates)if(!currentIds.has(id))await deps.publishEvent(`genie.agent.${id}.killed`,{timestamp:now,kind:"state",agent:id,team:prev.team,text:`Agent ${id} killed`,data:{lastState:prev.state},source:"registry"}),previousWorkerStates.delete(id)}function _resetWorkerStatesForTesting(){previousWorkerStates.clear()}function startDaemon(configOverrides,depsOverrides){let config=resolveConfig(configOverrides),deps={...createDefaultDeps(),...depsOverrides},daemonId=deps.generateId(),running=!0,pollTimeout=null,pollResolve=null,listenConnection=null,heartbeatTimer=null,orphanTimer=null,stop=()=>{if(running=!1,pollTimeout)clearTimeout(pollTimeout),pollTimeout=null;if(pollResolve)pollResolve(),pollResolve=null;if(heartbeatTimer)clearInterval(heartbeatTimer),heartbeatTimer=null;if(orphanTimer)clearInterval(orphanTimer),orphanTimer=null;if(listenConnection)listenConnection.end().catch(()=>{}),listenConnection=null},processTriggers=async()=>{try{let claimed=await claimDueTriggers(deps,config,daemonId);if(claimed.length===0)return;if(claimed.length>config.jitterThreshold){let jitterMs=deps.jitter(config.maxJitterMs);deps.log({timestamp:deps.now().toISOString(),level:"info",event:"jitter_applied",count:claimed.length,jitter_ms:jitterMs}),await deps.sleep(jitterMs)}for(let trigger of claimed){if(!running)break;await fireTrigger(deps,trigger,daemonId)}}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"process_cycle_error",error:message})}},done=(async()=>{deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_started",daemon_id:daemonId,max_concurrent:config.maxConcurrent,poll_interval_ms:config.pollIntervalMs});try{await recoverOnStartup(deps,daemonId,config)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"recovery_error",error:message})}try{let sql=await deps.getConnection();listenConnection=sql,await sql.listen("genie_trigger_due",async()=>{if(!running)return;await processTriggers()}),deps.log({timestamp:deps.now().toISOString(),level:"info",event:"listen_started",channel:"genie_trigger_due"})}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"listen_failed",error:message})}heartbeatTimer=setInterval(async()=>{if(!running)return;try{await collectHeartbeats(deps),await collectMachineSnapshot(deps),await emitWorkerEvents(deps)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"heartbeat_error",error:message})}},config.heartbeatIntervalMs),orphanTimer=setInterval(async()=>{if(!running)return;try{await reconcileOrphans(deps,config)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"orphan_reconciliation_error",error:message})}},config.orphanCheckIntervalMs),await processTriggers();while(running){if(await new Promise((resolve4)=>{pollResolve=resolve4,pollTimeout=setTimeout(resolve4,config.pollIntervalMs)}),pollResolve=null,!running)break;await processTriggers()}deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_stopped",daemon_id:daemonId})})();return{stop,done,daemonId}}var RESUME_COOLDOWN_MS=60000,DEFAULT_MAX_RESUME_ATTEMPTS=3,previousWorkerStates;var init_scheduler_daemon=__esm(()=>{init_cron();init_run_spec();previousWorkerStates=new Map});import{randomUUID as randomUUID2}from"crypto";var native_default;var init_native=__esm(()=>{native_default={randomUUID:randomUUID2}});import{randomFillSync}from"crypto";function rng(){if(poolPtr>rnds8Pool.length-16)randomFillSync(rnds8Pool),poolPtr=0;return rnds8Pool.slice(poolPtr,poolPtr+=16)}var rnds8Pool,poolPtr;var init_rng=__esm(()=>{rnds8Pool=new Uint8Array(256),poolPtr=rnds8Pool.length});function unsafeStringify(arr,offset=0){return(byteToHex[arr[offset+0]]+byteToHex[arr[offset+1]]+byteToHex[arr[offset+2]]+byteToHex[arr[offset+3]]+"-"+byteToHex[arr[offset+4]]+byteToHex[arr[offset+5]]+"-"+byteToHex[arr[offset+6]]+byteToHex[arr[offset+7]]+"-"+byteToHex[arr[offset+8]]+byteToHex[arr[offset+9]]+"-"+byteToHex[arr[offset+10]]+byteToHex[arr[offset+11]]+byteToHex[arr[offset+12]]+byteToHex[arr[offset+13]]+byteToHex[arr[offset+14]]+byteToHex[arr[offset+15]]).toLowerCase()}var byteToHex;var init_stringify=__esm(()=>{byteToHex=[];for(let i2=0;i2<256;++i2)byteToHex.push((i2+256).toString(16).slice(1))});function v4(options,buf,offset){if(native_default.randomUUID&&!buf&&!options)return native_default.randomUUID();options=options||{};let rnds=options.random??options.rng?.()??rng();if(rnds.length<16)throw Error("Random bytes length must be >= 16");if(rnds[6]=rnds[6]&15|64,rnds[8]=rnds[8]&63|128,buf){if(offset=offset||0,offset<0||offset+16>buf.length)throw RangeError(`UUID byte range ${offset}:${offset+15} is out of buffer bounds`);for(let i2=0;i2<16;++i2)buf[offset+i2]=rnds[i2];return buf}return unsafeStringify(rnds)}var v4_default;var init_v4=__esm(()=>{init_native();init_rng();init_stringify();v4_default=v4});var init_esm7=__esm(()=>{init_v4()});import{appendFile,mkdir as mkdir7,readFile as readFile6,writeFile as writeFile6}from"fs/promises";import path2,{join as join21}from"path";function mailboxDir(repoPath){return join21(repoPath,".genie","mailbox")}function mailboxFilePath(repoPath,workerId){let safeId=path2.basename(workerId);return join21(mailboxDir(repoPath),`${safeId}.json`)}function outboxFilePath(repoPath,workerId){let safeId=path2.basename(workerId);return join21(mailboxDir(repoPath),`${safeId}-sent.jsonl`)}async function loadMailbox(repoPath,workerId){try{let content=await readFile6(mailboxFilePath(repoPath,workerId),"utf-8");return JSON.parse(content)}catch{return{workerId,messages:[],lastUpdated:new Date().toISOString()}}}async function saveMailbox(repoPath,mailbox){let dir=mailboxDir(repoPath);await mkdir7(dir,{recursive:!0}),mailbox.lastUpdated=new Date().toISOString(),await writeFile6(mailboxFilePath(repoPath,mailbox.workerId),JSON.stringify(mailbox,null,2))}function generateMessageId(){return`msg-${v4_default()}`}async function send(repoPath,from,to,body){await mkdir7(mailboxDir(repoPath),{recursive:!0});let release=await acquireLock(mailboxFilePath(repoPath,to));try{let mailbox=await loadMailbox(repoPath,to),message={id:generateMessageId(),from,to,body,createdAt:new Date().toISOString(),read:!1,deliveredAt:null};mailbox.messages.push(message),await saveMailbox(repoPath,mailbox),await appendFile(outboxFilePath(repoPath,from),`${JSON.stringify(message)}
|
|
592
|
-
`);try{let{publish:publish2}=await Promise.resolve().then(() => (init_nats_client(),exports_nats_client));await publish2(`genie.msg.${to}`,{timestamp:message.createdAt,kind:"message",agent:from,direction:"out",peer:to,text:body,data:{messageId:message.id,from,to},source:"mailbox"})}catch{}return message}finally{await release()}}async function inbox(repoPath,workerId){return(await loadMailbox(repoPath,workerId)).messages}async function readOutbox(repoPath,workerId){try{let lines=(await readFile6(outboxFilePath(repoPath,workerId),"utf-8")).trim().split(`
|
|
593
|
-
`).filter(Boolean),messages2=[];for(let line of lines)try{messages2.push(JSON.parse(line))}catch{}return messages2}catch{return[]}}async function markDelivered(repoPath,workerId,messageId){await mkdir7(mailboxDir(repoPath),{recursive:!0});let release=await acquireLock(mailboxFilePath(repoPath,workerId));try{let mailbox=await loadMailbox(repoPath,workerId),msg=mailbox.messages.find((m)=>m.id===messageId);if(!msg)return!1;return msg.deliveredAt=new Date().toISOString(),await saveMailbox(repoPath,mailbox),!0}finally{await release()}}function toNativeInboxMessage(msg,color="blue"){let words=msg.body.split(/\s+/),summary=words.slice(0,8).join(" ")+(words.length>8?"...":"");return{from:msg.from,text:msg.body,summary,timestamp:msg.createdAt,color,read:!1}}var init_mailbox=__esm(()=>{init_esm7();init_file_lock()});var exports_protocol_router_spawn={};__export(exports_protocol_router_spawn,{spawnWorkerFromTemplate:()=>spawnWorkerFromTemplate});import{exec as exec2}from"child_process";import{readFile as readFile7}from"fs/promises";import{join as join22}from"path";import{promisify as promisify2}from"util";async function resolveParentSession(_repoPath,team){let teamConfig=await getTeam2(team);if(teamConfig?.nativeTeamParentSessionId)return teamConfig.nativeTeamParentSessionId;return await discoverClaudeSessionId()??`genie-${team}`}function buildSpawnParams2(template,parentSessionId,spawnColor,resumeSessionId){let isClaude=template.provider==="claude",sessionName=template.role?`${template.team}-${template.role}`:void 0,newSessionId=isClaude&&!resumeSessionId?crypto.randomUUID():void 0,params={provider:template.provider,team:template.team,role:template.role,skill:template.skill,extraArgs:template.extraArgs,sessionId:newSessionId,resume:isClaude?resumeSessionId:void 0,name:sessionName};if(isClaude)params.nativeTeam={enabled:!0,parentSessionId,color:spawnColor,agentType:template.role??"general-purpose",agentName:template.role};return params}function buildFullCommand(launch){if(launch.env&&Object.keys(launch.env).length>0)return`env ${Object.entries(launch.env).map(([k,v])=>`${k}=${v}`).join(" ")} ${launch.command}`;return launch.command}async function generateWorkerId2(team,role){let base=role?`${team}-${role}`:team;return(await list()).some((w)=>w.id===base)?`${base}-${crypto.randomUUID().slice(0,8)}`:base}async function spawnPaneInSession(session,team,repoPath,fullCommand){let teamWindow=null;try{teamWindow=await ensureTeamWindow(session,team,repoPath)}catch{}let splitTarget=teamWindow?`-t '${teamWindow.windowId}'`:"",{stdout}=await execAsync(`tmux split-window -d ${splitTarget} -P -F '#{pane_id}' ${fullCommand}`),paneId=stdout.trim(),layoutTarget=`${session}:${teamWindow?.windowName??""}`;if(!teamWindow){let wins=await listWindows(session);layoutTarget=wins[0]?wins[0].id:`${session}:`}try{await execAsync(`tmux ${buildLayoutCommand(layoutTarget,resolveLayoutMode())}`)}catch{}return{paneId,teamWindow}}async function spawnWorkerFromTemplate(template,resumeSessionId){let repoPath=template.cwd??process.cwd(),team=template.team,parentSessionId=await resolveParentSession(repoPath,team);await ensureNativeTeam(team,`Genie team: ${team}`,parentSessionId);let spawnColor=await assignColor(team),params=buildSpawnParams2(template,parentSessionId,spawnColor,resumeSessionId),launch=buildLaunchCommand(validateSpawnParams(params)),fullCommand=buildFullCommand(launch),workerId=await generateWorkerId2(team,template.role),session=await getCurrentSessionName()??team,{paneId,teamWindow}=await spawnPaneInSession(session,team,repoPath,fullCommand),now=new Date().toISOString(),agentName=template.role??"worker",isClaude=template.provider==="claude",effectiveSessionId=resumeSessionId??params.sessionId,workerEntry={id:workerId,paneId,session,provider:template.provider,transport:"tmux",role:template.role,skill:template.skill,team,worktree:null,startedAt:now,state:"spawning",lastStateChange:now,repoPath,claudeSessionId:effectiveSessionId,nativeTeamEnabled:isClaude,nativeAgentId:`${agentName}@${team}`,nativeColor:spawnColor,parentSessionId,window:teamWindow?.windowName,windowName:teamWindow?.windowName,windowId:teamWindow?.windowId};if(await register(workerEntry),await registerNativeMember(team,{agentName,agentType:template.role??"general-purpose",color:spawnColor??"blue",tmuxPaneId:paneId,cwd:repoPath}),await writeNativeInbox(team,"team-lead",{from:agentName,text:`Worker ${agentName} (${template.provider}) auto-spawned${resumeSessionId?" with --resume":""}. Ready for tasks.`,summary:`${agentName} auto-spawned`,timestamp:now,color:spawnColor??"blue",read:!1}),spawnColor)await applyPaneColor(paneId,spawnColor,teamWindow?.windowId);return await injectResumeContext(repoPath,workerId,agentName,team),{worker:workerEntry,paneId,workerId}}function extractGroupSection(content,groupName){let escaped=groupName.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),pattern=new RegExp(`^### Group ${escaped}:`,"m"),match=content.match(pattern);if(!match||match.index===void 0)return null;let start=match.index,nextBoundary=content.slice(start).slice(1).search(/^### Group \d|^---$/m),end=nextBoundary!==-1?start+1+nextBoundary:content.length;return content.slice(start,end).trim()}async function getRecentGitLog(repoPath,count=3){try{let{stdout}=await execAsync(`git -C '${repoPath}' log --oneline -${count} 2>/dev/null`);return stdout.trim()}catch{return""}}async function injectResumeContext(repoPath,workerId,agentName,_team){try{let match=await findAnyGroupByAssignee(workerId,repoPath)??await findAnyGroupByAssignee(agentName,repoPath);if(!match)return;let{slug,groupName,group}=match,wishPath=join22(repoPath,".genie","wishes",slug,"WISH.md"),groupSection="";try{let wishContent=await readFile7(wishPath,"utf-8");groupSection=extractGroupSection(wishContent,groupName)??""}catch{}let gitLog=await getRecentGitLog(repoPath),resumePrompt=[`RESUME CONTEXT: You were working on wish "${slug}", group "${groupName}".`,`Status: ${group.status}. Started at: ${group.startedAt??"unknown"}.`,`Wish file: .genie/wishes/${slug}/WISH.md`,"",groupSection?`Group section:
|
|
594
|
-
${groupSection}`:"","",gitLog?`Last git log:
|
|
595
|
-
${gitLog}`:"","","Pick up where you left off. Read the wish file for full context."].filter(Boolean).join(`
|
|
596
|
-
`);await send(repoPath,"genie",workerId,resumePrompt)}catch{}}var execAsync;var init_protocol_router_spawn=__esm(()=>{init_agent_registry();init_claude_native_teams();init_mailbox();init_provider_adapters();init_team_manager();init_tmux();init_wish_state();execAsync=promisify2(exec2)});var exports_protocol_router={};__export(exports_protocol_router,{sendMessage:()=>sendMessage,getInbox:()=>getInbox});async function waitForWorkerReady(paneId,timeoutMs=AUTO_SPAWN_READY_TIMEOUT_MS){let start=Date.now();while(Date.now()-start<timeoutMs){try{let content=await capturePaneContent(paneId,30);if(detectState(content).type==="idle")return!0}catch{}await new Promise((r)=>setTimeout(r,AUTO_SPAWN_POLL_INTERVAL_MS))}return!1}async function resolveRecipient(recipientId){let allWorkers=await list(),byId=[],byRole=[],byTeamRole=[];for(let w of allWorkers){if(w.state==="suspended")continue;if(!await isPaneAlive(w.paneId))continue;if(w.id===recipientId)byId.push(w);else if(w.role===recipientId)byRole.push(w);else if(`${w.team}:${w.role}`===recipientId)byTeamRole.push(w)}if(byId.length>0)return byId;if(byRole.length>0)return byRole;return byTeamRole}async function findLiveWorkerFuzzy(recipientId){let matches=await resolveRecipient(recipientId);return matches.length===1?matches[0]:null}async function ensureWorkerAlive(worker,recipientId){if(worker&&worker.state!=="suspended"&&await isPaneAlive(worker.paneId))return{worker,respawned:!1};let live=await findLiveWorkerFuzzy(recipientId);if(live)return{worker:live,respawned:!1};if(!process.env.TMUX)return null;let templates=await listTemplates(),candidates=[worker?.role,worker?.id,recipientId].filter((v)=>Boolean(v)),uniqueCandidates=[...new Set(candidates)],workerTeam=worker?.team,template=templates.find((t)=>{if(workerTeam&&t.team!==workerTeam)return!1;return uniqueCandidates.some((q)=>t.id===q||t.role===q||`${t.team}:${t.role}`===q)});if(!template)return null;let resumeSessionId=template.provider==="claude"&&worker?.claudeSessionId?worker.claudeSessionId:void 0;try{if(await cleanupDeadWorkers(recipientId,workerTeam),worker)await unregister(worker.id);let{spawnWorkerFromTemplate:spawnWorkerFromTemplate2}=await Promise.resolve().then(() => (init_protocol_router_spawn(),exports_protocol_router_spawn)),result=await spawnWorkerFromTemplate2(template,resumeSessionId);if(await saveTemplate({...template,lastSpawnedAt:new Date().toISOString()}),await waitForWorkerReady(result.paneId),!await isPaneAlive(result.paneId))return await unregister(result.worker.id),null;return{worker:result.worker,respawned:!0}}catch{return null}}async function cleanupDeadWorkers(recipientId,team){let allWorkers=await list();for(let w of allWorkers){if(team&&w.team!==team)continue;if(!(w.role===recipientId||w.id===recipientId))continue;if(await isPaneAlive(w.paneId))continue;await unregister(w.id)}}async function deliverToWorker(repoPath,from,worker,body){let message=await send(repoPath,from,worker.id,body),delivered=!1;if(worker.nativeTeamEnabled&&worker.team&&worker.role)delivered=await writeToNativeInbox(worker,message);else delivered=await injectToTmuxPane(worker,message);if(!delivered&&worker.team){let agentName=worker.role||worker.id.split("-").slice(-1)[0]||worker.id;try{let nativeMsg=toNativeInboxMessage(message,worker.nativeColor??"blue");await writeNativeInbox(worker.team,agentName,nativeMsg),delivered=!0}catch{}}if(delivered)await markDelivered(repoPath,worker.id,message.id);return{messageId:message.id,workerId:worker.id,delivered}}async function deliverViaNativeInbox(repoPath,from,to,body,teamName){let resolvedTeam=teamName??await discoverTeamName();if(!resolvedTeam)return null;let config=await loadConfig(resolvedTeam).catch(()=>null);if(!config)return null;let sanitizedTo=sanitizeTeamName(to),matchedMember=config.members?.find((m)=>m.name===to||m.name===sanitizedTo||m.agentId===`${to}@${resolvedTeam}`||m.agentId===`${sanitizedTo}@${resolvedTeam}`);if(!matchedMember)return null;let inboxName=matchedMember.name??to;try{let message=await send(repoPath,from,to,body),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1};return await writeNativeInbox(resolvedTeam,inboxName,nativeMsg),await markDelivered(repoPath,to,message.id),{messageId:message.id,workerId:to,delivered:!0}}catch{return null}}async function sendMessage(repoPath,from,to,body,teamName){let liveMatches=await resolveRecipient(to);if(liveMatches.length===1)return deliverToWorker(repoPath,from,liveMatches[0],body);if(liveMatches.length>1)return{messageId:"",workerId:to,delivered:!1,reason:`Worker "${to}" is ambiguous. Found ${liveMatches.length} live matches: ${liveMatches.map((m)=>m.id).join(", ")}. Use exact worker ID.`};let{resolve:resolve4}=await Promise.resolve().then(() => (init_agent_directory(),exports_agent_directory)),dirResolved=await resolve4(to),worker=await get(to);if(!worker){let allWorkers=await list();worker=allWorkers.find((w)=>w.role===to&&w.state==="suspended")??allWorkers.find((w)=>w.role===to)??null}if(dirResolved||worker){let alive=await ensureWorkerAlive(worker,to);if(alive)return deliverToWorker(repoPath,from,alive.worker,body)}let nativeResult=await deliverViaNativeInbox(repoPath,from,to,body,teamName);if(nativeResult)return nativeResult;return{messageId:"",workerId:to,delivered:!1,reason:`Worker "${to}" not found or not alive`}}async function writeToNativeInbox(worker,message){try{let nativeMsg=toNativeInboxMessage(message,worker.nativeColor??"blue"),agentName=worker.role??worker.id;return await writeNativeInbox(worker.team??"",agentName,nativeMsg),!0}catch{return!1}}async function injectToTmuxPane(worker,message){if(!worker.paneId)return!1;if(!/^%\d+$/.test(worker.paneId))return!1;try{let escaped=message.body.replace(/'/g,"'\\''");return await executeTmux2(`send-keys -t '${worker.paneId}' '${escaped}'`),await new Promise((resolve4)=>setTimeout(resolve4,200)),await executeTmux2(`send-keys -t '${worker.paneId}' Enter`),!0}catch{return!1}}async function getInbox(repoPath,workerId){return inbox(repoPath,workerId)}var AUTO_SPAWN_READY_TIMEOUT_MS=15000,AUTO_SPAWN_POLL_INTERVAL_MS=1000;var init_protocol_router=__esm(()=>{init_agent_registry();init_claude_native_teams();init_mailbox();init_orchestrator();init_tmux()});var exports_claude_logs={};__export(exports_claude_logs,{readLogFile:()=>readLogFile,projectPathToHash:()=>projectPathToHash,parseLogEntry:()=>parseLogEntry,listSessions:()=>listSessions2,getLogsForPane:()=>getLogsForPane,findClaudeProjectDir:()=>findClaudeProjectDir,findActiveSession:()=>findActiveSession,claudeTranscriptProvider:()=>claudeTranscriptProvider,claudeEntryToTranscript:()=>claudeEntryToTranscript});import{access,readFile as readFile10,readdir as readdir3,stat as stat3}from"fs/promises";import{join as join25}from"path";function projectPathToHash(projectPath){let normalized=projectPath.replace(/\/+$/,"");if(!normalized)normalized="/";return normalized.replace(/[/.]/g,"-")}function getClaudeDir(){return join25(process.env.HOME||"",".claude")}function getProjectsDir(claudeDir){return join25(claudeDir||getClaudeDir(),"projects")}async function findClaudeProjectDir(projectPath,claudeDir){let projectsDir=getProjectsDir(claudeDir),expectedHash=projectPathToHash(projectPath);try{await access(projectsDir);let projectDir=join25(projectsDir,expectedHash);return await access(projectDir),projectDir}catch{return null}}async function listSessions2(projectDir){let indexPath=join25(projectDir,"sessions-index.json");try{let content=await readFile10(indexPath,"utf-8");return JSON.parse(content).entries}catch{return await scanForSessions(projectDir)}}async function scanForSessions(projectDir){let sessions=[];try{let entries=await readdir3(projectDir);for(let entry of entries)if(entry.endsWith(".jsonl")&&!entry.startsWith(".")){let filePath=join25(projectDir,entry),stats=await stat3(filePath),sessionId=entry.replace(".jsonl","");sessions.push({sessionId,fullPath:filePath,fileMtime:stats.mtimeMs,messageCount:0,created:stats.birthtime.toISOString(),modified:stats.mtime.toISOString(),projectPath:"",isSidechain:!1})}}catch{}return sessions}async function findActiveSession(projectDir){let sessions=await listSessions2(projectDir);if(sessions.length===0)return null;return sessions.sort((a,b2)=>{let timeA=new Date(a.modified).getTime();return new Date(b2.modified).getTime()-timeA}),sessions[0]}function extractToolCalls(content){let toolCalls=[];for(let item of content)if(item.type==="tool_use")toolCalls.push({id:item.id||"",name:item.name||"",input:item.input||{}});return toolCalls.length>0?toolCalls:void 0}function populateAssistantFields(entry,raw){if(raw.type!=="assistant")return;if(Array.isArray(raw.message.content))entry.toolCalls=extractToolCalls(raw.message.content);if(raw.message.model)entry.model=raw.message.model;if(raw.message.usage)entry.usage=raw.message.usage}function parseLogEntry(line){if(!line||!line.trim())return null;try{let raw=JSON.parse(line);if(!raw.type)return null;let entry={type:raw.type,sessionId:raw.sessionId||"",uuid:raw.uuid||"",parentUuid:raw.parentUuid||null,timestamp:raw.timestamp||"",cwd:raw.cwd||"",gitBranch:raw.gitBranch,version:raw.version,raw};if(raw.message)entry.message={role:raw.message.role,content:raw.message.content},populateAssistantFields(entry,raw);if(raw.data)entry.data=raw.data;return entry}catch{return null}}async function readLogFile(logPath){let entries=[];try{let lines=(await readFile10(logPath,"utf-8")).split(`
|
|
597
|
+
`,deps.log({timestamp:now.toISOString(),level:"debug",event:"machine_snapshot",active_workers:activeWorkers,active_teams:teams.size,tmux_sessions:tmuxSessions,cpu_percent:cpuPercent,memory_mb:memoryMb})}async function emitWorkerEvents(deps){let workers=await deps.listWorkers(),now=deps.now().toISOString(),currentIds=new Set;for(let worker of workers){currentIds.add(worker.id);let prev=previousWorkerStates.get(worker.id);if(!prev)await deps.publishEvent(`genie.agent.${worker.id}.spawned`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} spawned`,data:{state:worker.state},source:"registry"});else if(prev.state!==worker.state){if(await deps.publishEvent(`genie.agent.${worker.id}.state`,{timestamp:now,kind:"state",agent:worker.id,team:worker.team,text:`Agent ${worker.id} state: ${prev.state} \u2192 ${worker.state}`,data:{previousState:prev.state,state:worker.state},source:"registry"}),worker.state==="done"&&worker.wishSlug&&worker.groupNumber!=null)await deps.publishEvent(`genie.wish.${worker.wishSlug}.group.${worker.groupNumber}.done`,{timestamp:now,kind:"system",agent:worker.id,team:worker.team,text:`Wish ${worker.wishSlug} group ${worker.groupNumber} completed by ${worker.id}`,data:{wishSlug:worker.wishSlug,groupNumber:worker.groupNumber},source:"registry"})}previousWorkerStates.set(worker.id,{...worker})}for(let[id,prev]of previousWorkerStates)if(!currentIds.has(id))await deps.publishEvent(`genie.agent.${id}.killed`,{timestamp:now,kind:"state",agent:id,team:prev.team,text:`Agent ${id} killed`,data:{lastState:prev.state},source:"registry"}),previousWorkerStates.delete(id)}function _resetWorkerStatesForTesting(){previousWorkerStates.clear()}function startDaemon(configOverrides,depsOverrides){let config=resolveConfig(configOverrides),deps={...createDefaultDeps(),...depsOverrides},daemonId=deps.generateId(),running=!0,pollTimeout=null,pollResolve=null,listenConnection=null,heartbeatTimer=null,orphanTimer=null,stop=()=>{if(running=!1,pollTimeout)clearTimeout(pollTimeout),pollTimeout=null;if(pollResolve)pollResolve(),pollResolve=null;if(heartbeatTimer)clearInterval(heartbeatTimer),heartbeatTimer=null;if(orphanTimer)clearInterval(orphanTimer),orphanTimer=null;if(listenConnection)listenConnection.end().catch(()=>{}),listenConnection=null},processTriggers=async()=>{try{let claimed=await claimDueTriggers(deps,config,daemonId);if(claimed.length===0)return;if(claimed.length>config.jitterThreshold){let jitterMs=deps.jitter(config.maxJitterMs);deps.log({timestamp:deps.now().toISOString(),level:"info",event:"jitter_applied",count:claimed.length,jitter_ms:jitterMs}),await deps.sleep(jitterMs)}for(let trigger of claimed){if(!running)break;await fireTrigger(deps,trigger,daemonId)}}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"process_cycle_error",error:message})}},done=(async()=>{deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_started",daemon_id:daemonId,max_concurrent:config.maxConcurrent,poll_interval_ms:config.pollIntervalMs});try{await recoverOnStartup(deps,daemonId,config)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"recovery_error",error:message})}try{let sql=await deps.getConnection();listenConnection=sql,await sql.listen("genie_trigger_due",async()=>{if(!running)return;await processTriggers()}),deps.log({timestamp:deps.now().toISOString(),level:"info",event:"listen_started",channel:"genie_trigger_due"})}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"warn",event:"listen_failed",error:message})}heartbeatTimer=setInterval(async()=>{if(!running)return;try{await collectHeartbeats(deps),await collectMachineSnapshot(deps),await emitWorkerEvents(deps)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"heartbeat_error",error:message})}},config.heartbeatIntervalMs),orphanTimer=setInterval(async()=>{if(!running)return;try{await reconcileOrphans(deps,config)}catch(err){let message=err instanceof Error?err.message:String(err);deps.log({timestamp:deps.now().toISOString(),level:"error",event:"orphan_reconciliation_error",error:message})}},config.orphanCheckIntervalMs),await processTriggers();while(running){if(await new Promise((resolve4)=>{pollResolve=resolve4,pollTimeout=setTimeout(resolve4,config.pollIntervalMs)}),pollResolve=null,!running)break;await processTriggers()}deps.log({timestamp:deps.now().toISOString(),level:"info",event:"daemon_stopped",daemon_id:daemonId})})();return{stop,done,daemonId}}var RESUME_COOLDOWN_MS=60000,DEFAULT_MAX_RESUME_ATTEMPTS=3,previousWorkerStates;var init_scheduler_daemon=__esm(()=>{init_cron();init_run_spec();previousWorkerStates=new Map});var exports_protocol_router={};__export(exports_protocol_router,{sendMessage:()=>sendMessage,getInbox:()=>getInbox});async function waitForWorkerReady(paneId,timeoutMs=AUTO_SPAWN_READY_TIMEOUT_MS){let start=Date.now();while(Date.now()-start<timeoutMs){try{let content=await capturePaneContent(paneId,30);if(detectState(content).type==="idle")return!0}catch{}await new Promise((r)=>setTimeout(r,AUTO_SPAWN_POLL_INTERVAL_MS))}return!1}async function resolveRecipient(recipientId){let allWorkers=await list(),byId=[],byRole=[],byTeamRole=[];for(let w of allWorkers){if(w.state==="suspended")continue;if(!await isPaneAlive(w.paneId))continue;if(w.id===recipientId)byId.push(w);else if(w.role===recipientId)byRole.push(w);else if(`${w.team}:${w.role}`===recipientId)byTeamRole.push(w)}if(byId.length>0)return byId;if(byRole.length>0)return byRole;return byTeamRole}async function findLiveWorkerFuzzy(recipientId){let matches=await resolveRecipient(recipientId);return matches.length===1?matches[0]:null}async function ensureWorkerAlive(worker,recipientId){if(worker&&worker.state!=="suspended"&&await isPaneAlive(worker.paneId))return{worker,respawned:!1};let live=await findLiveWorkerFuzzy(recipientId);if(live)return{worker:live,respawned:!1};if(!process.env.TMUX)return null;let templates=await listTemplates(),candidates=[worker?.role,worker?.id,recipientId].filter((v)=>Boolean(v)),uniqueCandidates=[...new Set(candidates)],workerTeam=worker?.team,template=templates.find((t)=>{if(workerTeam&&t.team!==workerTeam)return!1;return uniqueCandidates.some((q)=>t.id===q||t.role===q||`${t.team}:${t.role}`===q)});if(!template)return null;let resumeSessionId=template.provider==="claude"&&worker?.claudeSessionId?worker.claudeSessionId:void 0;try{if(await cleanupDeadWorkers(recipientId,workerTeam),worker)await unregister(worker.id);let{spawnWorkerFromTemplate:spawnWorkerFromTemplate2}=await Promise.resolve().then(() => (init_protocol_router_spawn(),exports_protocol_router_spawn)),result=await spawnWorkerFromTemplate2(template,resumeSessionId);if(await saveTemplate({...template,lastSpawnedAt:new Date().toISOString()}),await waitForWorkerReady(result.paneId),!await isPaneAlive(result.paneId))return await unregister(result.worker.id),null;return{worker:result.worker,respawned:!0}}catch{return null}}async function cleanupDeadWorkers(recipientId,team){let allWorkers=await list();for(let w of allWorkers){if(team&&w.team!==team)continue;if(!(w.role===recipientId||w.id===recipientId))continue;if(await isPaneAlive(w.paneId))continue;await unregister(w.id)}}async function deliverToWorker(repoPath,from,worker,body){let message=await send(repoPath,from,worker.id,body),delivered=!1;if(worker.nativeTeamEnabled&&worker.team&&worker.role)delivered=await writeToNativeInbox(worker,message);else delivered=await injectToTmuxPane(worker,message);if(!delivered&&worker.team){let agentName=worker.role||worker.id.split("-").slice(-1)[0]||worker.id;try{let nativeMsg=toNativeInboxMessage(message,worker.nativeColor??"blue");await writeNativeInbox(worker.team,agentName,nativeMsg),delivered=!0}catch{}}if(delivered)await markDelivered(repoPath,worker.id,message.id);return{messageId:message.id,workerId:worker.id,delivered}}async function deliverViaNativeInbox(repoPath,from,to,body,teamName){let resolvedTeam=teamName??await discoverTeamName();if(!resolvedTeam)return null;let config=await loadConfig(resolvedTeam).catch(()=>null);if(!config)return null;let sanitizedTo=sanitizeTeamName(to),matchedMember=config.members?.find((m)=>m.name===to||m.name===sanitizedTo||m.agentId===`${to}@${resolvedTeam}`||m.agentId===`${sanitizedTo}@${resolvedTeam}`);if(!matchedMember)return null;let inboxName=matchedMember.name??to;try{let message=await send(repoPath,from,to,body),nativeMsg={from,text:body,summary:body.length>50?`${body.substring(0,50)}...`:body,timestamp:new Date().toISOString(),color:"blue",read:!1};return await writeNativeInbox(resolvedTeam,inboxName,nativeMsg),await markDelivered(repoPath,to,message.id),{messageId:message.id,workerId:to,delivered:!0}}catch{return null}}async function sendMessage(repoPath,from,to,body,teamName){let liveMatches=await resolveRecipient(to);if(liveMatches.length===1)return deliverToWorker(repoPath,from,liveMatches[0],body);if(liveMatches.length>1)return{messageId:"",workerId:to,delivered:!1,reason:`Worker "${to}" is ambiguous. Found ${liveMatches.length} live matches: ${liveMatches.map((m)=>m.id).join(", ")}. Use exact worker ID.`};let{resolve:resolve4}=await Promise.resolve().then(() => (init_agent_directory(),exports_agent_directory)),dirResolved=await resolve4(to),worker=await get(to);if(!worker){let allWorkers=await list();worker=allWorkers.find((w)=>w.role===to&&w.state==="suspended")??allWorkers.find((w)=>w.role===to)??null}if(dirResolved||worker){let alive=await ensureWorkerAlive(worker,to);if(alive)return deliverToWorker(repoPath,from,alive.worker,body)}let nativeResult=await deliverViaNativeInbox(repoPath,from,to,body,teamName);if(nativeResult)return nativeResult;return{messageId:"",workerId:to,delivered:!1,reason:`Worker "${to}" not found or not alive`}}async function writeToNativeInbox(worker,message){try{let nativeMsg=toNativeInboxMessage(message,worker.nativeColor??"blue"),agentName=worker.role??worker.id;return await writeNativeInbox(worker.team??"",agentName,nativeMsg),!0}catch{return!1}}async function injectToTmuxPane(worker,message){if(!worker.paneId)return!1;if(!/^%\d+$/.test(worker.paneId))return!1;try{let escaped=message.body.replace(/'/g,"'\\''");return await executeTmux2(`send-keys -t '${worker.paneId}' '${escaped}'`),await new Promise((resolve4)=>setTimeout(resolve4,200)),await executeTmux2(`send-keys -t '${worker.paneId}' Enter`),!0}catch{return!1}}async function getInbox(repoPath,workerId){return inbox(repoPath,workerId)}var AUTO_SPAWN_READY_TIMEOUT_MS=15000,AUTO_SPAWN_POLL_INTERVAL_MS=1000;var init_protocol_router=__esm(()=>{init_agent_registry();init_claude_native_teams();init_mailbox();init_orchestrator();init_tmux()});var exports_claude_logs={};__export(exports_claude_logs,{readLogFile:()=>readLogFile,projectPathToHash:()=>projectPathToHash,parseLogEntry:()=>parseLogEntry,listSessions:()=>listSessions2,getLogsForPane:()=>getLogsForPane,findClaudeProjectDir:()=>findClaudeProjectDir,findActiveSession:()=>findActiveSession,claudeTranscriptProvider:()=>claudeTranscriptProvider,claudeEntryToTranscript:()=>claudeEntryToTranscript});import{access,readFile as readFile10,readdir as readdir3,stat as stat3}from"fs/promises";import{join as join25}from"path";function projectPathToHash(projectPath){let normalized=projectPath.replace(/\/+$/,"");if(!normalized)normalized="/";return normalized.replace(/[/.]/g,"-")}function getClaudeDir(){return join25(process.env.HOME||"",".claude")}function getProjectsDir(claudeDir){return join25(claudeDir||getClaudeDir(),"projects")}async function findClaudeProjectDir(projectPath,claudeDir){let projectsDir=getProjectsDir(claudeDir),expectedHash=projectPathToHash(projectPath);try{await access(projectsDir);let projectDir=join25(projectsDir,expectedHash);return await access(projectDir),projectDir}catch{return null}}async function listSessions2(projectDir){let indexPath=join25(projectDir,"sessions-index.json");try{let content=await readFile10(indexPath,"utf-8");return JSON.parse(content).entries}catch{return await scanForSessions(projectDir)}}async function scanForSessions(projectDir){let sessions=[];try{let entries=await readdir3(projectDir);for(let entry of entries)if(entry.endsWith(".jsonl")&&!entry.startsWith(".")){let filePath=join25(projectDir,entry),stats=await stat3(filePath),sessionId=entry.replace(".jsonl","");sessions.push({sessionId,fullPath:filePath,fileMtime:stats.mtimeMs,messageCount:0,created:stats.birthtime.toISOString(),modified:stats.mtime.toISOString(),projectPath:"",isSidechain:!1})}}catch{}return sessions}async function findActiveSession(projectDir){let sessions=await listSessions2(projectDir);if(sessions.length===0)return null;return sessions.sort((a,b2)=>{let timeA=new Date(a.modified).getTime();return new Date(b2.modified).getTime()-timeA}),sessions[0]}function extractToolCalls(content){let toolCalls=[];for(let item of content)if(item.type==="tool_use")toolCalls.push({id:item.id||"",name:item.name||"",input:item.input||{}});return toolCalls.length>0?toolCalls:void 0}function populateAssistantFields(entry,raw){if(raw.type!=="assistant")return;if(Array.isArray(raw.message.content))entry.toolCalls=extractToolCalls(raw.message.content);if(raw.message.model)entry.model=raw.message.model;if(raw.message.usage)entry.usage=raw.message.usage}function parseLogEntry(line){if(!line||!line.trim())return null;try{let raw=JSON.parse(line);if(!raw.type)return null;let entry={type:raw.type,sessionId:raw.sessionId||"",uuid:raw.uuid||"",parentUuid:raw.parentUuid||null,timestamp:raw.timestamp||"",cwd:raw.cwd||"",gitBranch:raw.gitBranch,version:raw.version,raw};if(raw.message)entry.message={role:raw.message.role,content:raw.message.content},populateAssistantFields(entry,raw);if(raw.data)entry.data=raw.data;return entry}catch{return null}}async function readLogFile(logPath){let entries=[];try{let lines=(await readFile10(logPath,"utf-8")).split(`
|
|
597
598
|
`);for(let line of lines){let entry=parseLogEntry(line);if(entry)entries.push(entry)}}catch{}return entries}async function findLogsForWorkspace(workspacePath,claudeDir){let projectDir=await findClaudeProjectDir(workspacePath,claudeDir);if(!projectDir)return null;let session=await findActiveSession(projectDir);if(!session)return null;return{projectDir,session}}async function getLogsForPane(paneWorkdir,claudeDir){let result=await findLogsForWorkspace(paneWorkdir,claudeDir);if(!result)return null;return{logPath:result.session.fullPath,session:result.session,projectDir:result.projectDir}}function extractText(content){if(typeof content==="string")return content;if(!Array.isArray(content))return"";let parts=[];for(let item of content)if(typeof item==="string")parts.push(item);else if(item&&typeof item==="object"&&"text"in item)parts.push(String(item.text));return parts.join(" ")}function convertAssistant(entry,base){let results=[],text=entry.message?extractText(entry.message.content):"";if(text)results.push({...base,role:"assistant",timestamp:entry.timestamp,text,usage:entry.usage?{input:entry.usage.input_tokens,output:entry.usage.output_tokens}:void 0});if(entry.toolCalls)for(let tc of entry.toolCalls)results.push({...base,role:"tool_call",timestamp:entry.timestamp,text:`${tc.name}: ${JSON.stringify(tc.input).slice(0,200)}`,toolCall:{id:tc.id,name:tc.name,input:tc.input}});return results}function claudeEntryToTranscript(entry){let base={provider:"claude",model:entry.model,raw:entry.raw};if(entry.type==="user"&&entry.message){let text=extractText(entry.message.content);return text?[{...base,role:"user",timestamp:entry.timestamp,text}]:[]}if(entry.type==="assistant")return convertAssistant(entry,base);if(entry.type==="system"||entry.type==="progress"){let text=entry.message?extractText(entry.message.content):"";return text?[{...base,role:"system",timestamp:entry.timestamp,text}]:[]}return[]}var claudeTranscriptProvider;var init_claude_logs=__esm(()=>{claudeTranscriptProvider={async discoverLogPath(worker){let workspacePath=worker.worktree||worker.repoPath;return(await getLogsForPane(workspacePath))?.logPath??null},async readEntries(logPath){return(await readLogFile(logPath)).flatMap(claudeEntryToTranscript)}}});var exports_codex_logs={};__export(exports_codex_logs,{parseCodexLine:()=>parseCodexLine,extractCodexContent:()=>extractCodexContent,discoverViaSqlite:()=>discoverViaSqlite,discoverViaScan:()=>discoverViaScan,codexTranscriptProvider:()=>codexTranscriptProvider});import{access as access2,readFile as readFile11,readdir as readdir4}from"fs/promises";import{homedir as homedir18}from"os";import{join as join26}from"path";function getCodexDir(){return join26(homedir18(),".codex")}function getSessionsDir(){return join26(getCodexDir(),"sessions")}function getStateDbPath(){return join26(getCodexDir(),"state_5.sqlite")}async function discoverLogPath(worker){let cwd=worker.worktree||worker.repoPath,sqlitePath=await discoverViaSqlite(cwd);if(sqlitePath)try{return await access2(sqlitePath),sqlitePath}catch{}return discoverViaScan(cwd)}async function discoverViaSqlite(cwd){try{let{Database}=await import("bun:sqlite"),dbPath=getStateDbPath(),db=new Database(dbPath,{readonly:!0});try{return db.query("SELECT rollout_path FROM threads WHERE cwd = ? ORDER BY updated_at DESC LIMIT 1").get(cwd)?.rollout_path??null}finally{db.close()}}catch{return null}}async function listDirsDesc(parent,pattern){return(await readdir4(parent)).filter((d)=>pattern.test(d)).sort().reverse()}async function discoverViaScan(cwd){let sessionsDir=getSessionsDir();try{let years=await listDirsDesc(sessionsDir,/^\d{4}$/);for(let year of years.slice(0,2)){let result=await scanYear(join26(sessionsDir,year),cwd);if(result)return result}}catch{}return null}async function scanYear(yearDir,cwd){let months=await listDirsDesc(yearDir,/^\d{2}$/);for(let month of months.slice(0,2)){let result=await scanMonth(join26(yearDir,month),cwd);if(result)return result}return null}async function scanMonth(monthDir,cwd){let days=await listDirsDesc(monthDir,/^\d{2}$/);for(let day of days.slice(0,3)){let result=await scanDay(join26(monthDir,day),cwd);if(result)return result}return null}async function scanDay(dayDir,cwd){let files=(await readdir4(dayDir)).filter((f)=>f.endsWith(".jsonl")).sort().reverse();for(let file of files.slice(0,5)){let filePath=join26(dayDir,file);if((await readSessionMeta(filePath))?.cwd===cwd)return filePath}return null}async function readSessionMeta(filePath){try{let content=await readFile11(filePath,"utf-8"),nlIdx=content.indexOf(`
|
|
598
599
|
`),firstLine=nlIdx===-1?content:content.slice(0,nlIdx),entry=JSON.parse(firstLine);if(entry.type==="session_meta"&&entry.payload?.cwd)return{cwd:entry.payload.cwd}}catch{}return null}function parseEventMsg(payload,ts,base){if(payload.type==="user_message"){let text=String(payload.message??"");return text?[{...base,role:"user",timestamp:ts,text}]:[]}if(payload.type==="agent_message"){let text=String(payload.message??"");return text?[{...base,role:"assistant",timestamp:ts,text}]:[]}return[]}function parseResponseMessage(payload,ts,base){let role=payload.role,text=extractCodexContent(payload.content);if(!text)return[];if(role==="user")return[{...base,role:"user",timestamp:ts,text}];if(role==="developer")return[{...base,role:"system",timestamp:ts,text}];if(role==="assistant")return[{...base,role:"assistant",timestamp:ts,text}];return[]}function parseFunctionCall(payload,ts,base){let name=String(payload.name??payload.type),callId=String(payload.call_id??""),input={};try{input=typeof payload.arguments==="string"?JSON.parse(payload.arguments):{}}catch{input={raw:payload.arguments}}let cmdText=input.command?String(Array.isArray(input.command)?input.command.join(" "):input.command):name;return[{...base,role:"tool_call",timestamp:ts,text:`${name}: ${cmdText.slice(0,200)}`,toolCall:{id:callId,name,input}}]}function parseWebSearch(payload,ts,base){let action=payload.action,query=String(action?.query??"web search");return[{...base,role:"tool_call",timestamp:ts,text:`web_search: ${query.slice(0,200)}`,toolCall:{id:"",name:"web_search",input:{query}}}]}function parseResponseItem(payload,ts,base){if(payload.type==="message")return parseResponseMessage(payload,ts,base);if(payload.type==="function_call"||payload.type==="shell")return parseFunctionCall(payload,ts,base);if(payload.type==="function_call_output"){let output=String(payload.output??"").slice(0,500);return[{...base,role:"tool_result",timestamp:ts,text:output}]}if(payload.type==="web_search_call")return parseWebSearch(payload,ts,base);return[]}function parseCodexLine(line){if(!line.trim())return[];let raw;try{raw=JSON.parse(line)}catch{return[]}if(!raw.type||!raw.timestamp)return[];let base={provider:"codex",raw};if(!raw.payload||typeof raw.payload!=="object")return[];if(raw.type==="event_msg")return parseEventMsg(raw.payload,raw.timestamp,base);if(raw.type==="response_item")return parseResponseItem(raw.payload,raw.timestamp,base);return[]}function extractCodexContent(content){if(typeof content==="string")return content;if(!Array.isArray(content))return"";let parts=[];for(let item of content)if(typeof item==="string")parts.push(item);else if(item&&typeof item==="object"){if("text"in item)parts.push(String(item.text));else if("input_text"in item)parts.push(String(item.input_text))}return parts.join(" ")}async function readEntries(logPath){let content;try{content=await readFile11(logPath,"utf-8")}catch{return[]}return content.split(`
|
|
599
600
|
`).flatMap(parseCodexLine)}var codexTranscriptProvider;var init_codex_logs=__esm(()=>{codexTranscriptProvider={discoverLogPath,readEntries}});var exports_transcript={};__export(exports_transcript,{readTranscript:()=>readTranscript,getProvider:()=>getProvider,applyFilter:()=>applyFilter});function applyFilter(entries,filter){if(!filter)return entries;let result=entries;if(filter.since){let sinceMs=new Date(filter.since).getTime();result=result.filter((e)=>new Date(e.timestamp).getTime()>=sinceMs)}if(filter.roles&&filter.roles.length>0){let roles=new Set(filter.roles);result=result.filter((e)=>roles.has(e.role))}if(filter.last&&filter.last>0)result=result.slice(-filter.last);return result}async function getClaudeProvider(){if(!_claudeProvider)_claudeProvider=(await Promise.resolve().then(() => (init_claude_logs(),exports_claude_logs))).claudeTranscriptProvider;return _claudeProvider}async function getCodexProvider(){if(!_codexProvider)_codexProvider=(await Promise.resolve().then(() => (init_codex_logs(),exports_codex_logs))).codexTranscriptProvider;return _codexProvider}async function getProvider(worker){if((worker.provider??"claude")==="codex")return getCodexProvider();return getClaudeProvider()}async function readTranscript(worker,filter){let provider=await getProvider(worker),logPath=await provider.discoverLogPath(worker);if(!logPath)return[];let entries=await provider.readEntries(logPath);return applyFilter(entries,filter)}var _claudeProvider,_codexProvider;var exports_task_service={};__export(exports_task_service,{updateTask:()=>updateTask,updateMessage:()=>updateMessage,untagTask:()=>untagTask,unblockTask:()=>unblockTask,tagTask:()=>tagTask,setRelease:()=>setRelease,setPreference:()=>setPreference,sendMessage:()=>sendMessage2,resolveTaskId:()=>resolveTaskId,resolveChannels:()=>resolveChannels,removeMember:()=>removeMember,removeDependency:()=>removeDependency,removeActor:()=>removeActor,releaseTask:()=>releaseTask,moveTask:()=>moveTask,markDone:()=>markDone,listTypes:()=>listTypes,listTasksForActor:()=>listTasksForActor,listTasks:()=>listTasks,listTags:()=>listTags,listReleases:()=>listReleases,listProjects:()=>listProjects,listConversations:()=>listConversations,getType:()=>getType,getTaskTags:()=>getTaskTags,getTaskActors:()=>getTaskActors,getTask:()=>getTask,getStageLog:()=>getStageLog,getRepoPath:()=>getRepoPath,getProjectByRepoPath:()=>getProjectByRepoPath,getProjectByName:()=>getProjectByName,getPreferences:()=>getPreferences,getMessages:()=>getMessages,getMessage:()=>getMessage,getMembers:()=>getMembers,getDependents:()=>getDependents,getConversation:()=>getConversation,getCheckoutOwner:()=>getCheckoutOwner,getBlockers:()=>getBlockers,forceUnlockTask:()=>forceUnlockTask,findOrCreateConversation:()=>findOrCreateConversation,expireStaleCheckouts:()=>expireStaleCheckouts,ensureProject:()=>ensureProject,deletePreference:()=>deletePreference,createType:()=>createType,createTask:()=>createTask,createTag:()=>createTag,createProject:()=>createProject,commentOnTask:()=>commentOnTask,checkoutTask:()=>checkoutTask,blockTask:()=>blockTask,assignTask:()=>assignTask,addMember:()=>addMember,addDependency:()=>addDependency});import{execSync as execSync7}from"child_process";function str2(v){return v!=null?String(v):null}function strOrDefault(v,def){return v!=null?String(v):def}function mapTask(row){return{id:row.id,seq:row.seq,parentId:str2(row.parent_id),repoPath:row.repo_path,projectId:str2(row.project_id),genieOsFolderId:str2(row.genie_os_folder_id),wishFile:str2(row.wish_file),groupName:str2(row.group_name),title:row.title,description:str2(row.description),acceptanceCriteria:str2(row.acceptance_criteria),typeId:row.type_id,stage:row.stage,status:row.status,priority:row.priority,startDate:str2(row.start_date),dueDate:str2(row.due_date),estimatedEffort:str2(row.estimated_effort),startedAt:str2(row.started_at),endedAt:str2(row.ended_at),blockedReason:str2(row.blocked_reason),releaseId:str2(row.release_id),checkoutRunId:str2(row.checkout_run_id),executionLockedAt:str2(row.execution_locked_at),checkoutTimeoutMs:row.checkout_timeout_ms??600000,sessionId:str2(row.session_id),paneId:str2(row.pane_id),traceId:str2(row.trace_id),metadata:row.metadata??{},createdAt:strOrDefault(row.created_at,""),updatedAt:strOrDefault(row.updated_at,"")}}function mapConversation(row){return{id:row.id,parentMessageId:row.parent_message_id!=null?Number(row.parent_message_id):null,name:row.name??null,type:row.type,linkedEntity:row.linked_entity??null,linkedEntityId:row.linked_entity_id??null,createdByType:row.created_by_type??null,createdById:row.created_by_id??null,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapMessage(row){return{id:Number(row.id),conversationId:row.conversation_id,replyToId:row.reply_to_id!=null?Number(row.reply_to_id):null,senderType:row.sender_type,senderId:row.sender_id,body:row.body,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapTaskActor(row){return{taskId:row.task_id,actorType:row.actor_type,actorId:row.actor_id,role:row.role,permissions:row.permissions??{},createdAt:String(row.created_at)}}function mapDependency(row){return{taskId:row.task_id,dependsOnId:row.depends_on_id,depType:row.dep_type,createdAt:String(row.created_at)}}function mapTag(row){return{id:row.id,name:row.name,color:row.color??"#9ca3af",typeId:row.type_id??null,createdAt:String(row.created_at)}}function mapTaskType(row){return{id:row.id,name:row.name,description:row.description??null,icon:row.icon??null,stages:row.stages,isBuiltin:row.is_builtin,createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapNotificationPref(row){return{actorType:row.actor_type,actorId:row.actor_id,channel:row.channel,priorityThreshold:row.priority_threshold,isDefault:row.is_default,enabled:row.enabled,metadata:row.metadata??{},createdAt:String(row.created_at),updatedAt:String(row.updated_at)}}function mapStageLog(row){return{id:Number(row.id),taskId:row.task_id,fromStage:row.from_stage??null,toStage:row.to_stage,actorType:row.actor_type??null,actorId:row.actor_id??null,runId:row.run_id??null,gateType:row.gate_type??null,createdAt:String(row.created_at)}}function mapConversationMember(row){return{conversationId:row.conversation_id,actorType:row.actor_type,actorId:row.actor_id,role:row.role,joinedAt:String(row.joined_at)}}function mapProject(row){return{id:row.id,name:row.name,repoPath:str2(row.repo_path),description:str2(row.description),createdAt:String(row.created_at)}}function getRepoPath(){try{return execSync7("git rev-parse --show-toplevel",{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return process.cwd()}}async function resolveTaskId(idOrSeq,repoPath){let sql=await getConnection(),repo=repoPath??getRepoPath();if(idOrSeq.startsWith("#")){let seq2=Number.parseInt(idOrSeq.slice(1),10);if(Number.isNaN(seq2))return null;let rows2=await sql`SELECT id FROM tasks WHERE repo_path = ${repo} AND seq = ${seq2} LIMIT 1`;return rows2.length>0?rows2[0].id:null}let rows=await sql`SELECT id FROM tasks WHERE id = ${idOrSeq} LIMIT 1`;return rows.length>0?rows[0].id:null}async function createProject(input){let rows=await(await getConnection())`
|
|
@@ -970,7 +971,7 @@ Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.
|
|
|
970
971
|
`),await promptUninstallFrom(join4(home,".tmux.conf"),"generated by genie-cli","tmux.conf");for(let shellRc of[join4(home,".zshrc"),join4(home,".bashrc")])await promptUninstallFrom(shellRc,"generated by genie-cli",shellRc);let termuxDir=join4(home,".termux"),isTermux=existsSync5(termuxDir)||process.env.TERMUX_VERSION;if(isTermux){let termuxProps=join4(termuxDir,"termux.properties");if(await promptUninstallFrom(termuxProps,"generated by genie-cli","termux.properties"),!contentExists(termuxProps,"generated by genie-cli"))console.log(" Run: termux-reload-settings")}if(console.log(`
|
|
971
972
|
\u2705 Uninstallation complete!`),console.log(`
|
|
972
973
|
Next steps:`),console.log(" 1. Reload tmux: tmux source ~/.tmux.conf"),console.log(" 2. Restart your shell or run: source ~/.bashrc"),isTermux)console.log(" 3. Reload Termux: termux-reload-settings")}function printHeader(){console.log(),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log("\x1B[1m\x1B[36m Genie Setup Wizard\x1B[0m"),console.log(`\x1B[1m\x1B[36m${"=".repeat(64)}\x1B[0m`),console.log()}function printSection(title,description){if(console.log(),console.log(`\x1B[1m${title}\x1B[0m`),description)console.log(`\x1B[2m${description}\x1B[0m`);console.log()}async function configureSession(config,quick){if(printSection("2. Session Configuration","Configure tmux session settings"),quick)return console.log(` Using defaults: session="${config.session.name}", window="${config.session.defaultWindow}"`),config;let sessionName=await esm_default3({message:"Session name:",default:config.session.name}),defaultWindow=await esm_default3({message:"Default window name:",default:config.session.defaultWindow}),autoCreate=await esm_default2({message:"Auto-create session on connect?",default:config.session.autoCreate});return config.session={name:sessionName,defaultWindow,autoCreate},config}async function configureTerminal(config,quick){if(printSection("3. Terminal Defaults","Configure default values for term commands"),quick)return console.log(` Using defaults: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),config;let timeoutStr=await esm_default3({message:"Exec timeout (milliseconds):",default:String(config.terminal.execTimeout),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),linesStr=await esm_default3({message:"Read lines (default for genie agent read):",default:String(config.terminal.readLines),validate:(v)=>{let n=Number.parseInt(v,10);return!Number.isNaN(n)&&n>0?!0:"Must be a positive number"}}),worktreeBase=await esm_default3({message:"Worktree base directory (leave empty for ~/.genie/worktrees/<project>/):",default:config.terminal.worktreeBase??""});return config.terminal={execTimeout:Number.parseInt(timeoutStr,10),readLines:Number.parseInt(linesStr,10),...worktreeBase?{worktreeBase}:{}},config}async function configureShortcuts(config,quick){printSection("4. Keyboard Shortcuts","Warp-like tmux shortcuts for quick navigation");let home=homedir5(),tmuxConf=join5(home,".tmux.conf");if(isShortcutsInstalled(tmuxConf))return console.log(" \x1B[32m\u2713\x1B[0m Tmux shortcuts already installed"),config.shortcuts.tmuxInstalled=!0,config;if(console.log(" Available shortcuts:"),console.log(" \x1B[36mCtrl+T\x1B[0m \u2192 New tab (window)"),console.log(" \x1B[36mCtrl+S\x1B[0m \u2192 Vertical split"),console.log(" \x1B[36mCtrl+H\x1B[0m \u2192 Horizontal split"),console.log(),quick)return console.log(" Skipped in quick mode. Run \x1B[36mgenie setup --shortcuts\x1B[0m to install."),config;if(await esm_default2({message:"Install tmux keyboard shortcuts?",default:!1}))console.log(),await installShortcuts(),config.shortcuts.tmuxInstalled=!0,await updateShortcutsConfig({tmuxInstalled:!0});else console.log(" Skipped. Run \x1B[36mgenie shortcuts install\x1B[0m later.");return config}function printCodexResult(result){if(result==="changed")console.log(" \x1B[32m\u2713\x1B[0m Codex config updated");else if(result==="unchanged")console.log(" \x1B[32m\u2713\x1B[0m Codex config already up to date");else console.log(" \x1B[31m\u2717\x1B[0m Failed to update codex config")}async function configureCodex(config,quick){printSection("5. Codex Integration","Configure OpenAI Codex for genie agents");let codexCheck=await checkCommand("codex");if(!codexCheck.exists)return console.log(" \x1B[33m!\x1B[0m Codex CLI not found. Skipping codex integration."),config;if(console.log(` \x1B[32m\u2713\x1B[0m Codex CLI found (${codexCheck.version??"unknown version"})`),isCodexConfigured())return console.log(" \x1B[32m\u2713\x1B[0m Codex config already configured"),config.codex={configured:!0},config;if(console.log(),console.log(" Genie needs to configure codex for agent communication:"),console.log(" \x1B[36mdisable_paste_burst\x1B[0m \u2192 Reliable tmux command injection"),console.log(" \x1B[36mOTel exporter\x1B[0m \u2192 Telemetry relay for state detection"),console.log(` Config: \x1B[2m${contractPath(getCodexConfigPath())}\x1B[0m`),console.log(),quick){let result=ensureCodexOtelConfig();return printCodexResult(result),config.codex={configured:result!=="error"},config}if(await esm_default2({message:"Configure Codex for genie agent integration?",default:!0})){let result=ensureCodexOtelConfig();printCodexResult(result),config.codex={configured:result!=="error"}}else console.log(" Skipped. Run \x1B[36mgenie setup --codex\x1B[0m later.");return config}async function configureDebug(config,quick){if(printSection("6. Debug Options","Logging and debugging settings"),quick)return console.log(" Using defaults: tmuxDebug=false, verbose=false"),config;let tmuxDebug=await esm_default2({message:"Enable tmux debug logging?",default:config.logging.tmuxDebug}),verbose=await esm_default2({message:"Enable verbose mode?",default:config.logging.verbose});return config.logging={tmuxDebug,verbose},config}async function configurePromptMode(config,quick){if(printSection("7. Prompt Mode","Controls how genie injects system prompts into Claude Code"),quick)return console.log(` Using default: promptMode="${config.promptMode}"`),config;console.log(" append \u2014 Uses --append-system-prompt-file (preserves Claude Code default system prompt)"),console.log(" system \u2014 Uses --system-prompt-file (replaces Claude Code default system prompt)"),console.log();let promptMode=await esm_default4({message:"Prompt mode:",choices:[{name:"append (recommended \u2014 preserves CC default)",value:"append"},{name:"system (replaces CC default)",value:"system"}],default:config.promptMode});return config.promptMode=promptMode,config}async function showSummaryAndSave(config){printSection("Summary",`Configuration will be saved to ${contractPath(getGenieConfigPath())}`),console.log(` Session: \x1B[36m${config.session.name}\x1B[0m (window: ${config.session.defaultWindow})`),console.log(` Terminal: timeout=${config.terminal.execTimeout}ms, lines=${config.terminal.readLines}`),console.log(` Shortcuts: ${config.shortcuts.tmuxInstalled?"\x1B[32minstalled\x1B[0m":"\x1B[2mnot installed\x1B[0m"}`),console.log(` Codex: ${config.codex?.configured?"\x1B[32mconfigured\x1B[0m":"\x1B[2mnot configured\x1B[0m"}`),console.log(` Debug: tmux=${config.logging.tmuxDebug}, verbose=${config.logging.verbose}`),console.log(` Prompt mode: \x1B[36m${config.promptMode}\x1B[0m`),console.log(),config.setupComplete=!0,config.lastSetupAt=new Date().toISOString(),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Configuration saved!\x1B[0m")}async function showCurrentConfig(){let config=await loadGenieConfig();console.log(),console.log("\x1B[1mCurrent Genie Configuration\x1B[0m"),console.log(`\x1B[2m${contractPath(getGenieConfigPath())}\x1B[0m`),console.log(),console.log(JSON.stringify(config,null,2)),console.log()}function printNextSteps(){console.log(),console.log("\x1B[1mNext Steps:\x1B[0m"),console.log(),console.log(" Start a session: \x1B[36mgenie\x1B[0m"),console.log(" Watch AI work: \x1B[36mtmux attach -t genie\x1B[0m"),console.log(" Check health: \x1B[36mgenie doctor\x1B[0m"),console.log()}async function setupCommand(options={}){if(options.show){await showCurrentConfig();return}if(options.reset){await resetConfig(),console.log("\x1B[32m\u2713 Configuration reset to defaults.\x1B[0m"),console.log();return}let config=await loadGenieConfig();if(options.shortcuts){printHeader(),await configureShortcuts(config,!1),await markSetupComplete();return}if(options.terminal){printHeader(),config=await configureTerminal(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Terminal configuration saved.\x1B[0m");return}if(options.session){printHeader(),config=await configureSession(config,!1),await saveGenieConfig(config),console.log("\x1B[32m\u2713 Session configuration saved.\x1B[0m");return}if(options.codex){if(printHeader(),config=await configureCodex(config,!1),await saveGenieConfig(config),config.codex?.configured)console.log("\x1B[32m\u2713 Codex configuration saved.\x1B[0m");return}let quick=options.quick??!1;if(printHeader(),quick)console.log("\x1B[2mQuick mode: accepting all defaults\x1B[0m");config=await configureSession(config,quick),config=await configureTerminal(config,quick),config=await configureShortcuts(config,quick),config=await configureCodex(config,quick),config=await configureDebug(config,quick),config=await configurePromptMode(config,quick),await showSummaryAndSave(config),printNextSteps()}import{existsSync as existsSync6}from"fs";import{homedir as homedir6}from"os";import{join as join6}from"path";async function shortcutsShowCommand(){displayShortcuts();let home=homedir6(),tmuxConf=join6(home,".tmux.conf"),zshrc=join6(home,".zshrc"),bashrc=join6(home,".bashrc");if(console.log("Installation status:"),isShortcutsInstalled(tmuxConf))console.log(" \x1B[32m\u2713\x1B[0m tmux.conf");else console.log(" \x1B[33m-\x1B[0m tmux.conf");let shellRc=existsSync6(zshrc)?zshrc:bashrc;if(isShortcutsInstalled(shellRc))console.log(` \x1B[32m\u2713\x1B[0m ${shellRc.replace(home,"~")}`);else console.log(` \x1B[33m-\x1B[0m ${shellRc.replace(home,"~")}`);console.log(),console.log("Run \x1B[36mgenie shortcuts install\x1B[0m to install shortcuts."),console.log("Run \x1B[36mgenie shortcuts uninstall\x1B[0m to remove shortcuts."),console.log()}async function shortcutsInstallCommand(){await installShortcuts()}async function shortcutsUninstallCommand(){await uninstallShortcuts()}init_esm6();import{existsSync as existsSync7,lstatSync,rmSync,unlinkSync as unlinkSync2}from"fs";import{homedir as homedir7}from"os";import{join as join7}from"path";init_genie_config2();var ORCHESTRATION_RULES_PATH=join7(homedir7(),".claude","rules","genie-orchestration.md"),LOCAL_BIN=join7(homedir7(),".local","bin"),SYMLINKS=["genie","term"];function isGenieSymlink(path){try{if(!existsSync7(path))return!1;if(!lstatSync(path).isSymbolicLink())return!1;return!0}catch{return!1}}function removeSymlinks(){let removed=[];for(let name of SYMLINKS){let symlinkPath=join7(LOCAL_BIN,name);if(isGenieSymlink(symlinkPath))try{unlinkSync2(symlinkPath),removed.push(name)}catch{}}return removed}function tryRemoveStep(label,successMsg,fn){console.log(`\x1B[2m${label}\x1B[0m`);try{fn(),console.log(` \x1B[32m+\x1B[0m ${successMsg}`)}catch(error){let message=error instanceof Error?error.message:String(error);console.log(` \x1B[33m!\x1B[0m ${label.replace("...","")} failed: ${message}`)}}function performUninstall(hasHookScript,existingSymlinks,genieDir,hasGenieDir){if(hasHookScript)tryRemoveStep("Removing hook script...","Hook script removed",()=>removeHookScript());if(existingSymlinks.length>0){console.log("\x1B[2mRemoving symlinks...\x1B[0m");let removed=removeSymlinks();if(removed.length>0)console.log(` \x1B[32m+\x1B[0m Removed: ${removed.join(", ")}`)}if(existsSync7(ORCHESTRATION_RULES_PATH))tryRemoveStep("Removing orchestration rules...","Orchestration rules removed (~/.claude/rules/genie-orchestration.md)",()=>unlinkSync2(ORCHESTRATION_RULES_PATH));if(hasGenieDir)tryRemoveStep("Removing genie directory...","Directory removed",()=>rmSync(genieDir,{recursive:!0,force:!0}))}async function uninstallCommand(){console.log(),console.log("\x1B[1m\x1B[33m Uninstall Genie CLI\x1B[0m"),console.log();let genieDir=getGenieDir(),hasGenieDir=existsSync7(genieDir),hasHookScript=hookScriptExists(),hasOrchestrationRules=existsSync7(ORCHESTRATION_RULES_PATH),existingSymlinks=SYMLINKS.filter((name)=>isGenieSymlink(join7(LOCAL_BIN,name)));if(console.log("\x1B[2mThis will remove:\x1B[0m"),hasHookScript)console.log(" \x1B[31m-\x1B[0m Hook script (~/.claude/hooks/genie-bash-hook.sh)");if(hasOrchestrationRules)console.log(" \x1B[31m-\x1B[0m Orchestration rules (~/.claude/rules/genie-orchestration.md)");if(hasGenieDir)console.log(` \x1B[31m-\x1B[0m Genie directory (${contractPath(genieDir)})`);if(existingSymlinks.length>0)console.log(` \x1B[31m-\x1B[0m Symlinks from ~/.local/bin: ${existingSymlinks.join(", ")}`);if(console.log(),!hasGenieDir&&!hasHookScript&&!hasOrchestrationRules&&existingSymlinks.length===0){console.log("\x1B[33mNothing to uninstall.\x1B[0m"),console.log();return}if(!await esm_default2({message:"Are you sure you want to uninstall Genie CLI?",default:!1})){console.log(),console.log("\x1B[2mUninstall cancelled.\x1B[0m"),console.log();return}console.log(),performUninstall(hasHookScript,existingSymlinks,genieDir,hasGenieDir),console.log(),console.log("\x1B[32m+\x1B[0m Genie CLI uninstalled."),console.log(),console.log("\x1B[2mNote: If you installed via npm/bun, also run:\x1B[0m"),console.log(" \x1B[36mbun remove -g @automagik/genie\x1B[0m"),console.log(" \x1B[2mor\x1B[0m"),console.log(" \x1B[36mnpm uninstall -g @automagik/genie\x1B[0m"),console.log()}init_genie_config2();import{execSync,spawn}from"child_process";import{chmodSync,copyFileSync,existsSync as existsSync8,mkdirSync as mkdirSync4,readFileSync as readFileSync4,readdirSync,rmSync as rmSync2,writeFileSync as writeFileSync4}from"fs";import{chmod,copyFile,mkdir,unlink}from"fs/promises";import{homedir as homedir8}from"os";import{join as join8}from"path";var GENIE_HOME=process.env.GENIE_HOME||join8(homedir8(),".genie"),GENIE_SRC=join8(GENIE_HOME,"src"),GENIE_BIN=join8(GENIE_HOME,"bin"),LOCAL_BIN2=join8(homedir8(),".local","bin");function log(message){console.log(`\x1B[32m\u25B8\x1B[0m ${message}`)}function success(message){console.log(`\x1B[32m\u2714\x1B[0m ${message}`)}function error(message){console.log(`\x1B[31m\u2716\x1B[0m ${message}`)}async function runCommand(command,args,cwd){return new Promise((resolve)=>{let output=[],child=spawn(command,args,{cwd,stdio:["inherit","pipe","pipe"],env:{...process.env,FORCE_COLOR:"1"}});child.stdout?.on("data",(data)=>{let str=data.toString();output.push(str),process.stdout.write(str)}),child.stderr?.on("data",(data)=>{let str=data.toString();output.push(str),process.stderr.write(str)}),child.on("close",(code)=>{resolve({success:code===0,output:output.join("")})}),child.on("error",(err)=>{error(err.message),resolve({success:!1,output:err.message})})})}async function getGitInfo(cwd){try{let branchResult=await runCommandSilent("git",["rev-parse","--abbrev-ref","HEAD"],cwd),commitResult=await runCommandSilent("git",["rev-parse","--short","HEAD"],cwd),dateResult=await runCommandSilent("git",["log","-1","--format=%ci"],cwd);if(branchResult.success&&commitResult.success&&dateResult.success)return{branch:branchResult.output.trim(),commit:commitResult.output.trim(),commitDate:dateResult.output.trim().split(" ")[0]}}catch{}return null}async function runCommandSilent(command,args,cwd){return new Promise((resolve)=>{let output=[],child=spawn(command,args,{cwd,stdio:["inherit","pipe","pipe"]});child.stdout?.on("data",(data)=>{output.push(data.toString())}),child.stderr?.on("data",(data)=>{output.push(data.toString())}),child.on("close",(code)=>{resolve({success:code===0,output:output.join("")})}),child.on("error",(err)=>{resolve({success:!1,output:err.message})})})}function detectFromBinaryPath(path){if(path.includes(".bun"))return"bun";if(path.includes("node_modules"))return"npm";if(path===join8(LOCAL_BIN2,"genie")||path.startsWith(GENIE_BIN))return"source";return null}async function detectInstallationType(){if(genieConfigExists())try{let config=await loadGenieConfig();if(config.installMethod)return config.installMethod}catch{}if(existsSync8(join8(GENIE_SRC,".git")))return"source";let result=await runCommandSilent("which",["genie"]);if(!result.success)return"unknown";let detected=detectFromBinaryPath(result.output.trim());if(detected)return detected;return(await runCommandSilent("which",["bun"])).success?"bun":"npm"}async function updateViaBun(channel){try{__require("fs").unlinkSync(join8(homedir8(),".bun","install","global","bun.lock"))}catch{}if(log(`Updating via bun (channel: ${channel})...`),!(await runCommand("bun",["add","-g","--force","--no-cache",`@automagik/genie@${channel}`])).success)return error("Failed to update via bun"),!1;return console.log(),success(`Genie CLI updated via bun (${channel})!`),!0}async function updateViaNpm(channel){if(log(`Updating via npm (channel: ${channel})...`),!(await runCommand("npm",["install","-g",`@automagik/genie@${channel}`])).success)return error("Failed to update via npm"),!1;return console.log(),success(`Genie CLI updated via npm (${channel})!`),!0}async function detectGlobalInstalls(){let found=new Set,[npmResult,bunResult]=await Promise.all([runCommandSilent("npm",["list","-g","@automagik/genie"]),runCommandSilent("bun",["pm","ls","-g"])]);if(npmResult.success&&!npmResult.output.includes("(empty)"))found.add("npm");if(bunResult.success&&bunResult.output.includes("@automagik/genie"))found.add("bun");return found}async function updateSource(){let beforeInfo=await getGitInfo(GENIE_SRC);if(beforeInfo)console.log(`Current: \x1B[2m${beforeInfo.branch}@${beforeInfo.commit} (${beforeInfo.commitDate})\x1B[0m`),console.log();if(log("Fetching latest changes..."),!(await runCommand("git",["fetch","origin"],GENIE_SRC)).success)error("Failed to fetch from origin"),process.exit(1);if(log("Resetting to origin/main..."),!(await runCommand("git",["reset","--hard","origin/main"],GENIE_SRC)).success)error("Failed to reset to origin/main"),process.exit(1);console.log();let afterInfo=await getGitInfo(GENIE_SRC);if(beforeInfo&&afterInfo&&beforeInfo.commit===afterInfo.commit){success("Already up to date!"),console.log();return}if(log("Installing dependencies..."),!(await runCommand("bun",["install"],GENIE_SRC)).success)error("Failed to install dependencies"),process.exit(1);if(console.log(),log("Building..."),!(await runCommand("bun",["run","build"],GENIE_SRC)).success)error("Failed to build"),process.exit(1);console.log(),log("Installing binaries...");try{await mkdir(GENIE_BIN,{recursive:!0}),await mkdir(LOCAL_BIN2,{recursive:!0});let binaries=["genie.js","term.js"],names=["genie","term"];for(let i=0;i<binaries.length;i++){let src=join8(GENIE_SRC,"dist",binaries[i]),binDest=join8(GENIE_BIN,binaries[i]),linkDest=join8(LOCAL_BIN2,names[i]);await copyFile(src,binDest),await chmod(binDest,493),await symlinkOrCopy(binDest,linkDest)}for(let legacy of["claudio.js","claudio"]){let legacyBin=join8(GENIE_BIN,legacy),legacyLink=join8(LOCAL_BIN2,legacy);try{await unlink(legacyBin)}catch{}try{await unlink(legacyLink)}catch{}}success("Binaries installed")}catch(err){error(`Failed to install binaries: ${err}`),process.exit(1)}if(console.log(),console.log("\x1B[2m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),success("Genie CLI updated successfully!"),console.log(),afterInfo)console.log(`Version: \x1B[36m${afterInfo.branch}@${afterInfo.commit}\x1B[0m (${afterInfo.commitDate})`),console.log()}async function symlinkOrCopy(src,dest){let{symlink,unlink:unlink2}=await import("fs/promises");try{if(existsSync8(dest))await unlink2(dest);await symlink(src,dest)}catch{await copyFile(src,dest)}}function copyDirSync(src,dest){mkdirSync4(dest,{recursive:!0});for(let entry of readdirSync(src,{withFileTypes:!0})){let srcPath=join8(src,entry.name),destPath=join8(dest,entry.name);if(entry.isDirectory())copyDirSync(srcPath,destPath);else copyFileSync(srcPath,destPath)}}async function resolveGlobalPkgDir(installType){if(installType==="bun"){let bunPath=join8(homedir8(),".bun","install","global","node_modules","@automagik","genie");if(existsSync8(bunPath))return bunPath}if(installType==="npm"){let npmRootResult=await runCommandSilent("npm",["root","-g"]);if(npmRootResult.success){let npmPath=join8(npmRootResult.output.trim(),"@automagik","genie");if(existsSync8(npmPath))return npmPath}}let bunFallback=join8(homedir8(),".bun","install","global","node_modules","@automagik","genie");if(existsSync8(bunFallback))return bunFallback;let npmRootFallback=await runCommandSilent("npm",["root","-g"]);if(npmRootFallback.success){let npmPath=join8(npmRootFallback.output.trim(),"@automagik","genie");if(existsSync8(npmPath))return npmPath}return null}function updatePluginRegistry(claudePlugins,cacheDir,version){let registryPath=join8(claudePlugins,"installed_plugins.json");try{if(!existsSync8(registryPath))return;let registry=JSON.parse(readFileSync4(registryPath,"utf-8")),entries=registry.plugins?.["genie@automagik"];if(!Array.isArray(entries))return;for(let entry of entries)if(entry.scope==="user")entry.installPath=cacheDir,entry.version=version,entry.lastUpdated=new Date().toISOString();writeFileSync4(registryPath,JSON.stringify(registry,null,2))}catch(err){log(`Registry update failed (non-fatal): ${err}`)}}var GENIE_TMUX_HEADER="# Genie TUI \u2014 tmux configuration";function syncTmuxConf(tmuxScriptsSrc){let tmuxConfSrc=join8(tmuxScriptsSrc,"genie.tmux.conf"),tmuxConfDest=join8(homedir8(),".tmux.conf");if(!existsSync8(tmuxConfSrc)||!existsSync8(tmuxConfDest))return;try{if(!readFileSync4(tmuxConfDest,"utf-8").includes(GENIE_TMUX_HEADER))return;copyFileSync(tmuxConfSrc,tmuxConfDest),success("Updated ~/.tmux.conf (genie-managed)");try{execSync("tmux source-file ~/.tmux.conf",{stdio:"ignore"}),success("Reloaded tmux configuration")}catch{}}catch{}}function syncTmuxScripts(globalPkgDir){let tmuxScriptsSrc=join8(globalPkgDir,"scripts","tmux");if(!existsSync8(tmuxScriptsSrc))return;let scriptsDir=join8(GENIE_HOME,"scripts");mkdirSync4(scriptsDir,{recursive:!0});let scriptCount=0;for(let entry of readdirSync(tmuxScriptsSrc))if(entry.endsWith(".sh")||entry==="genie.tmux.conf"){let src=join8(tmuxScriptsSrc,entry),dest=join8(scriptsDir,entry);copyFileSync(src,dest);try{chmodSync(dest,entry.endsWith(".sh")?493:420)}catch{}scriptCount++}if(scriptCount>0)success(`Refreshed ${scriptCount} tmux scripts at ${scriptsDir}`);syncTmuxConf(tmuxScriptsSrc)}async function syncPlugin(installType){log("Syncing Claude Code plugin...");let globalPkgDir=await resolveGlobalPkgDir(installType);if(!globalPkgDir){log("Could not find installed package \u2014 skipping plugin sync");return}let pluginSrc=join8(globalPkgDir,"plugins","genie");if(!existsSync8(pluginSrc)){log("Plugin source not found in package \u2014 skipping plugin sync");return}let version;try{version=JSON.parse(readFileSync4(join8(globalPkgDir,"package.json"),"utf-8")).version}catch{log("Could not read package version \u2014 skipping plugin sync");return}let claudePlugins=join8(homedir8(),".claude","plugins"),cacheDir=join8(claudePlugins,"cache","automagik","genie",version);try{if(existsSync8(cacheDir))rmSync2(cacheDir,{recursive:!0,force:!0});copyDirSync(pluginSrc,cacheDir);let skillsSrc=join8(globalPkgDir,"skills");if(existsSync8(skillsSrc)&&!existsSync8(join8(cacheDir,"skills")))copyDirSync(skillsSrc,join8(cacheDir,"skills"))}catch(err){error(`Failed to copy plugin: ${err}`);return}updatePluginRegistry(claudePlugins,cacheDir,version),syncTmuxScripts(globalPkgDir),success(`Plugin synced to v${version}`)}async function resolveChannel(options){if(options.next)return"next";if(options.stable)return"latest";if(genieConfigExists())try{let config=await loadGenieConfig();if(config.updateChannel)return config.updateChannel}catch{}return"latest"}async function persistChannel(channel){try{let config=await loadGenieConfig();config.updateChannel=channel,await saveGenieConfig(config)}catch{}}async function updateCommand(options={}){console.log(),console.log("\x1B[1m\uD83E\uDDDE Genie CLI Update\x1B[0m"),console.log("\x1B[2m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),console.log();let channel=await resolveChannel(options);if(options.next||options.stable)await persistChannel(channel);let installType=await detectInstallationType();if(log(`Detected installation: ${installType}`),log(`Channel: ${channel}${channel==="next"?" (dev builds)":" (stable)"}`),console.log(),installType==="unknown")error("No Genie CLI installation found"),console.log(),console.log("Install method not configured. Please reinstall genie:"),console.log("\x1B[36m curl -fsSL https://raw.githubusercontent.com/automagik-dev/genie/main/install.sh | bash\x1B[0m"),console.log(),process.exit(1);if(installType==="source"){await updateSource();return}let globalInstalls=await detectGlobalInstalls(),primaryMethod=installType;if(!(primaryMethod==="bun"?await updateViaBun(channel):await updateViaNpm(channel)))process.exit(1);let secondaryMethod=primaryMethod==="bun"?"npm":"bun";if(globalInstalls.has(secondaryMethod)){if(console.log(),log(`Also updating ${secondaryMethod}-global install...`),!(secondaryMethod==="bun"?await updateViaBun(channel):await updateViaNpm(channel)))error(`Secondary update via ${secondaryMethod} failed (non-blocking)`)}await syncPlugin(installType)}import{existsSync as existsSync9,readFileSync as readFileSync5}from"fs";import{dirname,resolve}from"path";var __dirname="/home/runner/_work/genie/genie/src/lib",FALLBACK_VERSION="0.0.0-unknown";function readVersionFromPackageJson(){let candidates=[resolve(dirname(import.meta.dir??__dirname),"..","..","package.json"),resolve(dirname(import.meta.dir??__dirname),"..","package.json"),resolve(dirname(import.meta.dir??__dirname),"package.json")];for(let candidate of candidates)try{if(existsSync9(candidate)){let pkg=JSON.parse(readFileSync5(candidate,"utf-8"));if(pkg.version)return pkg.version}}catch{}return FALLBACK_VERSION}var VERSION=readVersionFromPackageJson();function buildSearchNames(recipient,dirEntry){let names=new Set([recipient]);if(dirEntry){if(names.add(dirEntry.entry.name),dirEntry.entry.roles)for(let role of dirEntry.entry.roles)names.add(role)}return names}function buildSpawnArgs(template){let args=["spawn","--provider",template.provider,"--team",template.team];if(template.role)args.push("--role",template.role);if(template.skill)args.push("--skill",template.skill);if(template.cwd)args.push("--cwd",template.cwd);if(template.extraArgs)args.push(...template.extraArgs);return args}async function autoSpawn(payload){let input=payload.tool_input;if(!input||input.type!=="message")return;let recipient=input.recipient;if(!recipient||recipient==="team-lead")return;let teamName=process.env.GENIE_TEAM??payload.team_name;if(!teamName)return;try{let registryMod=await Promise.resolve().then(() => (init_agent_registry(),exports_agent_registry)),tmuxMod=await Promise.resolve().then(() => (init_tmux(),exports_tmux)),directoryMod=await Promise.resolve().then(() => (init_agent_directory(),exports_agent_directory)),existing=(await registryMod.list()).find((a)=>(a.role===recipient||a.id===recipient)&&a.team===teamName);if(existing&&await tmuxMod.isPaneAlive(existing.paneId))return;let dirEntry=await directoryMod.resolve(recipient),templates=await registryMod.listTemplates(),searchNames=buildSearchNames(recipient,dirEntry),template=templates.find((t)=>{if(t.team!==teamName)return!1;return[...searchNames].some((q)=>t.id===q||t.role===q)});if(!template){if(dirEntry)console.error(`[genie-hook] Agent "${recipient}" is registered in directory but has no spawn template in team "${teamName}".`);return}let{spawnSync}=__require("child_process");spawnSync("genie",buildSpawnArgs(template),{timeout:1e4,stdio:"ignore",env:{...process.env,GENIE_TEAM:teamName}}),console.error(`[genie-hook] Auto-spawned "${recipient}" in team "${teamName}"`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`[genie-hook] Auto-spawn failed for "${recipient}": ${msg}`)}}async function identityInject(payload){let input=payload.tool_input;if(!input)return;let msgType=input.type;if(msgType!=="message"&&msgType!=="broadcast")return;let agentName=process.env.GENIE_AGENT_NAME;if(!agentName)return;let content=input.content;if(!content)return;if(content.startsWith(`[from:${agentName}]`))return;return{updatedInput:{...input,content:`[from:${agentName}] ${content}`}}}var getAgent=()=>process.env.GENIE_AGENT_NAME??"unknown",getTeam=()=>process.env.GENIE_TEAM;async function emit(subject,event){try{let{publish:publish2}=await Promise.resolve().then(() => (init_nats_client(),exports_nats_client));await publish2(subject,event)}catch{}}async function natsEmitToolCall(payload){let{tool_name:toolName,tool_input:input}=payload;if(!toolName||!input)return;await emit(`genie.tool.${getAgent()}.call`,{timestamp:new Date().toISOString(),kind:"tool_call",agent:getAgent(),team:getTeam(),text:summarizeToolCall(toolName,input),data:{toolCall:{name:toolName,input}},source:"hook"});return}async function natsEmit(payload){let input=payload.tool_input;if(!input)return;let msgType=input.type;if(msgType!=="message"&&msgType!=="broadcast")return;let{to,content}=input;if(!to||!content)return;let subject=msgType==="broadcast"?"genie.msg.broadcast":`genie.msg.${to}`;await emit(subject,{timestamp:new Date().toISOString(),kind:"message",agent:getAgent(),peer:to,direction:"out",text:content,source:"hook"});return}async function natsEmitUserPrompt(payload){let prompt2=payload.prompt;if(!prompt2)return;await emit(`genie.user.${getAgent()}.prompt`,{timestamp:new Date().toISOString(),kind:"user",agent:getAgent(),team:getTeam(),text:prompt2,source:"hook"});return}async function natsEmitAssistantResponse(payload){let lastMessage=payload.last_assistant_message;if(!lastMessage)return;await emit(`genie.agent.${getAgent()}.response`,{timestamp:new Date().toISOString(),kind:"assistant",agent:getAgent(),team:getTeam(),text:lastMessage,source:"hook"});return}function summarizeToolCall(name,input){switch(name){case"Read":case"Edit":case"Write":return`${name} ${input.file_path??""}`;case"Bash":return`$ ${String(input.command??"").split(`
|
|
973
|
-
`)[0]}`;case"Grep":return`Grep "${input.pattern}" ${input.path??""}`;case"Glob":return`Glob ${input.pattern}`;case"Agent":return`Agent: ${input.description??""}`;case"SendMessage":return`SendMessage \u2192 ${input.to}: ${String(input.message??"").slice(0,80)}`;default:return name}}init_types2();var handlers=[{name:"identity-inject",event:"PreToolUse",matcher:/^SendMessage$/,priority:10,fn:identityInject},{name:"auto-spawn",event:"PreToolUse",matcher:/^SendMessage$/,priority:20,fn:autoSpawn},{name:"nats-emit-tool",event:"PreToolUse",matcher:/.*/,priority:30,fn:natsEmitToolCall},{name:"nats-emit-msg",event:"PostToolUse",matcher:/^SendMessage$/,priority:30,fn:natsEmit},{name:"nats-emit-user-prompt",event:"UserPromptSubmit",priority:30,fn:natsEmitUserPrompt},{name:"nats-emit-assistant-response",event:"Stop",priority:30,fn:natsEmitAssistantResponse}];function resolveHandlers(event,toolName){return handlers.filter((h)=>{if(h.event!==event)return!1;if(h.matcher&&toolName&&!h.matcher.test(toolName))return!1;if(h.matcher&&!toolName)return!1;return!0}).sort((a,b)=>a.priority-b.priority)}async function runHandler(handler,payload,currentInput){let handlerPayload={...payload};if(currentInput)handlerPayload.tool_input=currentInput;try{return await handler.fn(handlerPayload)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`[genie-hook] Handler "${handler.name}" threw: ${msg}`);return}}async function executeBlockingChain(matched,payload){let currentInput=payload.tool_input?{...payload.tool_input}:void 0;for(let handler of matched){let result=await runHandler(handler,payload,currentInput);if(!result)continue;if(result.decision==="deny")return{decision:"deny",reason:result.reason??`Denied by handler: ${handler.name}`};if(result.updatedInput)currentInput={...currentInput,...result.updatedInput}}if(currentInput&&payload.tool_input&&JSON.stringify(currentInput)!==JSON.stringify(payload.tool_input))return{updatedInput:currentInput};return{}}async function executeNonBlockingHandlers(matched,payload){await Promise.allSettled(matched.map((h)=>h.fn(payload).catch((err)=>{let msg=err instanceof Error?err.message:String(err);console.error(`[genie-hook] Handler "${h.name}" threw: ${msg}`)})))}async function dispatch(stdin){let payload;try{payload=JSON.parse(stdin)}catch{return console.error("[genie-hook] Invalid JSON on stdin"),""}let event=payload.hook_event_name;if(!event)return console.error("[genie-hook] Missing hook_event_name in payload"),"";let toolName=payload.tool_name,matched=resolveHandlers(event,toolName);if(matched.length===0)return"";if(isBlockingEvent(event)){let result=await executeBlockingChain(matched,payload);if(result.decision||result.updatedInput)return JSON.stringify(result);return""}return await executeNonBlockingHandlers(matched,payload),""}async function readStdin(){let chunks=[];for await(let chunk of Bun.stdin.stream())chunks.push(Buffer.from(chunk));return Buffer.concat(chunks).toString("utf-8")}async function dispatchAction(){let stdin=await readStdin();if(!stdin.trim())process.exit(0);let result=await dispatch(stdin);if(result)process.stdout.write(result)}function registerHookNamespace(program2){program2.command("hook").description("Hook middleware for Claude Code integration").command("dispatch").description("Dispatch a CC hook event (reads JSON from stdin, writes decision to stdout)").action(dispatchAction)}init_agents();import{existsSync as existsSync17,mkdirSync as mkdirSync8,readFileSync as readFileSync9,unlinkSync as unlinkSync4,writeFileSync as writeFileSync6}from"fs";import{homedir as homedir17}from"os";import{join as
|
|
974
|
+
`)[0]}`;case"Grep":return`Grep "${input.pattern}" ${input.path??""}`;case"Glob":return`Glob ${input.pattern}`;case"Agent":return`Agent: ${input.description??""}`;case"SendMessage":return`SendMessage \u2192 ${input.to}: ${String(input.message??"").slice(0,80)}`;default:return name}}init_types2();var handlers=[{name:"identity-inject",event:"PreToolUse",matcher:/^SendMessage$/,priority:10,fn:identityInject},{name:"auto-spawn",event:"PreToolUse",matcher:/^SendMessage$/,priority:20,fn:autoSpawn},{name:"nats-emit-tool",event:"PreToolUse",matcher:/.*/,priority:30,fn:natsEmitToolCall},{name:"nats-emit-msg",event:"PostToolUse",matcher:/^SendMessage$/,priority:30,fn:natsEmit},{name:"nats-emit-user-prompt",event:"UserPromptSubmit",priority:30,fn:natsEmitUserPrompt},{name:"nats-emit-assistant-response",event:"Stop",priority:30,fn:natsEmitAssistantResponse}];function resolveHandlers(event,toolName){return handlers.filter((h)=>{if(h.event!==event)return!1;if(h.matcher&&toolName&&!h.matcher.test(toolName))return!1;if(h.matcher&&!toolName)return!1;return!0}).sort((a,b)=>a.priority-b.priority)}async function runHandler(handler,payload,currentInput){let handlerPayload={...payload};if(currentInput)handlerPayload.tool_input=currentInput;try{return await handler.fn(handlerPayload)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`[genie-hook] Handler "${handler.name}" threw: ${msg}`);return}}async function executeBlockingChain(matched,payload){let currentInput=payload.tool_input?{...payload.tool_input}:void 0;for(let handler of matched){let result=await runHandler(handler,payload,currentInput);if(!result)continue;if(result.decision==="deny")return{decision:"deny",reason:result.reason??`Denied by handler: ${handler.name}`};if(result.updatedInput)currentInput={...currentInput,...result.updatedInput}}if(currentInput&&payload.tool_input&&JSON.stringify(currentInput)!==JSON.stringify(payload.tool_input))return{updatedInput:currentInput};return{}}async function executeNonBlockingHandlers(matched,payload){await Promise.allSettled(matched.map((h)=>h.fn(payload).catch((err)=>{let msg=err instanceof Error?err.message:String(err);console.error(`[genie-hook] Handler "${h.name}" threw: ${msg}`)})))}async function dispatch(stdin){let payload;try{payload=JSON.parse(stdin)}catch{return console.error("[genie-hook] Invalid JSON on stdin"),""}let event=payload.hook_event_name;if(!event)return console.error("[genie-hook] Missing hook_event_name in payload"),"";let toolName=payload.tool_name,matched=resolveHandlers(event,toolName);if(matched.length===0)return"";if(isBlockingEvent(event)){let result=await executeBlockingChain(matched,payload);if(result.decision||result.updatedInput)return JSON.stringify(result);return""}return await executeNonBlockingHandlers(matched,payload),""}async function readStdin(){let chunks=[];for await(let chunk of Bun.stdin.stream())chunks.push(Buffer.from(chunk));return Buffer.concat(chunks).toString("utf-8")}async function dispatchAction(){let stdin=await readStdin();if(!stdin.trim())process.exit(0);let result=await dispatch(stdin);if(result)process.stdout.write(result)}function registerHookNamespace(program2){program2.command("hook").description("Hook middleware for Claude Code integration").command("dispatch").description("Dispatch a CC hook event (reads JSON from stdin, writes decision to stdout)").action(dispatchAction)}init_agents();import{existsSync as existsSync17,mkdirSync as mkdirSync8,readFileSync as readFileSync9,unlinkSync as unlinkSync4,writeFileSync as writeFileSync6}from"fs";import{homedir as homedir17}from"os";import{join as join22}from"path";function genieHome(){return process.env.GENIE_HOME??join22(homedir17(),".genie")}function pidFilePath(){return join22(genieHome(),"scheduler.pid")}function logFilePath(){return join22(genieHome(),"logs","scheduler.log")}function systemdDir(){return join22(homedir17(),".config","systemd","user")}function systemdUnitPath(){return join22(systemdDir(),"genie-scheduler.service")}function readPid(){let path3=pidFilePath();if(!existsSync17(path3))return null;let raw=readFileSync9(path3,"utf-8").trim(),pid=Number.parseInt(raw,10);if(Number.isNaN(pid)||pid<=0)return null;return pid}function writePid(pid){let dir=genieHome();mkdirSync8(dir,{recursive:!0}),writeFileSync6(pidFilePath(),String(pid),"utf-8")}function removePid(){let path3=pidFilePath();if(existsSync17(path3))try{unlinkSync4(path3)}catch{}}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch{return!1}}function generateSystemdUnit(){let genieBin=process.argv[1]??"genie";return`[Unit]
|
|
974
975
|
Description=Genie Scheduler Daemon
|
|
975
976
|
Documentation=https://github.com/automagik/genie
|
|
976
977
|
After=network.target
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genie",
|
|
3
|
-
"version": "4.260324.
|
|
3
|
+
"version": "4.260324.20",
|
|
4
4
|
"description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Namastex Labs"
|
|
@@ -224,6 +224,19 @@ async function getRecentGitLog(repoPath: string, count = 3): Promise<string> {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Get uncommitted changes (staged + unstaged) as a short summary.
|
|
229
|
+
* Best-effort — returns empty string on failure.
|
|
230
|
+
*/
|
|
231
|
+
async function getGitStatus(repoPath: string): Promise<string> {
|
|
232
|
+
try {
|
|
233
|
+
const { stdout } = await execAsync(`git -C '${repoPath}' status --short 2>/dev/null`);
|
|
234
|
+
return stdout.trim();
|
|
235
|
+
} catch {
|
|
236
|
+
return '';
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
227
240
|
/**
|
|
228
241
|
* Build and deliver resume context to a respawned agent.
|
|
229
242
|
*
|
|
@@ -234,7 +247,7 @@ async function getRecentGitLog(repoPath: string, count = 3): Promise<string> {
|
|
|
234
247
|
* Delivered via mailbox as the FIRST message before any task prompt,
|
|
235
248
|
* so the agent has immediate context even without conversation history.
|
|
236
249
|
*/
|
|
237
|
-
async function injectResumeContext(
|
|
250
|
+
export async function injectResumeContext(
|
|
238
251
|
repoPath: string,
|
|
239
252
|
workerId: string,
|
|
240
253
|
agentName: string,
|
|
@@ -260,6 +273,7 @@ async function injectResumeContext(
|
|
|
260
273
|
}
|
|
261
274
|
|
|
262
275
|
const gitLog = await getRecentGitLog(repoPath);
|
|
276
|
+
const gitStatus = await getGitStatus(repoPath);
|
|
263
277
|
|
|
264
278
|
const resumePrompt = [
|
|
265
279
|
`RESUME CONTEXT: You were working on wish "${slug}", group "${groupName}".`,
|
|
@@ -270,6 +284,8 @@ async function injectResumeContext(
|
|
|
270
284
|
'',
|
|
271
285
|
gitLog ? `Last git log:\n${gitLog}` : '',
|
|
272
286
|
'',
|
|
287
|
+
gitStatus ? `Uncommitted changes:\n${gitStatus}` : '',
|
|
288
|
+
'',
|
|
273
289
|
'Pick up where you left off. Read the wish file for full context.',
|
|
274
290
|
]
|
|
275
291
|
.filter(Boolean)
|
|
@@ -15,6 +15,7 @@ import { resolveBuiltinAgentPath } from '../lib/builtin-agents.js';
|
|
|
15
15
|
import * as nativeTeams from '../lib/claude-native-teams.js';
|
|
16
16
|
import { OTEL_RELAY_PORT, ensureCodexOtelConfig } from '../lib/codex-config.js';
|
|
17
17
|
import { buildLayoutCommand, resolveLayoutMode } from '../lib/mosaic-layout.js';
|
|
18
|
+
import { injectResumeContext } from '../lib/protocol-router-spawn.js';
|
|
18
19
|
import {
|
|
19
20
|
type ClaudeTeamColor,
|
|
20
21
|
type ProviderName,
|
|
@@ -1228,18 +1229,13 @@ export async function buildResumeContext(agent: registry.Agent): Promise<string
|
|
|
1228
1229
|
return undefined;
|
|
1229
1230
|
}
|
|
1230
1231
|
|
|
1231
|
-
/**
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
const template = (await registry.listTemplates()).find((t) => t.id === (agent.role ?? agent.id));
|
|
1237
|
-
|
|
1238
|
-
await registry.update(agent.id, { resumeAttempts: 0 });
|
|
1239
|
-
|
|
1232
|
+
/** Build full spawn params for resume, including initial prompt and native team config. */
|
|
1233
|
+
async function buildFullResumeParams(
|
|
1234
|
+
agent: registry.Agent,
|
|
1235
|
+
template: registry.WorkerTemplate | undefined,
|
|
1236
|
+
): Promise<SpawnParams> {
|
|
1240
1237
|
const params = buildResumeParams(agent, template);
|
|
1241
1238
|
|
|
1242
|
-
// Inject resume context so the agent knows where it left off
|
|
1243
1239
|
const resumeContext = await buildResumeContext(agent);
|
|
1244
1240
|
if (resumeContext) {
|
|
1245
1241
|
params.initialPrompt = resumeContext;
|
|
@@ -1254,6 +1250,20 @@ async function resumeAgent(agent: registry.Agent): Promise<void> {
|
|
|
1254
1250
|
if (nativeResult.nativeTeam) params.nativeTeam = nativeResult.nativeTeam;
|
|
1255
1251
|
}
|
|
1256
1252
|
|
|
1253
|
+
return params;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
/**
|
|
1257
|
+
* Resume a single agent by rebuilding spawn params with --resume <sessionId>.
|
|
1258
|
+
* Resets resumeAttempts to 0 (manual resume = fresh retry budget).
|
|
1259
|
+
*/
|
|
1260
|
+
async function resumeAgent(agent: registry.Agent): Promise<void> {
|
|
1261
|
+
const template = (await registry.listTemplates()).find((t) => t.id === (agent.role ?? agent.id));
|
|
1262
|
+
|
|
1263
|
+
await registry.update(agent.id, { resumeAttempts: 0 });
|
|
1264
|
+
|
|
1265
|
+
const params = await buildFullResumeParams(agent, template);
|
|
1266
|
+
|
|
1257
1267
|
const validated = validateSpawnParams(params);
|
|
1258
1268
|
const launch = buildLaunchCommand(validated);
|
|
1259
1269
|
const fullCommand = prependEnvVars(launch.command, launch.env);
|
|
@@ -1308,6 +1318,9 @@ async function resumeAgent(agent: registry.Agent): Promise<void> {
|
|
|
1308
1318
|
|
|
1309
1319
|
await notifySpawnJoin(ctx, paneId);
|
|
1310
1320
|
|
|
1321
|
+
// Inject resume context so the agent knows what wish/group it was working on
|
|
1322
|
+
await injectResumeContext(ctx.cwd ?? agent.repoPath ?? process.cwd(), agent.id, agent.role ?? agent.id, params.team);
|
|
1323
|
+
|
|
1311
1324
|
if (ctx.spawnColor && paneId !== 'inline') {
|
|
1312
1325
|
await tmux.applyPaneColor(paneId, ctx.spawnColor, teamWindow?.windowId);
|
|
1313
1326
|
}
|